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 d2b1396..98ee85b 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -28,10 +28,10 @@ # Do we want LDAP support %global ldap 1 -%global openssh_ver 6.4p1 -%global openssh_rel 1 +%global openssh_ver 7.4p1 +%global openssh_rel 8 -Summary: An implementation of the SSH protocol with GSI authentication +Summary: An implementation of the SSH protocol with GSI authentication and HPN features Name: gsi-openssh Version: %{openssh_ver} Release: %{openssh_rel}%{?dist} @@ -49,96 +49,168 @@ Source13: gsisshd-keygen 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 -#https://bugzilla.mindrot.org/show_bug.cgi?id=1894 -#https://bugzilla.redhat.com/show_bug.cgi?id=735889 -Patch102: openssh-5.8p1-getaddrinfo.patch +Patch100: openssh-7.4p1-coverity.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1889 Patch103: openssh-5.8p1-packet.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 -Patch200: openssh-6.4p1-audit.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1171248 +# record pfs= field in CRYPTO_SESSION audit event +Patch200: openssh-7.4p1-audit.patch +# Do not write to one socket from more processes (#1310684) +Patch202: openssh-6.6p1-audit-race-condition.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) -Patch400: openssh-6.3p1-role-mls.patch +Patch400: openssh-7.4p1-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 -#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=1644 +Patch601: openssh-6.6p1-allow-ip-opts.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 #? 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.3p1-fips.patch +Patch700: openssh-7.4p1-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 +# https://bugzilla.redhat.com/show_bug.cgi?id=205842 +# drop? Patch704: openssh-5.9p1-edns.patch #? -Patch704: openssh-5.9p1-edns.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.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-7.4p1-ctr-cavstest.patch +# add SSH KDF CAVS test driver +Patch714: openssh-7.4p1-kdf-cavs.patch #http://www.sxw.org.uk/computing/patches/openssh.html #changed cache storage type - #848228 -Patch800: openssh-6.3p1-gsskex.patch +Patch800: openssh-7.4p1-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 +# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843) +# CVE-2014-9278 +Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch +# Respect k5login_directory option in krk5.conf (#1328243) +Patch803: openssh-6.6p1-k5login_directory.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-7.4p1-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 +# Change GSSAPIStrictAcceptor to yes as it ever was (#1488982) +Patch903: openssh-7.4p1-gss-strict-acceptor.patch +# Run ssh-copy-id in the legacy mode when SSH_COPY_ID_LEGACY variable is set (#969375 +Patch905: openssh-7.4p1-legacy-ssh-copy-id.patch +# Use tty allocation for a remote scp (#985650) +Patch906: openssh-6.4p1-fromto-remote.patch +# log when a client requests an interactive session and only sftp is allowed (#1130198) +Patch914: openssh-6.6.1p1-log-sftp-only-connections.patch +# log via monitor in chroots without /dev/log (#1083482) +Patch918: openssh-7.4p1-log-in-chroot.patch +# MLS labeling according to chosen sensitivity (#1202843) +Patch919: openssh-6.6.1p1-mls-fix-labeling.patch +# sshd test mode show all config values (#1187597) +Patch920: openssh-6.6p1-test-mode-all-values.patch +# Add sftp option to force mode of created files (#1191055) +Patch921: openssh-6.6p1-sftp-force-permission.patch +# fix memory problem (#1223218) +Patch924: openssh-6.6p1-memory-problems.patch +# Enhance AllowGroups documentation in man page (#1150007) +Patch925: openssh-6.6p1-allowGroups-documentation.patch +# provide option GssKexAlgorithms to disable vulnerable groun1 kex +Patch928: openssh-7.4p1-gssKexAlgorithms.patch +# make s390 use /dev/ crypto devices -- ignore closefrom (#1318760) +Patch935: openssh-6.6p1-s390-closefrom.patch +# expose more information to PAM (#1312304) +Patch938: openssh-7.4p1-expose-pam.patch +# Move MAX_DISPLAYS to a configuration option (#1341302) +Patch939: openssh-6.6p1-x11-max-displays.patch +# Add systemd stuff so it can track running service (#1381997) +Patch942: openssh-6.6p1-systemd.patch +# Permit root login to preserve backward compatibility +Patch943: openssh-7.4p1-permit-root-login.patch +# Restore TCP wrappers support +Patch944: openssh-7.4p1-debian-restore-tcp-wrappers.patch +# Set sane whitelist for PKCS#11 modules in ssh-agent +Patch945: openssh-7.4p1-pkcs11-whitelist.patch +# Allow legacy algorithms and formats for key exchange after rebase +Patch946: openssh-7.4p1-legacy-algorithms.patch +# Show more fingerprints +Patch947: openssh-7.4p1-show-more-fingerprints.patch +# Fix newline in the end of server ident banner (upstream 5b9070) +Patch948: openssh-7.4p1-newline-banner.patch +# Do not utilize SHA1 by default for digital signatures (#1322911) +Patch949: openssh-7.4p1-sha2-signatures.patch +# Canonize pkcs11 provider path when removing smartcard (#2682) +Patch950: openssh-7.4p1-canonize-pkcs11-provider.patch +# Do not segfault sshd if it loads RSA1 keys (#2686) +Patch951: openssh-7.4p1-rsa1-segfault.patch +# OpenSSH 7.5 fixes CBC cipher weakness +Patch952: openssh-7.4p1-cbc-weakness.patch +# sandbox-seccomp filter is not denying socketcall() on ppc64le (#1443916) +Patch953: openssh-7.4p1-sandbox-ppc64le.patch +# ControlPath too long should not be fatal (#1447561) +Patch954: openssh-7.4p1-ControlPath_too_long.patch +# sandbox-seccomp for ibmca engine from upstream (#1451809) +Patch955: openssh-7.4p1-sandbox-ibmca.patch +# Back to UseDNS=yes by default (#1478175) +Patch956: openssh-7.4p1-usedns-yes.patch +# Clatch between ClientAlive timeouts and rekeying (#1480510) +Patch957: openssh-7.4p1-rekeying-timeouts.patch +# WinSCP 5.10+ compatibility (#1496808) +Patch958: openssh-7.4p1-winscp-compat.patch +# SSH AuthorizedKeysCommand hangs when output is too large (#1496467) +Patch959: openssh-7.4p1-authorized_keys_command.patch +# Fix for CVE-2017-15906 (#1517226) +Patch960: openssh-7.5p1-sftp-empty-files.patch +# Fix for CVE-2018-15473 (#1619079) +Patch961: openssh-7.4p1-CVE-2018-15473.patch +# invalidate supplemental group cache used by temporarily_use_uid() (#1619079) +Patch962: openssh-7.4p1-uidswap.patch +# CVE-2021-41617 +Patch978: openssh-8.7p1-upstream-cve-2021-41617.patch +# upsream commit +# b23fe83f06ee7e721033769cfa03ae840476d280 +Patch1015: openssh-9.3p1-upstream-cve-2023-38408.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-7.4p1-gsissh.patch + +# This is the HPN patch +# Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2014v13%207.4p1/openssh-7_4_P1-hpn-14.13.diff/download +Patch99: openssh-7.4p1-hpn-14.13-modified.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 %if %{ldap} BuildRequires: openldap-devel @@ -150,6 +222,7 @@ BuildRequires: pam-devel BuildRequires: tcp_wrappers-devel BuildRequires: fipscheck-devel >= 1.3.0 BuildRequires: openssl-devel >= 0.9.8j +BuildRequires: systemd-devel %if %{kerberos5} BuildRequires: krb5-devel @@ -157,9 +230,8 @@ BuildRequires: krb5-devel %if %{gsi} BuildRequires: globus-gss-assist-devel >= 8 -BuildRequires: globus-gssapi-gsi >= 10 -BuildRequires: globus-common >= 14 -BuildRequires: globus-usage-devel >= 3 +BuildRequires: globus-gssapi-gsi-devel >= 12.12 +BuildRequires: globus-common-devel >= 14 %endif %if %{libedit} @@ -167,6 +239,7 @@ BuildRequires: libedit-devel ncurses-devel %endif %if %{WITH_SELINUX} +Conflicts: selinux-policy < 3.13.1-92 Requires: libselinux >= 1.27.7 BuildRequires: libselinux-devel >= 1.27.7 Requires: audit-libs >= 1.0.8 @@ -230,13 +303,8 @@ This version of OpenSSH has been modified to support GSI authentication. %prep %setup -q -n openssh-%{version} -%patch100 -p1 -b .coverity -%patch101 -p1 -b .fingerprint -%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 @@ -248,21 +316,16 @@ 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 %patch706 -p1 -b .localdomain %patch707 -p1 -b .redhat %patch708 -p1 -b .entropy @@ -270,6 +333,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 @@ -277,9 +341,55 @@ 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 +%patch903 -p1 -b .gss-strict +%patch905 -p1 -b .legacy-ssh-copy-id +%patch906 -p1 -b .fromto-remote +%patch914 -p1 -b .log-sftp-only +%patch918 -p1 -b .log-in-chroot +%patch919 -p1 -b .mls-labels +%patch802 -p1 -b .GSSAPIEnablek5users +%patch803 -p1 -b .k5login +%patch920 -p1 -b .sshd-t +%patch921 -p1 -b .sftp-force-mode +%patch924 -p1 -b .memory-problems +%patch925 -p1 -b .allowGroups +%patch928 -p1 -b .gsskexalg +%patch935 -p1 -b .s390 +%patch938 -p1 -b .expose-pam +%patch939 -p1 -b .x11max +%patch942 -p1 -b .patch +%patch943 -p1 -b .permit-root +%patch944 -p1 -b .tcp_wrappers +%patch945 -p1 -b .pkcs11-whitelist +%patch946 -p1 -b .legacy +%patch947 -p1 -b .fingerprint +%patch948 -p1 -b .newline-banner +%patch949 -p1 -b .sha2 +%patch950 -p1 -b .smartcard +%patch951 -p1 -b .rsa1 +%patch952 -p1 -b .cbc +%patch953 -p1 -b .seccomp +%patch954 -p1 -b .ControlPath +%patch955 -p1 -b .ibmca +%patch956 -p1 -b .usedns +%patch957 -p1 -b .rekey-timeout +%patch958 -p1 -b .winscp +%patch959 -p1 -b .large-command +%patch960 -p1 -b .sftp-empty +%patch961 -p1 -b .CVE-2018-15473 +%patch962 -p1 -b .uidswap +%patch978 -p1 -b .cve-2021-41617 + +%patch200 -p1 -b .audit +%patch202 -p1 -b .audit-race +%patch700 -p1 -b .fips + +%patch100 -p1 -b .coverity + +%patch1015 -p1 -b .cve-2023-38408 %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 @@ -325,20 +435,21 @@ fi --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 \ - --enable-vendor-patchlevel="FC-%{version}-%{release}" \ + --with-privsep-path=%{_var}/empty/sshd \ + --enable-vendor-patchlevel="RHEL7-%{openssh_ver}-%{openssh_rel}" \ --disable-strip \ --without-zlib-version-check \ --with-ssl-engine \ --with-ipaddr-display \ + --with-systemd \ + --with-ssh1 \ %if %{ldap} --with-ldap \ %endif --with-pam \ %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ -%if 0 - #seccomp_filter cannot be build right now +%ifnarch ppc --with-sandbox=seccomp_filter \ %else --with-sandbox=rlimit \ @@ -364,10 +475,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} @@ -375,7 +486,7 @@ make SSH_PROGRAM=%{_bindir}/gsissh \ rm -rf $RPM_BUILD_ROOT mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/gsissh mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/gsissh -mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/gsisshd +mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/sshd make install DESTDIR=$RPM_BUILD_ROOT rm -f $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/ldap.conf @@ -395,6 +506,9 @@ install -m644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd-keygen.service 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 @@ -435,26 +549,19 @@ getent passwd sshd >/dev/null || \ %systemd_preun gsisshd.service gsisshd.socket %postun server -%systemd_postun_with_restart gsisshd.service gsisshd.socket - -%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 || : +%systemd_postun_with_restart gsisshd.service %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 +%doc CREDITS ChangeLog INSTALL 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(0600,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 %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 @@ -473,7 +580,7 @@ getent passwd sshd >/dev/null || \ %files server %defattr(-,root,root) -%dir %attr(0711,root,root) %{_var}/empty/gsisshd +%dir %attr(0711,root,root) %{_var}/empty/sshd %attr(0755,root,root) %{_sbindir}/gsisshd %attr(0755,root,root) %{_sbindir}/gsisshd-keygen %attr(0644,root,root) %{_libdir}/fipscheck/gsisshd.hmac @@ -491,17 +598,66 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/gsisshd-keygen.service %changelog -* Tue Nov 26 2013 Mattias Ellert - 6.4p1-1 -- Based on openssh-6.4p1-2.fc20 +* Wed Aug 09 2023 Mattias Ellert - 7.4p1-8 +- Based on openssh-7.4p1-23.el7_9 -* Mon Oct 21 2013 Mattias Ellert - 6.3p1-2 -- Add obsoletes for -fips packages +* Wed Nov 24 2021 Mattias Ellert - 7.4p1-7 +- Based on openssh-7.4p1-22.el7_9 -* Tue Oct 15 2013 Mattias Ellert - 6.3p1-1 -- Based on openssh-6.3p1-1.fc20 +* Fri Oct 23 2020 Frank Scheiner - 7.4p1-6 +- Add HPN patch -* Wed Oct 02 2013 Mattias Ellert - 6.2p2-3 -- Based on openssh-6.2p2-8.fc20 +* Wed Aug 07 2019 Mattias Ellert - 7.4p1-5 +- Based on openssh-7.4p1-21.el7 + +* Tue May 28 2019 Mattias Ellert - 7.4p1-4 +- Change GSSAPITrustDNS default to no + +* Wed Feb 27 2019 Mattias Ellert - 7.4p1-3 +- Remove usage statistics collection support + +* Tue Apr 10 2018 Mattias Ellert - 7.4p1-2 +- Based on openssh-7.4p1-16.el7 + +* Sun Nov 12 2017 Mattias Ellert - 7.4p1-1 +- Based on openssh-7.4p1-13.el7_4 + +* Mon Jul 31 2017 Mattias Ellert - 6.6.1p1-8 +- Based on openssh-6.6.1p1-35.el7_3 +- Update GSI patch with more openssl 1.1.0 fixes from Globus + +* Fri Feb 24 2017 Mattias Ellert - 6.6.1p1-7 +- Based on openssh-6.6.1p1-33.el7_3 + +* Thu Dec 15 2016 Mattias Ellert - 6.6.1p1-6 +- Adding mechanism OID negotiation with the introduction of micv2 OID + +* Wed Dec 14 2016 Mattias Ellert - 6.6.1p1-5 +- Based on openssh 6.6.1p1-31.el7 + +* Sun Jun 26 2016 Mattias Ellert - 6.6.1p1-4 +- Based on openssh-6.6.1p1-25.el7_2 + +* Tue Jan 19 2016 Mattias Ellert - 6.6.1p1-3 +- Based on openssh-6.6.1p1-23.el7_2 + +* Wed Aug 05 2015 Mattias Ellert - 6.6.1p1-2 +- Fix typos in gsisshd.service file + +* Sun Jul 05 2015 Mattias Ellert - 6.6.1p1-1 +- Based on openssh-6.6.1p1-12.el7_1 + +* Wed Jul 16 2014 Mattias Ellert - 6.4p1-2 +- Based on openssh-6.4p1-8.el7 + +* Tue Jan 28 2014 Mattias Ellert - 6.4p1-1 +- Based on openssh-6.4p1-1.el7 + +* Thu Dec 12 2013 Mattias Ellert - 6.2p2-4 +- Based on openssh-6.2p2-7.fc19 + +* Tue Nov 26 2013 Mattias Ellert - 6.2p2-3 +- Based on openssh-6.2p2-6.fc19 * Fri Aug 23 2013 Mattias Ellert - 6.2p2-2 - Based on openssh-6.2p2-5.fc19 diff --git a/gsisshd-keygen b/gsisshd-keygen index c944449..b313c87 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="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 @@ -70,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 @@ -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 @@ -96,10 +97,10 @@ 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 + /sbin/restorecon $ECDSA_KEY{,.pub} fi success $"ECDSA key generation" echo @@ -111,12 +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_rsa1_keygen - do_dsa_keygen - do_ecdsa_keygen +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";; +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 6bd2c4f..546e82e 100644 --- a/gsisshd-keygen.service +++ b/gsisshd-keygen.service @@ -1,8 +1,11 @@ [Unit] Description=gsissh Server Key Generation -ConditionPathExists=|!/etc/gsissh/ssh_host_rsa_key -ConditionPathExists=|!/etc/gsissh/ssh_host_dsa_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] ExecStart=/usr/sbin/gsisshd-keygen Type=oneshot +RemainAfterExit=yes diff --git a/gsisshd.pam b/gsisshd.pam index af19ec0..eae0ba6 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 @@ -10,6 +12,9 @@ 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 +# 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..2f9366a 100644 --- a/gsisshd.service +++ b/gsisshd.service @@ -1,10 +1,12 @@ [Unit] Description=gsissh server daemon -After=syslog.target network.target auditd.service +Documentation=man:gsisshd(8) man:gsisshd_config(5) +After=network.target gsisshd-keygen.service +Wants=gsisshd-keygen.service [Service] -EnvironmentFile=/etc/sysconfig/gsisshd -ExecStartPre=/usr/sbin/gsisshd-keygen +Type=notify +EnvironmentFile=-/etc/sysconfig/gsisshd ExecStart=/usr/sbin/gsisshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process 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.sysconfig b/gsisshd.sysconfig index 9a30a83..e666ab9 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -1,12 +1,12 @@ # 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 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=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..2f59be2 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -1,7 +1,8 @@ [Unit] Description=gsissh per-connection server daemon +Documentation=man:gsisshd(8) man:gsisshd_config(5) Wants=gsisshd-keygen.service -After=auditd.service gsisshd-keygen.service +After=gsisshd-keygen.service [Service] EnvironmentFile=-/etc/sysconfig/gsisshd 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-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-5.2p1-allow-ip-opts.patch b/openssh-5.2p1-allow-ip-opts.patch deleted file mode 100644 index 96aaab1..0000000 --- a/openssh-5.2p1-allow-ip-opts.patch +++ /dev/null @@ -1,37 +0,0 @@ -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) - option_size = sizeof(options); - if (getsockopt(sock, ipproto, IP_OPTIONS, options, - &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); -+ i = 0; -+ do { -+ switch (options[i]) { -+ case 0: -+ case 1: -+ ++i; -+ break; -+ case 131: -+ case 137: -+ /* Fail, fatally, if we detect either loose or strict -+ * source routing options. */ -+ 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); -+ default: -+ i += options[i + 1]; -+ } -+ } while (i < option_size); - } - #endif /* IP_OPTIONS */ - } diff --git a/openssh-5.5p1-x11.patch b/openssh-5.5p1-x11.patch index cac5d5e..91e82ef 100644 --- a/openssh-5.5p1-x11.patch +++ b/openssh-5.5p1-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_ +@@ -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,16 +30,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.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-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-5.8p1-glob.patch b/openssh-5.8p1-glob.patch deleted file mode 100644 index cb45cd1..0000000 --- a/openssh-5.8p1-glob.patch +++ /dev/null @@ -1,10 +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/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-5.8p1-packet.patch b/openssh-5.8p1-packet.patch index 4951af6..7b1a985 100644 --- a/openssh-5.8p1-packet.patch +++ b/openssh-5.8p1-packet.patch @@ -5,8 +5,8 @@ diff -up openssh-5.8p1/packet.c.packet openssh-5.8p1/packet.c 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) - return 1; + if (state->connection_in == -1 || state->connection_out == -1) + return 0; + 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-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-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-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.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.1p1-log-usepam-no.patch b/openssh-6.1p1-log-usepam-no.patch deleted file mode 100644 index 4ed52b1..0000000 --- a/openssh-6.1p1-log-usepam-no.patch +++ /dev/null @@ -1,26 +0,0 @@ -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) - parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, - &cfg, NULL); - -+ /* 'UsePAM no' is not supported in Fedora */ -+ if (! options.use_pam) -+ logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems."); -+ - 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 yes - # 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 - diff --git a/openssh-6.2p1-vendor.patch b/openssh-6.2p1-vendor.patch index ddccd2c..54d08f0 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-7.4p1/configure.ac.vendor openssh-7.4p1/configure.ac +--- openssh-7.4p1/configure.ac.vendor 2017-02-10 10:45:54.977836854 +0100 ++++ openssh-7.4p1/configure.ac 2017-02-10 10:45:54.995836725 +0100 +@@ -4930,6 +4930,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 +@@ -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-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-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 2017-02-10 10:45:54.995836725 +0100 +@@ -143,6 +143,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 +@@ -325,6 +326,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 { - sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, - sMaxStartups, sMaxAuthTries, sMaxSessions, + 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, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, -@@ -439,6 +443,7 @@ static struct { + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sHostKeyAlgorithms, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, +@@ -528,6 +531,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 +@@ -1369,6 +1373,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) - 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->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(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 2017-02-10 10:45:54.995836725 +0100 +@@ -149,6 +149,7 @@ typedef struct { int max_authtries; int max_sessions; char *banner; /* SSH-2 banner message */ @@ -90,39 +89,13 @@ 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 - #Compression delayed - #ClientAliveInterval 0 - #ClientAliveCountMax 3 -+#ShowPatchLevel no - #UseDNS yes - #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 - Defines the number of bits in the ephemeral protocol version 1 - server key. The minimum value is 512, and the default is 1024. - -+ 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-^]. -+ - 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 - .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 -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.vendor 2017-02-10 10:45:54.990836761 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-02-10 10:45:54.996836718 +0100 +@@ -1334,6 +1334,14 @@ 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 @@ -131,28 +104,40 @@ diff -up openssh-6.2p1/sshd_config.5.vendor openssh-6.2p1/sshd_config.5 +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 - } + .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 2017-02-10 10:45:54.990836761 +0100 ++++ openssh-7.4p1/sshd_config 2017-02-10 10:45:54.996836718 +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 2017-02-10 10:45:54.996836718 +0100 ++++ openssh-7.4p1/sshd.c 2017-02-10 10:48:41.633648667 +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); -@@ -1675,7 +1675,8 @@ main(int ac, char **av) +@@ -1654,7 +1655,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. */ + #ifdef WITH_OPENSSL + SSLeay_version(SSLEAY_VERSION) + #else diff --git a/openssh-6.3p1-coverity.patch b/openssh-6.3p1-coverity.patch deleted file mode 100644 index 69bcb81..0000000 --- a/openssh-6.3p1-coverity.patch +++ /dev/null @@ -1,788 +0,0 @@ -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 * - 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.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 - 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 - - /* enable nonblocking mode */ - if (nonblock) { -- if (rfd != -1) -+ if (rfd >= 0) - set_nonblock(rfd); -- if (wfd != -1) -+ if (wfd >= 0) - set_nonblock(wfd); -- if (efd != -1) -+ if (efd >= 0) - set_nonblock(efd); - } - } -diff -up openssh-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_ - 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 -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) - success = 1; - /*XXXX*/ - key_free(k); -+/*XXXX - if (success != 1) - break; -+XXXX*/ - /* 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 - 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); -@@ -1202,6 +1202,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); - -@@ -1223,9 +1227,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.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, - 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.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 - 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.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) - case DEATTACK_DETECTED: - packet_disconnect("crc32 compensation attack: " - "network attack detected"); -+ break; - 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 -@@ -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 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) - } - - 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 -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 -@@ -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 -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 -@@ -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 -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 - 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++) -@@ -1414,8 +1414,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.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 -@@ -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"); - } - -@@ -336,7 +336,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); -@@ -476,7 +476,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); -@@ -589,7 +589,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)) -@@ -613,7 +613,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 - -@@ -643,7 +643,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 -@@ -739,15 +739,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; - -@@ -946,7 +946,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); - } - -@@ -1006,7 +1006,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.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 * - } - - 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; -@@ -165,7 +165,7 @@ send_string_request(struct sftp_conn *co - - 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; - -@@ -422,7 +422,7 @@ sftp_proto_version(struct sftp_conn *con - } - - 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; -@@ -447,7 +447,7 @@ do_close(struct sftp_conn *conn, char *h - - - static int --do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, -+do_lsreaddir(struct sftp_conn *conn, const char *path, int printflag, - SFTP_DIRENT ***dir) - { - Buffer msg; -@@ -572,7 +572,7 @@ do_lsreaddir(struct sftp_conn *conn, cha - } - - 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)); - } -@@ -590,7 +590,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; - -@@ -605,7 +605,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) - { - u_int status, id; - -@@ -621,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *p - } - - int --do_rmdir(struct sftp_conn *conn, char *path) -+do_rmdir(struct sftp_conn *conn, const char *path) - { - u_int status, id; - -@@ -637,7 +637,7 @@ do_rmdir(struct sftp_conn *conn, char *p - } - - 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; - -@@ -651,7 +651,7 @@ do_stat(struct sftp_conn *conn, char *pa - } - - 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; - -@@ -685,7 +685,7 @@ do_fstat(struct sftp_conn *conn, char *h - #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; - -@@ -702,7 +702,7 @@ do_setstat(struct sftp_conn *conn, char - } - - 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; -@@ -719,7 +719,7 @@ do_fsetstat(struct sftp_conn *conn, char - } - - 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; -@@ -768,7 +768,7 @@ do_realpath(struct sftp_conn *conn, char - } - - int --do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -802,7 +802,7 @@ do_rename(struct sftp_conn *conn, char * - } - - 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; -@@ -835,7 +835,7 @@ do_hardlink(struct sftp_conn *conn, char - } - - 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; -@@ -987,7 +987,7 @@ send_read_request(struct sftp_conn *conn - } - - 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 junk; -@@ -1255,7 +1255,7 @@ do_download(struct sftp_conn *conn, char - } - - 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) - { - int i, ret = 0; -@@ -1345,7 +1345,7 @@ download_dir_internal(struct sftp_conn * - } - - 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) - { - char *src_canon; -@@ -1363,7 +1363,7 @@ download_dir(struct sftp_conn *conn, cha - } - - 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 local_fd; -@@ -1548,7 +1548,7 @@ do_upload(struct sftp_conn *conn, char * - } - - 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) - { - int ret = 0, status; -@@ -1639,7 +1639,7 @@ upload_dir_internal(struct sftp_conn *co - } - - 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) - { - char *dst_canon; -@@ -1656,7 +1656,7 @@ upload_dir(struct sftp_conn *conn, char - } - - 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 -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 - 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 *); -+int do_rename(struct sftp_conn *, const char *, const char *); - - /* 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 *); -+/* 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 */ - -@@ -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); - - /* - * 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); - - /* - * 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); - - /* - * 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); - - /* 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) - { - if (sshpid > 1) { - kill(sshpid, SIGTERM); -- waitpid(sshpid, NULL, 0); -+ (void) waitpid(sshpid, NULL, 0); - } - - _exit(1); -@@ -324,7 +324,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; - -@@ -342,7 +342,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; - -@@ -493,7 +493,7 @@ parse_df_flags(const char *cmd, char **a - } - - static int --is_dir(char *path) -+is_dir(const char *path) - { - struct stat sb; - -@@ -505,7 +505,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; - -@@ -519,7 +519,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); - -@@ -527,7 +527,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) - { - char *abs_src = NULL; -@@ -605,7 +605,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) - { - char *tmp_dst = NULL; -@@ -709,7 +709,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; -@@ -794,7 +794,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; -@@ -875,7 +875,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.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) - 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.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) - 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; - } -@@ -1345,6 +1347,9 @@ server_accept_loop(int *sock_in, int *so - if (num_listen_socks < 0) - break; - } -+ -+ if (fdset != NULL) -+ free(fdset); - } - - diff --git a/openssh-6.3p1-fingerprint.patch b/openssh-6.3p1-fingerprint.patch deleted file mode 100644 index b9cfbdb..0000000 --- a/openssh-6.3p1-fingerprint.patch +++ /dev/null @@ -1,406 +0,0 @@ -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 -@@ -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 -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, - - 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 -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, - 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 -@@ -400,9 +400,9 @@ check_authkeys_file(FILE *f, char *file, - 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; - } -@@ -425,13 +425,13 @@ user_cert_trusted_ca(struct passwd *pw, - 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 -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 - 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 -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 - 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 -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 - 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 -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 -@@ -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 -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) - { - 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) -@@ -785,8 +786,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); -@@ -851,8 +852,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); -@@ -970,13 +971,15 @@ printhost(FILE *f, const char *name, Key - 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); -@@ -1855,16 +1858,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", -@@ -2655,13 +2659,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 -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 - "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); - } -@@ -871,9 +871,8 @@ check_host_key(char *hostname, struct so - 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) -@@ -888,10 +887,11 @@ 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" -+ "%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); -@@ -1136,8 +1136,9 @@ verify_host_key(char *host, struct socka - 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 */ -@@ -1238,14 +1239,15 @@ show_other_keys(struct hostkeys *hostkey - 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); -@@ -1260,7 +1262,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! @"); -@@ -1268,8 +1270,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 -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 - 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); - - /* -@@ -1202,8 +1203,9 @@ sign_and_send_pubkey(Authctxt *authctxt, - 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.3p1-fips.patch b/openssh-6.3p1-fips.patch deleted file mode 100644 index acf4e82..0000000 --- a/openssh-6.3p1-fips.patch +++ /dev/null @@ -1,607 +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.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 -@@ -76,6 +76,8 @@ - #include - #include - #include -+#include -+#include - #include "openbsd-compat/openssl-compat.h" - - #ifdef HAVE_SECUREWARE -@@ -1450,6 +1452,14 @@ 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."); -+ else -+ logit("FIPS integrity verification test failed."); -+ - /* 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) - 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 +1781,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 +1948,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 +2514,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 +2526,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.3p1-krb5-use-default_ccache_name.patch b/openssh-6.3p1-krb5-use-default_ccache_name.patch index b9c8000..773c788 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", + @@ -52,7 +52,7 @@ diff -up openssh-6.3p1/auth-krb5.c.ccache_name openssh-6.3p1/auth-krb5.c #ifdef USE_PAM if (options.use_pam) -@@ -235,10 +256,34 @@ auth_krb5_password(Authctxt *authctxt, c +@@ -235,10 +256,36 @@ auth_krb5_password(Authctxt *authctxt, c void krb5_cleanup_proc(Authctxt *authctxt) { @@ -64,24 +64,26 @@ diff -up openssh-6.3p1/auth-krb5.c.ccache_name openssh-6.3p1/auth-krb5.c 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) { ++ if (authctxt->krb5_ccname != 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"); ++ 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)); ++ 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) ++ ); + } -+ else -+ debug("cache primary file '%s', remove failed: %s", -+ krb5_ccname_dir_start, strerror(errno) -+ ); + } + } } diff --git a/openssh-6.3p1-kuserok.patch b/openssh-6.3p1-kuserok.patch deleted file mode 100644 index 60688db..0000000 --- a/openssh-6.3p1-kuserok.patch +++ /dev/null @@ -1,167 +0,0 @@ -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 @@ - - extern ServerOptions options; - -+int -+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) -+{ -+ if (options.use_kuserok) -+ return krb5_kuserok(krb5_ctx, krb5_user, client); -+ else { -+ char kuser[65]; -+ -+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) -+ return 0; -+ return strcmp(kuser, client) == 0; -+ } -+} -+ - static int - krb5_init(void *context) - { -@@ -159,7 +173,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)) { - 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 -@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr - int); - - static krb5_context krb_context = NULL; -+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); - - /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ - -@@ -116,7 +117,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - /* NOTE: .k5login and .k5users must opened as root, not the user, - * because if they are on a krb5-protected filesystem, user credentials - * to access these files aren't available yet. */ -- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { -+ if (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 -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 -@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions - options->ip_qos_interactive = -1; - options->ip_qos_bulk = -1; - options->version_addendum = NULL; -+ options->use_kuserok = -1; - } - - void -@@ -310,6 +311,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; - - /* Turn privilege separation on by default */ - if (use_privsep == -1) -@@ -336,7 +339,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, -+ sKerberosGetAFSToken, sKerberosUseKuserok, - sKerberosTgtPassing, sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, -@@ -409,11 +412,13 @@ static struct { - #else - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, - #endif -+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, - #else - { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, - { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, -+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, - #endif - { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, - { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1515,6 +1520,10 @@ process_server_config_line(ServerOptions - *activep = value; - break; - -+ case sKerberosUseKuserok: -+ intptr = &options->use_kuserok; -+ goto parse_flag; -+ - case sPermitOpen: - arg = strdelim(&cp); - if (!arg || *arg == '\0') -@@ -1815,6 +1824,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(max_authtries); - 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); - -@@ -2055,6 +2065,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); -+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - - /* 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 { - - int num_permitted_opens; - -+ int use_kuserok; - 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 - 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 . - .It Cm KexAlgorithms - Specifies the available KEX (Key Exchange) algorithms. - Multiple algorithms must be comma-separated. -@@ -833,6 +837,7 @@ Available keywords are - .Cm HostbasedUsesNameFromPacketOnly , - .Cm KbdInteractiveAuthentication , - .Cm KerberosAuthentication , -+.Cm KerberosUseKuserok , - .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 - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - #GSSAPIAuthentication no diff --git a/openssh-6.3p1-privsep-selinux.patch b/openssh-6.3p1-privsep-selinux.patch deleted file mode 100644 index 529468c..0000000 --- a/openssh-6.3p1-privsep-selinux.patch +++ /dev/null @@ -1,104 +0,0 @@ -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); - } - -+void -+ssh_selinux_copy_context(void) -+{ -+ security_context_t *ctx; -+ -+ if (!ssh_selinux_enabled()) -+ return; -+ -+ if (getexeccon((security_context_t *)&ctx) != 0) { -+ logit("%s: getcon failed with %s", __func__, strerror (errno)); -+ return; -+ } -+ if (ctx != NULL) { -+ if (setcon(ctx) != 0) -+ logit("%s: setcon failed with %s", __func__, strerror (errno)); -+ freecon(ctx); -+ } -+} -+ - #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 - -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) - 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(); -+#endif - safely_chroot(chroot_path, pw->pw_uid); - free(tmp); - free(chroot_path); -@@ -1544,6 +1547,12 @@ 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) -+ ssh_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 - argv[i] = NULL; - optind = optreset = 1; - __progname = argv[0]; --#ifdef WITH_SELINUX -- ssh_selinux_change_context("sftpd_t"); --#endif - exit(sftp_server_main(i, argv, s->pw)); - } - -diff -up openssh-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) - /* Demote the private keys to public keys. */ - demote_sensitive_data(); - -+#ifdef WITH_SELINUX -+ 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, -@@ -811,6 +815,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(); -+ } -+#endif -+ - /* It is safe now to apply the key state */ - monitor_apply_keystate(pmonitor); - 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.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-sftp-only-connections.patch b/openssh-6.6.1p1-log-sftp-only-connections.patch new file mode 100644 index 0000000..4f1e0ff --- /dev/null +++ b/openssh-6.6.1p1-log-sftp-only-connections.patch @@ -0,0 +1,12 @@ +diff --git a/session.c b/session.c +index 626a642..b186ca1 100644 +--- 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-6.6.1p1-mls-fix-labeling.patch b/openssh-6.6.1p1-mls-fix-labeling.patch new file mode 100644 index 0000000..1e8a8e2 --- /dev/null +++ b/openssh-6.6.1p1-mls-fix-labeling.patch @@ -0,0 +1,17 @@ +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-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch new file mode 100644 index 0000000..a48aabb --- /dev/null +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -0,0 +1,131 @@ +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 2017-02-09 10:10:47.403859893 +0100 ++++ openssh-7.4p1/gss-serv-krb5.c 2017-02-09 10:10:47.414859882 +0100 +@@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri + 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 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)) { ++ if ( !options.enable_k5users || (!k5login_exists && (access(file, F_OK) == -1))) { + 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 2017-02-09 10:10:47.404859892 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-09 10:18:45.800385543 +0100 +@@ -166,6 +166,7 @@ initialize_server_options(ServerOptions + options->ip_qos_bulk = -1; + options->version_addendum = NULL; + options->use_kuserok = -1; ++ options->enable_k5users = -1; + options->fingerprint_hash = -1; + options->disable_forwarding = -1; + } +@@ -337,6 +338,8 @@ fill_default_server_options(ServerOption + options->show_patchlevel = 0; + if (options->use_kuserok == -1) + options->use_kuserok = 1; ++ if (options->enable_k5users == -1) ++ options->enable_k5users = 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) +@@ -418,7 +421,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, +@@ -497,12 +500,14 @@ 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 }, + { "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 }, +@@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions + 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') +@@ -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); ++ M_CP_INTOPT(enable_k5users); + M_CP_INTOPT(rekey_limit); + M_CP_INTOPT(rekey_interval); + +@@ -2319,6 +2329,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); ++ dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + + /* string arguments */ +diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2017-02-09 10:10:47.404859892 +0100 ++++ openssh-7.4p1/servconf.h 2017-02-09 10:10:47.415859881 +0100 +@@ -174,7 +174,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 -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2017-02-09 10:10:47.415859881 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-02-09 10:19:29.420336796 +0100 +@@ -633,6 +633,12 @@ Specifies whether key exchange based on + doesn't rely on ssh keys to verify host identity. + The default is + .Dq no . ++.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 ++.Cm no . + .It Cm GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.GSSAPIEnablek5users 2017-02-09 10:10:47.404859892 +0100 ++++ openssh-7.4p1/sshd_config 2017-02-09 10:10:47.415859881 +0100 +@@ -80,6 +80,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-allow-ip-opts.patch b/openssh-6.6p1-allow-ip-opts.patch new file mode 100644 index 0000000..953d613 --- /dev/null +++ b/openssh-6.6p1-allow-ip-opts.patch @@ -0,0 +1,39 @@ +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", 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 (opts[i]) { ++ case 0: ++ case 1: ++ ++i; ++ break; ++ case 130: ++ case 133: ++ case 134: ++ i += opts[i + 1]; ++ break; ++ default: ++ /* Fail, fatally, if we detect either loose or strict ++ * source routing options. */ ++ text[0] = '\0'; ++ for (i = 0; i < option_size; i++) ++ snprintf(text + i*3, sizeof(text) - i*3, ++ " %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-allowGroups-documentation.patch b/openssh-6.6p1-allowGroups-documentation.patch new file mode 100644 index 0000000..9da6a1d --- /dev/null +++ b/openssh-6.6p1-allowGroups-documentation.patch @@ -0,0 +1,40 @@ +diff --git a/sshd_config.5 b/sshd_config.5 +index 2320128..6244e68 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -120,6 +120,8 @@ The allow/deny directives are processed in the following order: + .Cm DenyGroups , + and finally + .Cm AllowGroups . ++All of the specified user and group tests must succeed, before user ++is allowed to log in. + .Pp + See PATTERNS in + .Xr ssh_config 5 +@@ -160,6 +162,8 @@ The allow/deny directives are processed in the following order: + .Cm DenyGroups , + and finally + .Cm AllowGroups . ++All of the specified user and group tests must succeed, before user ++is allowed to log in. + .Pp + See PATTERNS in + .Xr ssh_config 5 +@@ -430,6 +434,8 @@ The allow/deny directives are processed in the following order: + .Cm DenyGroups , + and finally + .Cm AllowGroups . ++All of the specified user and group tests must succeed, before user ++is allowed to log in. + .Pp + See PATTERNS in + .Xr ssh_config 5 +@@ -449,6 +455,8 @@ The allow/deny directives are processed in the following order: + .Cm DenyGroups , + and finally + .Cm AllowGroups . ++All of the specified user and group tests must succeed, before user ++is allowed to log in. + .Pp + See PATTERNS in + .Xr ssh_config 5 diff --git a/openssh-6.6p1-audit-race-condition.patch b/openssh-6.6p1-audit-race-condition.patch new file mode 100644 index 0000000..9bbfcb1 --- /dev/null +++ b/openssh-6.6p1-audit-race-condition.patch @@ -0,0 +1,183 @@ +diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1/monitor_wrap.c.audit-race 2017-02-09 14:07:56.870994116 +0100 ++++ openssh-7.4p1/monitor_wrap.c 2017-02-09 14:07:56.874994112 +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); + } ++ ++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 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 message 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 -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h +--- openssh-7.4p1/monitor_wrap.h.audit-race 2017-02-09 14:07:56.870994116 +0100 ++++ openssh-7.4p1/monitor_wrap.h 2017-02-09 14:07:56.874994112 +0100 +@@ -80,6 +80,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 -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c +--- openssh-7.4p1/session.c.audit-race 2017-02-09 14:07:56.871994115 +0100 ++++ openssh-7.4p1/session.c 2017-02-09 14:09:44.710893783 +0100 +@@ -162,6 +162,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 in_chroot = 0; + static int have_dev_log = 1; +@@ -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)); ++ if (pipe(paudit) < 0) ++ fatal("pipe: %s", strerror(errno)); + #endif + if (s->ttyfd != -1) + ret = do_exec_pty(s, command); +@@ -732,6 +745,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; + } + +@@ -1542,6 +1569,33 @@ child_close_fds(void) + endpwent(); + } + ++void ++child_destory_sensitive_data() ++{ ++#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(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); ++ ++#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 +@@ -1558,12 +1612,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-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..6dcd38a 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,34 @@ 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-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_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 -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 --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 $ */ + @@ -59,6 +73,7 @@ diff -up openssh-6.2p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.2p1/op + +#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" @@ -68,10 +83,9 @@ diff -up openssh-6.2p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.2p1/op +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"; @@ -86,9 +100,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 +121,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 +146,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 +175,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 +204,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 +233,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 +261,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-force_krb.patch b/openssh-6.6p1-force_krb.patch similarity index 82% rename from openssh-6.3p1-force_krb.patch rename to openssh-6.6p1-force_krb.patch index 695c0eb..7055e10 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 @@ -11,12 +12,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c #include "xmalloc.h" #include "key.h" -@@ -40,10 +42,12 @@ - #include "auth.h" - #include "log.h" - #include "servconf.h" -+#include "misc.h" - +@@ -40,6 +42,7 @@ #include "buffer.h" #include "ssh-gss.h" @@ -38,7 +34,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 +42,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 +66,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; } @@ -167,7 +163,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c + 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; + } @@ -180,7 +176,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c + 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"); + } @@ -206,19 +202,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 +233,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 +251,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 +263,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.6p1-k5login_directory.patch b/openssh-6.6p1-k5login_directory.patch new file mode 100644 index 0000000..308c452 --- /dev/null +++ b/openssh-6.6p1-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-6.3p1-keycat.patch b/openssh-6.6p1-keycat.patch similarity index 60% rename from openssh-6.3p1-keycat.patch rename to openssh-6.6p1-keycat.patch index 6105d09..37aa9c5 100644 --- a/openssh-6.3p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,6 +1,61 @@ -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 -up openssh-7.4p1/auth2-pubkey.c.keycat openssh-7.4p1/auth2-pubkey.c +--- openssh-7.4p1/auth2-pubkey.c.keycat 2017-02-08 14:32:33.015581448 +0100 ++++ openssh-7.4p1/auth2-pubkey.c 2017-02-08 14:40:26.125216292 +0100 +@@ -1043,6 +1043,14 @@ user_key_command_allowed2(struct passwd + xasprintf(&command, "%s %s", av[0], av[1]); + } + ++#ifdef WITH_SELINUX ++ if (sshd_selinux_setup_env_variables() < 0) { ++ error ("failed to copy environment: %s", ++ strerror(errno)); ++ _exit(127); ++ } ++#endif ++ + if ((pid = subprocess("AuthorizedKeysCommand", pw, command, + ac, av, &f)) == 0) + goto out; +diff -up openssh-7.4p1/configure.ac.keycat openssh-7.4p1/configure.ac +--- openssh-7.4p1/configure.ac.keycat 2017-02-08 14:32:33.011581451 +0100 ++++ openssh-7.4p1/configure.ac 2017-02-08 14:32:33.016581448 +0100 +@@ -3129,6 +3129,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]) + +@@ -3139,6 +3140,7 @@ AC_ARG_WITH([pam], + ;; + *) + SSHDLIBS="$SSHDLIBS -ldl" ++ KEYCATLIBS="$KEYCATLIBS -ldl" + ;; + esac + fi +@@ -4255,6 +4257,7 @@ AC_ARG_WITH([selinux], + ) + AC_SUBST([SSHLIBS]) + AC_SUBST([SSHDLIBS]) ++AC_SUBST([KEYCATLIBS]) + + # Check whether user wants Kerberos 5 support + KRB5_MSG="no" +@@ -5206,6 +5209,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 -up openssh-7.4p1/HOWTO.ssh-keycat.keycat openssh-7.4p1/HOWTO.ssh-keycat +--- openssh-7.4p1/HOWTO.ssh-keycat.keycat 2017-02-08 14:32:33.014581449 +0100 ++++ openssh-7.4p1/HOWTO.ssh-keycat 2017-02-08 14:32:33.014581449 +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 @@ -14,9 +69,9 @@ 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 -up openssh-7.4p1/Makefile.in.keycat openssh-7.4p1/Makefile.in +--- openssh-7.4p1/Makefile.in.keycat 2017-02-08 14:32:33.012581451 +0100 ++++ openssh-7.4p1/Makefile.in 2017-02-08 14:38:28.839306815 +0100 @@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper @@ -25,26 +80,34 @@ diff -up openssh-6.3p1/Makefile.in.keycat openssh-6.3p1/Makefile.in SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ -@@ -64,7 +65,7 @@ EXEEXT=@EXEEXT@ +@@ -51,6 +52,7 @@ K5LIBS=@K5LIBS@ + GSSLIBS=@GSSLIBS@ + SSHLIBS=@SSHLIBS@ + SSHDLIBS=@SSHDLIBS@ ++KEYCATLIBS=@KEYCATLIBS@ + LIBEDIT=@LIBEDIT@ + AR=@AR@ + AWK=@AWK@ +@@ -65,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) +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 \ -@@ -172,6 +173,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) + LIBOPENSSH_OBJS=\ + ssh_api.o \ +@@ -190,6 +192,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 -lfipscheck $(LIBS) + $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -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 $(KEYCATLIBS) $(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) -@@ -279,6 +283,7 @@ install-files: +@@ -332,6 +337,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,37 +115,54 @@ 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 - _exit(1); - } +diff -up openssh-7.4p1/openbsd-compat/port-linux.h.keycat openssh-7.4p1/openbsd-compat/port-linux.h +--- openssh-7.4p1/openbsd-compat/port-linux.h.keycat 2017-02-08 14:32:33.009581453 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux.h 2017-02-08 14:32:33.015581448 +0100 +@@ -23,8 +23,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 (ssh_selinux_setup_env_variables() < 0) { -+ error ("failed to copy environment: %s", -+ strerror(errno)); -+ _exit(127); -+ } -+#endif ++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-7.4p1/openbsd-compat/port-linux-sshd.c.keycat openssh-7.4p1/openbsd-compat/port-linux-sshd.c +--- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.keycat 2017-02-08 14:32:33.008581454 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2017-02-08 14:32:33.015581448 +0100 +@@ -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; + - 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, ++ 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 +182,64 @@ 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 *pw + 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 -up openssh-7.4p1/platform.c.keycat openssh-7.4p1/platform.c +--- openssh-7.4p1/platform.c.keycat 2017-02-08 14:32:33.007581455 +0100 ++++ openssh-7.4p1/platform.c 2017-02-08 14:32:33.015581448 +0100 +@@ -99,7 +99,7 @@ platform_setusercontext(struct passwd *p + { + #ifdef WITH_SELINUX + /* Cache selinux status for later use */ +- (void)ssh_selinux_enabled(); ++ (void)sshd_selinux_enabled(); + #endif + + #ifdef USE_SOLARIS_PROJECTS +diff -up openssh-7.4p1/ssh-keycat.c.keycat openssh-7.4p1/ssh-keycat.c +--- openssh-7.4p1/ssh-keycat.c.keycat 2017-02-08 14:32:33.015581448 +0100 ++++ openssh-7.4p1/ssh-keycat.c 2017-02-08 14:32:33.015581448 +0100 @@ -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..1ac2c55 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-ldap.patch b/openssh-6.6p1-ldap.patch similarity index 90% rename from openssh-6.3p1-ldap.patch rename to openssh-6.6p1-ldap.patch index 052973c..ef5b14b 100644 --- a/openssh-6.3p1-ldap.patch +++ b/openssh-6.6p1-ldap.patch @@ -1,9 +1,235 @@ -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 ] - ) +diff -up openssh-7.4p1/HOWTO.ldap-keys.ldap openssh-7.4p1/HOWTO.ldap-keys +--- openssh-7.4p1/HOWTO.ldap-keys.ldap 2017-02-08 14:26:19.935750452 +0100 ++++ openssh-7.4p1/HOWTO.ldap-keys 2017-02-08 14:26:19.935750452 +0100 +@@ -0,0 +1,125 @@ ++ ++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) Account_Class option to define own user class name ++ (default is posixAccount) ++ 3) Search_Format option to define your own search string using expansion ++ characters %u for username and %f for above mentioned filter and ++ %c for above mentioned object class. ++ ++Example: ++Search_Format (&(objectclass=%c)(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-7.4p1/Makefile.in.ldap openssh-7.4p1/Makefile.in +--- openssh-7.4p1/Makefile.in.ldap 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/Makefile.in 2017-02-08 14:31:36.851624797 +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@ +@@ -61,8 +63,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) + + LIBOPENSSH_OBJS=\ + ssh_api.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 + +-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 +@@ -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 -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) + +@@ -322,6 +328,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 +@@ -338,6 +348,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 + + install-sysconf: + if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ +@@ -363,6 +377,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 \ +@@ -403,6 +424,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 +@@ -414,6 +437,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 + + regress-prep: + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress +diff -up openssh-7.4p1/configure.ac.ldap openssh-7.4p1/configure.ac +--- openssh-7.4p1/configure.ac.ldap 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/configure.ac 2017-02-08 14:26:19.936750452 +0100 +@@ -1656,6 +1656,106 @@ if test "x$use_pie" != "xno"; then + fi + fi +# Check whether user wants LDAP support +LDAP_MSG="no" @@ -107,123 +333,304 @@ diff -up openssh-6.2p1/configure.ac.ldap openssh-6.2p1/configure.ac + 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 -@@ -0,0 +1,108 @@ + Blowfish_initstate \ +diff -up openssh-7.4p1/ldap-helper.c.ldap openssh-7.4p1/ldap-helper.c +--- openssh-7.4p1/ldap-helper.c.ldap 2017-02-08 14:26:19.936750452 +0100 ++++ openssh-7.4p1/ldap-helper.c 2017-02-08 14:26:19.936750452 +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. ++ */ + -+HOW TO START ++#include "ldapincludes.h" ++#include "log.h" ++#include "misc.h" ++#include "xmalloc.h" ++#include "ldapconf.h" ++#include "ldapbody.h" ++#include ++#include + -+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 ++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; + -+HOW TO MIGRATE FROM LPK ++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); ++} + -+1) goto HOW TO START 4) .... the ldap schema is the same ++/* ++ * Main program for the ssh pka ldap agent. ++ */ + -+2) convert the group requests to the appropriate LDAP requests ++int ++main(int ac, char **av) ++{ ++ int opt; ++ FILE *outfile = NULL; + -+HOW TO SOLVE PROBLEMS ++ __progname = ssh_get_progname(av[0]); + -+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. ++ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); + -+ADVANTAGES ++ /* ++ * Initialize option structure to indicate that no values have been ++ * set. ++ */ ++ initialize_options(); + -+1) Blocking an user account can be done directly from LDAP (if sshd is using PubkeyAuthentication + AuthorizedKeysCommand with ldap only). ++ /* Parse command-line arguments. */ ++ while ((opt = getopt(ac, av, "def:s:vw")) != -1) { ++ switch (opt) { ++ case 'd': ++ config_debug = 1; ++ break; + -+DISADVANTAGES ++ case 'e': ++ config_exclusive_config_file = 1; ++ config_warning_config_file = 1; ++ break; + -+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. ++ case 'f': ++ config_file_name = optarg; ++ break; + -+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. ++ case 's': ++ config_single_user = optarg; ++ outfile = fdopen (dup (fileno (stdout)), "w"); ++ break; + -+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 ) ++ case 'v': ++ config_debug = 1; ++ if (config_verbose < SYSLOG_LEVEL_DEBUG3) ++ config_verbose++; ++ break; + -+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. ++ case 'w': ++ config_warning_config_file = 1; ++ break; + -+5) Author -+ Jan F. Chadima ++ case '?': ++ default: ++ usage(); ++ break; ++ } ++ } + -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 -@@ -0,0 +1,494 @@ ++ /* 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-7.4p1/ldap-helper.h.ldap openssh-7.4p1/ldap-helper.h +--- openssh-7.4p1/ldap-helper.h.ldap 2017-02-08 14:26:19.936750452 +0100 ++++ openssh-7.4p1/ldap-helper.h 2017-02-08 14:26:19.936750452 +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-7.4p1/ldap.conf.ldap openssh-7.4p1/ldap.conf +--- openssh-7.4p1/ldap.conf.ldap 2017-02-08 14:26:19.936750452 +0100 ++++ openssh-7.4p1/ldap.conf 2017-02-08 14:26:19.936750452 +0100 +@@ -0,0 +1,94 @@ ++# $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-7.4p1/ldapbody.c.ldap openssh-7.4p1/ldapbody.c +--- openssh-7.4p1/ldapbody.c.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/ldapbody.c 2017-02-08 14:26:19.937750451 +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. @@ -257,8 +664,9 @@ diff -up openssh-6.2p1/ldapbody.c.ldap openssh-6.2p1/ldapbody.c +#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" + @@ -645,8 +1053,8 @@ diff -up openssh-6.2p1/ldapbody.c.ldap openssh-6.2p1/ldapbody.c +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"); @@ -659,12 +1067,10 @@ diff -up openssh-6.2p1/ldapbody.c.ldap openssh-6.2p1/ldapbody.c + } + + /* 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); + @@ -718,9 +1124,9 @@ 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 -up openssh-7.4p1/ldapbody.h.ldap openssh-7.4p1/ldapbody.h +--- openssh-7.4p1/ldapbody.h.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/ldapbody.h 2017-02-08 14:26:19.937750451 +0100 @@ -0,0 +1,37 @@ +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -759,9 +1165,10 @@ 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 -@@ -0,0 +1,720 @@ +diff -up openssh-7.4p1/ldapconf.c.ldap openssh-7.4p1/ldapconf.c +--- openssh-7.4p1/ldapconf.c.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/ldapconf.c 2017-02-08 14:26:19.937750451 +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. @@ -805,7 +1212,7 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + 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; + @@ -858,6 +1265,7 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + { "LogDir", lLogDir }, + { "Debug", lDebug }, + { "SSH_Filter", lSSH_Filter }, ++ { "Search_Format", lSearch_Format }, + { "AccountClass", lAccountClass }, + { NULL, lBadOption } +}; @@ -1078,6 +1486,7 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + else + fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum); + if (*intptr == -1) ++ *intptr = value; + break; + + case lSSLPath: @@ -1142,6 +1551,7 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + else + fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum); + if (*intptr == -1) ++ *intptr = value; + break; + + case lTLS_CaCertFile: @@ -1180,6 +1590,10 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + 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; @@ -1217,7 +1631,7 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h +{ + FILE *f; + char line[1024]; -+ int active, linenum; ++ int linenum; + int bad_options = 0; + struct stat sb; + @@ -1236,7 +1650,6 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + * 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. */ @@ -1287,6 +1700,7 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + options.logdir = NULL; + options.debug = -1; + options.ssh_filter = NULL; ++ options.search_format = NULL; + options.account_class = NULL; +} + @@ -1330,7 +1744,7 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + 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 = ""; @@ -1479,13 +1893,14 @@ diff -up openssh-6.2p1/ldapbody.h.ldap openssh-6.2p1/ldapbody.h + 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 -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 -@@ -0,0 +1,72 @@ +diff -up openssh-7.4p1/ldapconf.h.ldap openssh-7.4p1/ldapconf.h +--- openssh-7.4p1/ldapconf.h.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/ldapconf.h 2017-02-08 14:26:19.937750451 +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. @@ -1547,6 +1962,7 @@ diff -up openssh-6.2p2/ldapconf.h.ldap openssh-6.2p2/ldapconf.h + char *logdir; + int debug; + char *ssh_filter; ++ char *search_format; + char *account_class; +} Options; + @@ -1558,296 +1974,9 @@ 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 -up openssh-7.4p1/ldapincludes.h.ldap openssh-7.4p1/ldapincludes.h +--- openssh-7.4p1/ldapincludes.h.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/ldapincludes.h 2017-02-08 14:26:19.937750451 +0100 @@ -0,0 +1,41 @@ +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -1890,9 +2019,9 @@ 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 -up openssh-7.4p1/ldapmisc.c.ldap openssh-7.4p1/ldapmisc.c +--- openssh-7.4p1/ldapmisc.c.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/ldapmisc.c 2017-02-08 14:26:19.937750451 +0100 @@ -0,0 +1,79 @@ + +#include "ldapincludes.h" @@ -1973,9 +2102,9 @@ 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 -up openssh-7.4p1/ldapmisc.h.ldap openssh-7.4p1/ldapmisc.h +--- openssh-7.4p1/ldapmisc.h.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/ldapmisc.h 2017-02-08 14:26:19.937750451 +0100 @@ -0,0 +1,35 @@ +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ +/* @@ -2012,106 +2141,9 @@ 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 -up openssh-7.4p1/openssh-lpk-openldap.schema.ldap openssh-7.4p1/openssh-lpk-openldap.schema +--- openssh-7.4p1/openssh-lpk-openldap.schema.ldap 2017-02-08 14:26:19.937750451 +0100 ++++ openssh-7.4p1/openssh-lpk-openldap.schema 2017-02-08 14:26:19.937750451 +0100 @@ -0,0 +1,21 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2134,9 +2166,9 @@ 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 -up openssh-7.4p1/openssh-lpk-sun.schema.ldap openssh-7.4p1/openssh-lpk-sun.schema +--- openssh-7.4p1/openssh-lpk-sun.schema.ldap 2017-02-08 14:26:19.938750451 +0100 ++++ openssh-7.4p1/openssh-lpk-sun.schema 2017-02-08 14:26:19.938750451 +0100 @@ -0,0 +1,23 @@ +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey @@ -2161,9 +2193,100 @@ 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 -up openssh-7.4p1/ssh-ldap-helper.8.ldap openssh-7.4p1/ssh-ldap-helper.8 +--- openssh-7.4p1/ssh-ldap-helper.8.ldap 2017-02-08 14:26:19.938750451 +0100 ++++ openssh-7.4p1/ssh-ldap-helper.8 2017-02-08 14:26:19.938750451 +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-7.4p1/ssh-ldap-wrapper.ldap openssh-7.4p1/ssh-ldap-wrapper +--- openssh-7.4p1/ssh-ldap-wrapper.ldap 2017-02-08 14:26:19.938750451 +0100 ++++ openssh-7.4p1/ssh-ldap-wrapper 2017-02-08 14:26:19.938750451 +0100 +@@ -0,0 +1,4 @@ ++#!/bin/sh ++ ++exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" ++ +diff -up openssh-7.4p1/ssh-ldap.conf.5.ldap openssh-7.4p1/ssh-ldap.conf.5 +--- openssh-7.4p1/ssh-ldap.conf.5.ldap 2017-02-08 14:26:19.938750451 +0100 ++++ openssh-7.4p1/ssh-ldap.conf.5 2017-02-08 14:26:19.938750451 +0100 @@ -0,0 +1,379 @@ +.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $ +.\" @@ -2523,8 +2646,14 @@ diff -up openssh-6.2p2/ssh-ldap.conf.5.ldap openssh-6.2p2/ssh-ldap.conf.5 +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 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=posixAccount)(objectclass=ldapPublicKey)(uid=%u)%f) +.It Cm AccountClass +Specifies the LDAP class used to find user accounts. +The default is posixAccount. @@ -2544,94 +2673,47 @@ 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 +diff -up openssh-7.4p1/openssh-lpk-openldap.ldif.ldap openssh-7.4p1/openssh-lpk-openldap.ldif +--- openssh-7.4p1/openssh-lpk-openldap.ldif.ldap 2017-02-08 14:26:19.938750451 +0100 ++++ openssh-7.4p1/openssh-lpk-openldap.ldif 2017-02-08 14:26:19.938750451 +0100 +@@ -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. ++# + -+exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" ++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 -up openssh-7.4p1/openssh-lpk-sun.ldif.ldap openssh-7.4p1/openssh-lpk-sun.ldif +--- openssh-7.4p1/openssh-lpk-sun.ldif.ldap 2017-02-08 14:26:19.938750451 +0100 ++++ openssh-7.4p1/openssh-lpk-sun.ldif 2017-02-08 14:26:19.938750451 +0100 +@@ -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.6p1-log-usepam-no.patch b/openssh-6.6p1-log-usepam-no.patch new file mode 100644 index 0000000..579446b --- /dev/null +++ b/openssh-6.6p1-log-usepam-no.patch @@ -0,0 +1,28 @@ +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); + ++ /* 'UsePAM no' is not supported in Red Hat Enterprise Linux */ ++ if (! options.use_pam) ++ logit("WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several problems."); ++ + seed_rng(); + + /* 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 + # 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 Red Hat Enterprise Linux and may cause several ++# problems. + UsePAM yes + + #AllowAgentForwarding yes diff --git a/openssh-6.6p1-memory-problems.patch b/openssh-6.6p1-memory-problems.patch new file mode 100644 index 0000000..0f5a0ab --- /dev/null +++ b/openssh-6.6p1-memory-problems.patch @@ -0,0 +1,25 @@ +diff -up openssh-7.4p1/servconf.c.memory-problems openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.memory-problems 2017-02-09 10:41:42.483123417 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-09 10:42:16.392102462 +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) + +diff -up openssh-7.4p1/sshd.c.memory-problems openssh-7.4p1/sshd.c diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch new file mode 100644 index 0000000..8b7d0c2 --- /dev/null +++ b/openssh-6.6p1-privsep-selinux.patch @@ -0,0 +1,108 @@ +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 ++sshd_selinux_copy_context(void) ++{ ++ security_context_t *ctx; ++ ++ if (!ssh_selinux_enabled()) ++ return; ++ ++ if (getexeccon((security_context_t *)&ctx) != 0) { ++ logit("%s: getcon failed with %s", __func__, strerror (errno)); ++ return; ++ } ++ if (ctx != NULL) { ++ if (setcon(ctx) != 0) ++ logit("%s: setcon failed with %s", __func__, strerror (errno)); ++ freecon(ctx); ++ } ++} ++ + #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 *); + ++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 ++ sshd_selinux_copy_context(); ++#endif + safely_chroot(chroot_path, pw->pw_uid); + free(tmp); + free(chroot_path); +@@ -1565,6 +1568,12 @@ 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) ++ 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"); +@@ -1826,9 +1835,6 @@ do_child(Session *s, const char *command) + argv[i] = NULL; + optind = optreset = 1; + __progname = argv[0]; +-#ifdef WITH_SELINUX +- ssh_selinux_change_context("sftpd_t"); +-#endif + exit(sftp_server_main(i, argv, s->pw)); + } + +diff --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(); + ++#ifdef WITH_SELINUX ++ ssh_selinux_change_context("sshd_net_t"); ++#endif ++ + /* Demote the child */ + if (getuid() == 0 || geteuid() == 0) { + /* Change our root directory */ +@@ -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) { ++ sshd_selinux_copy_context(); ++ } ++#endif ++ + /* It is safe now to apply the key state */ + monitor_apply_keystate(pmonitor); + diff --git a/openssh-6.3p1-redhat.patch b/openssh-6.6p1-redhat.patch similarity index 61% rename from openssh-6.3p1-redhat.patch rename to openssh-6.6p1-redhat.patch index 5b1ec1d..cd48484 100644 --- a/openssh-6.3p1-redhat.patch +++ b/openssh-6.6p1-redhat.patch @@ -1,10 +1,11 @@ -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 -@@ -46,3 +46,14 @@ - # VisualHostKey no - # ProxyCommand ssh -q -W %h:%p gateway.example.com - # RekeyLimit 1G 1h +diff -up openssh-7.4p1/ssh_config.redhat openssh-7.4p1/ssh_config +--- openssh-7.4p1/ssh_config.redhat 2017-02-08 15:22:30.811307915 +0100 ++++ openssh-7.4p1/ssh_config 2017-02-08 15:22:30.812307915 +0100 +@@ -52,3 +52,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 @@ -16,10 +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 +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 2017-02-08 15:22:30.813307914 +0100 +@@ -837,9 +837,9 @@ DESCRIPTION SyslogFacility Gives the facility code that is used when logging messages from @@ -32,10 +33,10 @@ diff -up openssh-6.3p1/sshd_config.0.redhat openssh-6.3p1/sshd_config.0 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 +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 2017-02-08 15:22:30.813307914 +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 . @@ -44,10 +45,10 @@ diff -up openssh-6.3p1/sshd_config.5.redhat openssh-6.3p1/sshd_config.5 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 -@@ -10,6 +10,10 @@ +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 2017-02-08 15:33:24.705736576 +0100 +@@ -10,21 +10,26 @@ # possible, but leave them commented. Uncommented options override the # default value. @@ -58,15 +59,26 @@ diff -up openssh-6.3p1/sshd_config.redhat openssh-6.3p1/sshd_config #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 -@@ -35,6 +39,7 @@ + #ListenAddress :: + +-#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 ++HostKey /etc/ssh/ssh_host_ed25519_key + + # Ciphers and keying + #RekeyLimit default none + # Logging - # obsoletes QuietMode and FascistLogging #SyslogFacility AUTH +SyslogFacility AUTHPRIV #LogLevel INFO # Authentication: -@@ -70,9 +75,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 @@ -78,31 +90,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 +@@ -68,8 +75,8 @@ AuthorizedKeysFile .ssh/authorized_keys + #KerberosGetAFSToken no # GSSAPI options - #GSSAPIAuthentication no +-#GSSAPIAuthentication no +-#GSSAPICleanupCredentials yes +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 -@@ -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 +@@ -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'. - #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 +@@ -108,6 +115,12 @@ AuthorizedKeysFile .ssh/authorized_keys # no default banner path #Banner none diff --git a/openssh-6.6p1-s390-closefrom.patch b/openssh-6.6p1-s390-closefrom.patch new file mode 100644 index 0000000..301a523 --- /dev/null +++ b/openssh-6.6p1-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-6.6p1-sftp-force-permission.patch b/openssh-6.6p1-sftp-force-permission.patch new file mode 100644 index 0000000..21607e7 --- /dev/null +++ b/openssh-6.6p1-sftp-force-permission.patch @@ -0,0 +1,98 @@ +diff -up openssh-7.4p1/sftp-server.8.sftp-force-mode openssh-7.4p1/sftp-server.8 +--- openssh-7.4p1/sftp-server.8.sftp-force-mode 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sftp-server.8 2017-02-09 10:35:41.926475399 +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-7.4p1/sftp-server.c.sftp-force-mode openssh-7.4p1/sftp-server.c +--- openssh-7.4p1/sftp-server.c.sftp-force-mode 2017-02-09 10:22:36.498019921 +0100 ++++ openssh-7.4p1/sftp-server.c 2017-02-09 10:35:07.190520959 +0100 +@@ -65,6 +65,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; + +@@ -679,6 +683,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 = 0; + + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || + (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ +@@ -688,6 +693,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; ++ 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 && +@@ -709,6 +718,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); +@@ -1490,7 +1501,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); +@@ -1516,7 +1527,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) { +@@ -1576,6 +1587,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.6p1-systemd.patch b/openssh-6.6p1-systemd.patch new file mode 100644 index 0000000..8f3114f --- /dev/null +++ b/openssh-6.6p1-systemd.patch @@ -0,0 +1,98 @@ +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) + } + } + ++#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-6.6p1-test-mode-all-values.patch b/openssh-6.6p1-test-mode-all-values.patch new file mode 100644 index 0000000..2903938 --- /dev/null +++ b/openssh-6.6p1-test-mode-all-values.patch @@ -0,0 +1,27 @@ +diff -up openssh-7.4p1/servconf.c.sshd-t openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.sshd-t 2017-02-09 10:19:56.859306131 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-09 10:22:07.895104402 +0100 +@@ -2337,7 +2337,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 ? "none" : o->banner); + 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-7.4p1/ssh.1.sshd-t openssh-7.4p1/ssh.1 +--- openssh-7.4p1/ssh.1.sshd-t 2017-02-09 10:19:56.823306172 +0100 ++++ openssh-7.4p1/ssh.1 2017-02-09 10:19:56.859306131 +0100 +@@ -512,7 +512,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.6p1-x11-max-displays.patch b/openssh-6.6p1-x11-max-displays.patch new file mode 100644 index 0000000..2c93ef1 --- /dev/null +++ b/openssh-6.6p1-x11-max-displays.patch @@ -0,0 +1,214 @@ +diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c +--- openssh-7.4p1/channels.c.x11max 2017-02-09 12:49:04.690996627 +0100 ++++ openssh-7.4p1/channels.c 2017-02-09 12:49:04.744996547 +0100 +@@ -152,8 +152,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; +@@ -4228,7 +4228,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; +@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ + if (chanids == NULL) + return -1; + ++ /* Try to bind ports starting at 6000+X11DisplayOffset */ ++ x11_max_displays = x11_max_displays + x11_display_offset; ++ + for (display_number = x11_display_offset; +- display_number < 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; +@@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_ + if (num_socks > 0) + break; + } +- if (display_number >= MAX_DISPLAYS) { ++ if (display_number >= x11_max_displays || port < X11_PORT_MIN ) { + 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 = 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) < 0) { + 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 2017-02-09 12:49:04.744996547 +0100 ++++ openssh-7.4p1/channels.h 2017-02-09 12:49:50.230929693 +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); +diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.x11max 2017-02-09 12:49:04.741996552 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-09 12:51:03.167822492 +0100 +@@ -94,6 +94,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; +@@ -242,6 +243,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) +@@ -416,7 +419,7 @@ typedef enum { + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, +- sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, ++ sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, + sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, + sPermitUserEnvironment, sAllowTcpForwarding, sCompression, + sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, +@@ -537,6 +540,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 }, +@@ -1313,6 +1317,10 @@ process_server_config_line(ServerOptions + *intptr = value; + break; + ++ case sX11MaxDisplays: ++ intptr = &options->x11_max_displays; ++ goto parse_int; ++ + case sX11UseLocalhost: + intptr = &options->x11_use_localhost; + goto parse_flag; +@@ -2060,6 +2068,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); +@@ -2312,6 +2321,7 @@ dump_config(ServerOptions *o) + #endif + dump_cfg_int(sLoginGraceTime, o->login_grace_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-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.x11max 2017-02-09 12:49:04.741996552 +0100 ++++ openssh-7.4p1/servconf.h 2017-02-09 12:49:04.744996547 +0100 +@@ -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-7.4p1/session.c.x11max openssh-7.4p1/session.c +--- openssh-7.4p1/session.c.x11max 2017-02-09 12:49:04.742996550 +0100 ++++ openssh-7.4p1/session.c 2017-02-09 12:49:04.745996546 +0100 +@@ -2502,8 +2502,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-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.x11max 2017-02-09 12:49:04.742996550 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-02-09 12:51:24.656790909 +0100 +@@ -1137,6 +1137,7 @@ Available keywords are + .Cm StreamLocalBindUnlink , + .Cm TrustedUserCAKeys , + .Cm X11DisplayOffset , ++.Cm X11MaxDisplays , + .Cm X11Forwarding + and + .Cm X11UseLocalHost . +@@ -1563,6 +1564,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 diff --git a/openssh-7.4p1-CVE-2018-15473.patch b/openssh-7.4p1-CVE-2018-15473.patch new file mode 100644 index 0000000..fb8934c --- /dev/null +++ b/openssh-7.4p1-CVE-2018-15473.patch @@ -0,0 +1,145 @@ +From 74287f5df9966a0648b4a68417451dd18f079ab8 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Tue, 31 Jul 2018 03:10:27 +0000 +Subject: [PATCH] upstream: delay bailout for invalid authentic + +=?UTF-8?q?ating=20user=20until=20after=20the=20packet=20containing=20the?= +=?UTF-8?q?=20request=20has=20been=20fully=20parsed.=20Reported=20by=20Dar?= +=?UTF-8?q?iusz=20Tytko=20and=20Micha=C5=82=20Sajdak;=20ok=20deraadt?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +OpenBSD-Commit-ID: b4891882fbe413f230fe8ac8a37349b03bd0b70d +--- + auth2-gss.c | 11 +++++++---- + auth2-hostbased.c | 11 ++++++----- + auth2-pubkey.c | 25 +++++++++++++++---------- + 3 files changed, 28 insertions(+), 19 deletions(-) + +diff --git a/auth2-gss.c b/auth2-gss.c +index 47308c5ce..9351e0428 100644 +--- a/auth2-gss.c ++++ b/auth2-gss.c +@@ -70,9 +70,6 @@ userauth_gssapi(struct ssh *ssh) + u_int len; + u_char *doid = NULL; + +- if (!authctxt->valid || authctxt->user == NULL) +- return (0); +- + mechs = packet_get_int(); + if (mechs == 0) { + debug("Mechanism negotiation is not supported"); +@@ -106,6 +103,12 @@ userauth_gssapi(struct ssh *ssh) + return (0); + } + ++ if (!authctxt->valid || authctxt->user == NULL) { ++ debug2("%s: disabled because of invalid user", __func__); ++ free(doid); ++ return (0); ++ } ++ + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) { + if (ctxt != NULL) + ssh_gssapi_delete_ctx(&ctxt); +diff --git a/auth2-hostbased.c b/auth2-hostbased.c +index 60159a56c..359393291 100644 +--- a/auth2-hostbased.c ++++ b/auth2-hostbased.c +@@ -67,10 +67,6 @@ userauth_hostbased(struct ssh *ssh) + int pktype; + int authenticated = 0; + +- if (!authctxt->valid) { +- debug2("userauth_hostbased: disabled because of invalid user"); +- return 0; +- } + pkalg = packet_get_string(&alen); + pkblob = packet_get_string(&blen); + chost = packet_get_string(NULL); +@@ -117,6 +113,11 @@ userauth_hostbased(struct ssh *ssh) + goto done; + } + ++ if (!authctxt->valid || authctxt->user == NULL) { ++ debug2("%s: disabled because of invalid user", __func__); ++ goto done; ++ } ++ + service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : + authctxt->service; + buffer_init(&b); +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index c4d0f7908..e1c150401 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -89,16 +89,12 @@ userauth_pubkey(struct ssh *ssh) + { + Buffer b; + Key *key = NULL; +- char *pkalg, *userstyle, *pubkey, *fp = NULL; +- u_char *pkblob, *sig; ++ char *pkalg = NULL, *userstyle = NULL, *pubkey = NULL, *fp = NULL; ++ u_char *pkblob = NULL, *sig = NULL; + u_int alen, blen, slen; + int have_sig, pktype; + int authenticated = 0; + +- if (!authctxt->valid) { +- debug2("%s: disabled because of invalid user", __func__); +- return 0; +- } + have_sig = packet_get_char(); + if (datafellows & SSH_BUG_PKAUTH) { + debug2("%s: SSH_BUG_PKAUTH", __func__); +@@ -167,6 +163,12 @@ userauth_pubkey(struct ssh *ssh) + } else { + buffer_put_string(&b, session_id2, session_id2_len); + } ++ if (!authctxt->valid || authctxt->user == NULL) { ++ buffer_free(&b); ++ debug2("%s: disabled because of invalid user", ++ __func__); ++ goto done; ++ } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user, +@@ -183,7 +184,6 @@ userauth_pubkey(struct ssh *ssh) + #endif + pubkey = sshkey_format_oneline(key, options.fingerprint_hash); + auth_info(authctxt, "%s", pubkey); +- + /* test for correct signature */ + authenticated = 0; + if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && +@@ -194,7 +194,6 @@ userauth_pubkey(struct ssh *ssh) + free(pubkey); + } + buffer_free(&b); +- free(sig); + } else { + debug("%s: test whether pkalg/pkblob are acceptable for %s %s", + __func__, sshkey_type(key), fp); +@@ -205,6 +204,11 @@ userauth_pubkey(struct ssh *ssh) + __func__, sshkey_type(key), fp); + packet_check_eom(); + ++ if (!authctxt->valid || authctxt->user == NULL) { ++ debug2("%s: disabled because of invalid user", ++ __func__); ++ goto done; ++ } + /* XXX fake reply and always send PK_OK ? */ + /* + * XXX this allows testing whether a user is allowed +@@ -238,6 +242,7 @@ userauth_pubkey(struct ssh *ssh) + free(pkalg); + free(pkblob); + free(fp); ++ free(sig); + return authenticated; + } + diff --git a/openssh-7.4p1-ControlPath_too_long.patch b/openssh-7.4p1-ControlPath_too_long.patch new file mode 100644 index 0000000..6d9125c --- /dev/null +++ b/openssh-7.4p1-ControlPath_too_long.patch @@ -0,0 +1,16 @@ +diff -up openssh-7.4p1/mux.c.controlPath openssh-7.4p1/mux.c +--- openssh-7.4p1/mux.c.controlPath 2017-05-04 14:49:44.629247946 +0200 ++++ openssh-7.4p1/mux.c 2017-05-04 14:52:54.955109022 +0200 +@@ -1290,6 +1290,12 @@ muxserver_listen(void) + oerrno = errno; + umask(old_umask); + if (muxserver_sock < 0) { ++ if (oerrno == ENAMETOOLONG) { ++ /* the error is already logged from unix_listener() */ ++ error("ControlPath %s too long, " ++ "disabling multiplexing", options.control_path); ++ goto disable_mux_master; ++ } + if (oerrno == EINVAL || oerrno == EADDRINUSE) { + error("ControlSocket %s already exists, " + "disabling multiplexing", options.control_path); diff --git a/openssh-6.4p1-audit.patch b/openssh-7.4p1-audit.patch similarity index 60% rename from openssh-6.4p1-audit.patch rename to openssh-7.4p1-audit.patch index 77a6fa4..5fb3753 100644 --- a/openssh-6.4p1-audit.patch +++ b/openssh-7.4p1-audit.patch @@ -1,19 +1,7 @@ -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 - - 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 -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 } @@ -38,7 +26,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 +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } @@ -51,7 +39,7 @@ diff -up openssh-6.3p1/audit-bsm.c.audit openssh-6.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); } } @@ -63,7 +51,7 @@ diff -up openssh-6.3p1/audit-bsm.c.audit openssh-6.3p1/audit-bsm.c +} + +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 */ +} @@ -92,399 +80,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 -@@ -35,13 +35,24 @@ - - #include "log.h" - #include "audit.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+#include "servconf.h" - #include "canohost.h" -+#include "packet.h" -+#include "cipher.h" - -+#define AUDIT_LOG_SIZE 128 -+ -+extern ServerOptions options; -+extern Authctxt *the_authctxt; -+extern u_int utmp_len; - 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) -+static void -+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 +60,11 @@ linux_audit_record_event(int uid, const - if (audit_fd < 0) { - if (errno == EINVAL || errno == EPROTONOSUPPORT || - errno == EAFNOSUPPORT) -- return 1; /* No audit support in kernel */ -+ return; /* No audit support in kernel */ - else -- return 0; /* Must prevent login */ -+ goto fatal_report; /* Must prevent login */ - } -- 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); - saved_errno = errno; -@@ -65,35 +76,150 @@ linux_audit_record_event(int uid, const - if ((rc == -EPERM) && (geteuid() != 0)) - rc = 0; - errno = saved_errno; -- 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) -+{ -+ int audit_fd, rc, saved_errno; -+ static const char *event_name[] = { -+ "maxtries exceeded", -+ "root denied", -+ "success", -+ "none", -+ "password", -+ "challenge-response", -+ "pubkey", -+ "hostbased", -+ "gssapi", -+ "invalid user", -+ "nologin", -+ "connection closed", -+ "connection abandoned", -+ "unknown" -+ }; -+ -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return; /* No audit support in kernel */ -+ else -+ goto fatal_report; /* Must prevent login */ -+ } -+ -+ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN)) -+ event = SSH_AUDIT_UNKNOWN; -+ -+ 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); -+ saved_errno = errno; -+ close(audit_fd); -+ /* -+ * Do not report error if the error is EPERM and sshd is run as non -+ * root user. -+ */ -+ if ((rc == -EPERM) && (geteuid() != 0)) -+ rc = 0; -+ errno = saved_errno; -+ if (rc < 0) { -+fatal_report: -+ fatal("linux_audit_write_entry failed: %s", strerror(errno)); -+ } -+} -+ -+int -+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) -+{ -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, rc, saved_errno; -+ -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return 1; /* No audit support in kernel */ -+ else -+ return 0; /* Must prevent login */ -+ } -+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port()); -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); -+ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) -+ goto out; -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s rport=%d", -+ type, bits, key_fingerprint_prefix(), 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: -+ 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) - { --} - /* not implemented */ -+} - --void -+int - audit_run_command(const char *command) - { -- /* 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), -+ 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), -+ NULL, "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, get_remote_name_or_ip(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), -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); -+} -+ -+void -+audit_count_session_open(void) -+{ -+ user_login_count++; - } - - void - audit_session_open(struct logininfo *li) - { -- 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, -+ NULL, li->line, 1, AUDIT_USER_LOGIN); -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, -+ NULL, li->line, 1, AUDIT_USER_START); - } - - void - audit_session_close(struct logininfo *li) - { -- /* 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) -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, -+ NULL, li->line, 1, AUDIT_USER_LOGOUT); - } - - void -@@ -101,21 +227,43 @@ 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); -+ 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); -+ linux_audit_user_logxxx(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); - break; - -+ case SSH_LOGIN_EXCEED_MAXTRIES: - case SSH_AUTH_FAIL_NONE: - case SSH_AUTH_FAIL_PASSWD: - case SSH_AUTH_FAIL_KBDINT: - case SSH_AUTH_FAIL_PUBKEY: - case SSH_AUTH_FAIL_HOSTBASED: - case SSH_AUTH_FAIL_GSSAPI: -+ linux_audit_user_auth(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "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), -+ 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), -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); -+ } -+ break; -+ -+ case SSH_CONNECTION_ABANDON: - case SSH_INVALID_USER: -- linux_audit_record_event(-1, audit_username(), NULL, -- get_remote_ipaddr(), "sshd", 0); -+ linux_audit_user_logxxx(-1, audit_username(), NULL, -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); - break; - - default: -@@ -123,4 +271,135 @@ audit_event(ssh_audit_event_t event) - } - } - -+void -+audit_unsupported_body(int what) -+{ -+#ifdef AUDIT_CRYPTO_SESSION -+ char buf[AUDIT_LOG_SIZE]; -+ const static char *name[] = { "cipher", "mac", "comp" }; -+ char *s; -+ 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()); -+ 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); -+ audit_close(audit_fd); -+#endif -+} -+ -+const static char *direction[] = { "from-server", "from-client", "both" }; -+ -+void -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, 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); -+ 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, -+ (intmax_t)pid, (intmax_t)uid, -+ get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); -+ free(s); -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return; /* No audit support in kernel */ -+ else -+ 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); -+ 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))) -+ fatal("cannot write into audit"); /* Must prevent login */ -+#endif -+} -+ -+void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) -+{ -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, audit_ok; -+ char *s; -+ -+ 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(), -+ (s = get_local_ipaddr(packet_get_connection_in())), -+ get_local_port()); -+ free(s); -+ 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, 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 */ -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) -+ error("cannot write into audit"); -+} -+ -+void -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) -+{ -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, audit_ok; -+ -+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ", -+ fp, (intmax_t)pid, (intmax_t)uid); -+ 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, -+ 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 */ -+ 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-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 -@@ -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 @@ -492,17 +91,43 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/audit.c #ifdef SSH_AUDIT_EVENTS -@@ -36,6 +37,9 @@ +@@ -34,6 +35,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 -@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) +@@ -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,40 @@ audit_event_lookup(ssh_audit_event_t ev) return(event_lookup[i].name); } @@ -512,7 +137,7 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/audit.c + 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 @@ -529,9 +154,9 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/audit.c +} + +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 @@ -543,7 +168,7 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.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) } /* @@ -561,7 +186,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 +@@ -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 @@ -599,9 +224,9 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/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, -+ key_fingerprint_prefix(), fp, rv); ++ fp, rv); +} + +/* @@ -617,11 +242,11 @@ diff -up openssh-6.3p1/audit.c.audit openssh-6.3p1/audit.c + * 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); +} + @@ -655,10 +280,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 -@@ -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" @@ -666,8 +291,16 @@ diff -up openssh-6.3p1/audit.h.audit openssh-6.3p1/audit.h enum ssh_audit_event_type { SSH_LOGIN_EXCEED_MAXTRIES, -@@ -47,11 +48,25 @@ enum ssh_audit_event_type { +@@ -43,13 +44,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); @@ -684,18 +317,409 @@ diff -up openssh-6.3p1/audit.h.audit openssh-6.3p1/audit.h +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 -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 -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" ++#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" +- ++#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); + +-int +-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) + { + int audit_fd, rc, saved_errno; + + if ((audit_fd = audit_open()) < 0) { + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) +- return 1; /* No audit support in kernel */ ++ return; /* No audit support in kernel */ + else +- return 0; /* Must prevent login */ ++ goto fatal_report; /* Must prevent login */ + } +- 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); + saved_errno = errno; +@@ -65,9 +78,97 @@ linux_audit_record_event(int uid, const + rc = 0; + errno = saved_errno; + +- 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) ++{ ++ int audit_fd, rc, saved_errno; ++ static const char *event_name[] = { ++ "maxtries exceeded", ++ "root denied", ++ "success", ++ "none", ++ "password", ++ "challenge-response", ++ "pubkey", ++ "hostbased", ++ "gssapi", ++ "invalid user", ++ "nologin", ++ "connection closed", ++ "connection abandoned", ++ "unknown" ++ }; ++ ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return; /* No audit support in kernel */ ++ else ++ goto fatal_report; /* Must prevent login */ ++ } ++ ++ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN)) ++ event = SSH_AUDIT_UNKNOWN; ++ ++ 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); ++ saved_errno = errno; ++ close(audit_fd); ++ /* ++ * Do not report error if the error is EPERM and sshd is run as non ++ * root user. ++ */ ++ if ((rc == -EPERM) && (geteuid() != 0)) ++ rc = 0; ++ errno = saved_errno; ++ if (rc < 0) { ++fatal_report: ++ fatal("linux_audit_write_entry failed: %s", strerror(errno)); ++ } ++} ++ ++int ++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, rc, saved_errno; ++ ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return 1; /* No audit support in kernel */ ++ else ++ return 0; /* Must prevent login */ ++ } ++ 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, 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); ++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 +@@ -76,24 +177,51 @@ audit_connection_from(const char *host, + /* not implemented */ + } + +-void ++int + audit_run_command(const char *command) + { +- /* 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); ++ 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); ++ 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); ++} ++ ++void ++audit_count_session_open(void) ++{ ++ user_login_count++; + } + + void + audit_session_open(struct logininfo *li) + { +- 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, ++ NULL, li->line, 1, AUDIT_USER_LOGIN); ++ linux_audit_user_logxxx(li->uid, NULL, li->hostname, ++ NULL, li->line, 1, AUDIT_USER_START); + } + + void + audit_session_close(struct logininfo *li) + { +- /* 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) ++ linux_audit_user_logxxx(li->uid, NULL, li->hostname, ++ NULL, li->line, 1, AUDIT_USER_LOGOUT); + } + + void +@@ -103,24 +231,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, ++ 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, ++ ssh_remote_ipaddr(ssh), "ssh", 0, event); ++ linux_audit_user_logxxx(-1, audit_username(), NULL, ++ 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: + case SSH_AUTH_FAIL_KBDINT: + case SSH_AUTH_FAIL_PUBKEY: + case SSH_AUTH_FAIL_HOSTBASED: + case SSH_AUTH_FAIL_GSSAPI: ++ linux_audit_user_auth(-1, audit_username(), NULL, ++ 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, ++ 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, ++ session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_LOGOUT); ++ } ++ break; ++ ++ case SSH_CONNECTION_ABANDON: + 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, ++ ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); + break; + default: + debug("%s: unhandled event %d", __func__, event); + break; + } + } ++ ++void ++audit_unsupported_body(int what) ++{ ++#ifdef AUDIT_CRYPTO_SESSION ++ char buf[AUDIT_LOG_SIZE]; ++ const static char *name[] = { "cipher", "mac", "comp" }; ++ char *s; ++ 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)); ++ 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); ++ audit_close(audit_fd); ++#endif ++} ++ ++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) ++{ ++#ifdef AUDIT_CRYPTO_SESSION ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ 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 ", ++ 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)); ++ free(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return; /* No audit support in kernel */ ++ else ++ 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); ++ 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))) ++ fatal("cannot write into audit"); /* Must prevent login */ ++#endif ++} ++ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ char *s; ++ ++ 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)); ++ free(s); ++ 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, 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))) ++ error("cannot write into audit"); ++} ++ ++void ++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ ++ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ", ++ fp, (intmax_t)pid, (intmax_t)uid); ++ 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, ++ 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 */ ++ 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.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 $ */ + @@ -734,7 +758,7 @@ diff -up openssh-6.3p1/auditstub.c.audit openssh-6.3p1/auditstub.c +} + +void -+audit_kex(int ctos, char *enc, char *mac, char *comp) ++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) +{ +} + @@ -747,77 +771,32 @@ 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 - { - u_char buf[32], mdbuf[16]; - MD5_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) { -@@ -113,12 +116,18 @@ auth_rsa_verify_response(Key *key, BIGNU - MD5_Final(mdbuf, &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 = key_selected_fingerprint(key, 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-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 - - 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); -@@ -204,6 +205,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); -+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.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 -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); + authctxt->pw = fakepw(); +-#ifdef SSH_AUDIT_EVENTS +- PRIVSEP(audit_event(SSH_INVALID_USER)); +-#endif + } + #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) /* 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) + buffer_len(&b))) == 1) { authenticated = 1; - -@@ -140,6 +140,18 @@ done: + authctxt->last_details = pubkey; +@@ -169,6 +169,18 @@ done: return authenticated; } @@ -836,19 +815,19 @@ 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 -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)) && + 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) + buffer_len(&b))) == 1) { authenticated = 1; - buffer_free(&b); -@@ -223,6 +223,18 @@ pubkey_auth_info(Authctxt *authctxt, con + authctxt->last_details = pubkey; +@@ -252,6 +252,18 @@ pubkey_auth_info(Authctxt *authctxt, con free(extra); } @@ -864,30 +843,49 @@ diff -up openssh-6.3p1/auth2-pubkey.c.audit openssh-6.3p1/auth2-pubkey.c + return rv; +} + - 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 - } else { - logit("input_userauth_request: invalid user %s", user); - authctxt->pw = fakepw(); + /* + * 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) + record_failed_login(user, + auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); + #endif -#ifdef SSH_AUDIT_EVENTS -- PRIVSEP(audit_event(SSH_INVALID_USER)); --#endif - } - #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 - extern const EVP_CIPHER *evp_ssh1_3des(void); - extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); +- audit_event(SSH_INVALID_USER); +-#endif /* SSH_AUDIT_EVENTS */ + 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 --struct Cipher { + 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); +@@ -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.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; - int number; /* for ssh1 only */ - u_int block_size; @@ -895,22 +893,30 @@ 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) +-#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 -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 @@ - typedef struct Cipher Cipher; - typedef struct CipherContext CipherContext; +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 Cipher; -+struct Cipher { +-struct sshcipher; ++struct sshcipher { /* from cipher.c */ + char *name; + int number; /* for ssh1 only */ + u_int block_size; @@ -918,85 +924,91 @@ 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) ++#define CFLAG_AESCTR (1<<2) ++#define CFLAG_NONE (1<<3) ++#ifdef WITH_OPENSSL + const EVP_CIPHER *(*evptype)(void); ++#else ++ void *ignored; ++#endif +}; -+ - 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" - #include "monitor.h" - #include "roaming.h" + 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" +#include "audit.h" - #if OPENSSL_VERSION_NUMBER >= 0x00907000L - # if defined(HAVE_EVP_SHA256) -@@ -341,9 +342,13 @@ static void - choose_enc(Enc *enc, char *client, char *server) + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -683,8 +684,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); ++ audit_unsupported(SSH_AUDIT_UNSUPPORTED_CIPHER); +#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; -@@ -359,9 +364,13 @@ static void - choose_mac(Mac *mac, char *client, char *server) +@@ -702,8 +707,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); ++ audit_unsupported(SSH_AUDIT_UNSUPPORTED_MAC); +#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 */ -@@ -376,8 +385,12 @@ static void - choose_comp(Comp *comp, char *client, char *server) +@@ -720,8 +729,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); ++ audit_unsupported(SSH_AUDIT_UNSUPPORTED_COMPRESSION); +#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) { -@@ -492,6 +505,9 @@ kex_choose_conf(Kex *kex) - newkeys->enc.name, - authlen == 0 ? newkeys->mac.name : "", - newkeys->comp.name); +@@ -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(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], -@@ -656,3 +672,34 @@ dump_digest(char *msg, u_char *digest, i - fprintf(stderr, "\n"); + /* XXX need runden? */ + kex->we_need = need; +@@ -1064,3 +1081,33 @@ 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; @@ -1007,7 +1019,7 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c + } + + if (enc->iv) { -+ memset(enc->iv, 0, enc->block_size); ++ memset(enc->iv, 0, enc->iv_len); + free(enc->iv); + } + @@ -1015,7 +1027,7 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c +} + +void -+newkeys_destroy(Newkeys *newkeys) ++newkeys_destroy(struct newkeys *newkeys) +{ + if (newkeys == NULL) + return; @@ -1024,73 +1036,38 @@ diff -up openssh-6.3p1/kex.c.audit openssh-6.3p1/kex.c + mac_destroy(&newkeys->mac); + 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 -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 -+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 -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) - } - - 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 -+ default: -+ fatal("key_is_private: bad key type %d", k->type); -+ return 1; -+ } -+} -+ -+int - 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); - 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_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) + 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 + #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) mac->umac_ctx = NULL; } +void -+mac_destroy(Mac *mac) ++mac_destroy(struct sshmac *mac) +{ + if (mac == NULL) + return; @@ -1106,35 +1083,49 @@ 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 -@@ -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" - #include "roaming.h" +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); + void mac_clear(struct sshmac *); ++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} \ + 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 + + 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 +@@ -102,6 +102,7 @@ + #include "compat.h" + #include "ssh2.h" #include "authfd.h" +#include "audit.h" + #include "match.h" + #include "ssherr.h" - #ifdef GSSAPI - static Gssctxt *gsscontext = NULL; -@@ -114,6 +115,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 { -@@ -186,6 +189,11 @@ int mm_answer_gss_checkmic(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 *); @@ -1146,7 +1137,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[] +@@ -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}, @@ -1157,7 +1148,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 +@@ -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}, @@ -1169,30 +1160,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[] - #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 - {0, 0, NULL} - }; -@@ -315,6 +336,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 - {0, 0, NULL} - }; -@@ -1365,9 +1391,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; @@ -1204,7 +1172,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) +@@ -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__); @@ -1213,7 +1181,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) +@@ -1426,7 +1447,17 @@ mm_answer_keyverify(int sock, Buffer *m) if (!valid_data) fatal("%s: bad signature data blob", __func__); @@ -1232,7 +1200,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) +@@ -1489,6 +1520,12 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } @@ -1245,7 +1213,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) +@@ -1591,6 +1628,8 @@ mm_answer_term(int sock, Buffer *req) sshpam_cleanup(); #endif @@ -1254,7 +1222,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 +@@ -1633,11 +1672,45 @@ mm_answer_audit_command(int socket, Buff { u_int len; char *cmd; @@ -1269,7 +1237,9 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.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); @@ -1299,24 +1269,18 @@ 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 +@@ -1690,6 +1763,7 @@ monitor_apply_keystate(struct monitor *p + 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 */ -@@ -1960,6 +2042,21 @@ mm_get_keystate(struct monitor *pmonitor - } - - buffer_free(&m); + if ((child_state = sshbuf_new()) == NULL) +@@ -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__); + +#ifdef SSH_AUDIT_EVENTS + if (compat20) { @@ -1335,11 +1299,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, - } +@@ -1953,3 +2042,86 @@ mm_answer_gss_updatecreds(int socket, Bu + + #endif /* GSSAPI */ - #endif /* JPAKE */ -+ +#ifdef SSH_AUDIT_EVENTS +int +mm_answer_audit_unsupported_body(int sock, Buffer *m) @@ -1360,7 +1323,7 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c +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; + @@ -1368,14 +1331,16 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c + 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); @@ -1418,14 +1383,13 @@ diff -up openssh-6.3p1/monitor.c.audit openssh-6.3p1/monitor.c + free(fp); + buffer_clear(m); + -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m); + 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 -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, MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, @@ -1436,14 +1400,14 @@ diff -up openssh-6.3p1/monitor.h.audit openssh-6.3p1/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 }; -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 -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 @@ -1452,7 +1416,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 +@@ -467,6 +467,7 @@ mm_key_verify(Key *key, u_char *sig, u_i return (0); buffer_init(&m); @@ -1460,7 +1424,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 +@@ -484,6 +485,18 @@ mm_key_verify(Key *key, u_char *sig, u_i return (verified); } @@ -1476,26 +1440,10 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c + 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) -@@ -642,12 +656,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); -@@ -1191,10 +1207,11 @@ mm_audit_event(ssh_audit_event_t event) + void + mm_send_keystate(struct monitor *monitor) + { +@@ -861,10 +874,11 @@ mm_audit_event(ssh_audit_event_t event) buffer_free(&m); } @@ -1508,7 +1456,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 +@@ -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); @@ -1535,11 +1483,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 */ -+ +@@ -1007,3 +1041,70 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc + + #endif /* GSSAPI */ + +#ifdef SSH_AUDIT_EVENTS +void +mm_audit_unsupported_body(int what) @@ -1557,7 +1504,7 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/monitor_wrap.c +} + +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; @@ -1565,8 +1512,9 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/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); + buffer_put_int64(&m, uid); + @@ -1603,25 +1551,23 @@ diff -up openssh-6.4p1/monitor_wrap.c.audit openssh-6.4p1/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 -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 - 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 *); +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 *); -@@ -74,7 +75,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); @@ -1629,25 +1575,25 @@ diff -up openssh-6.3p1/monitor_wrap.h.audit openssh-6.3p1/monitor_wrap.h +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 -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 -@@ -61,6 +61,7 @@ - #include +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" +#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" +@@ -494,6 +495,13 @@ ssh_packet_get_connection_out(struct ssh + return ssh->state->connection_out; } +static int @@ -1657,50 +1603,75 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c + (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL); +} + - /* Closes the connection and clears and frees internal data structures. */ + /* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. +@@ -510,11 +510,12 @@ + const char * + ssh_remote_ipaddr(struct ssh *ssh) + { +- const int sock = ssh->state->connection_in; ++ int sock; - void -@@ -484,13 +492,6 @@ packet_close(void) - if (!active_state->initialized) + /* Check whether we have cached the ipaddr. */ + if (ssh->remote_ipaddr == NULL) { + if (ssh_packet_connection_is_on_socket(ssh)) { ++ sock = ssh->state->connection_in; + ssh->remote_ipaddr = get_peer_ipaddr(sock); + ssh->remote_port = get_peer_port(sock); + ssh->local_ipaddr = get_local_ipaddr(sock); +@@ -562,13 +570,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); +@@ -600,11 +601,21 @@ 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); -+ audit_session_key_free(2); +- 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); ++ audit_session_key_free(MODE_MAX); + } -+ if (active_state->connection_in == active_state->connection_out) { -+ shutdown(active_state->connection_out, SHUT_RDWR); -+ close(active_state->connection_out); + 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(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. */ -@@ -735,6 +746,25 @@ packet_send1(void) - */ +@@ -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); + cipher_free(*ccp); + *ccp = NULL; + enc = &state->newkeys[mode]->enc; +@@ -2440,6 +2452,72 @@ 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; @@ -1718,51 +1689,27 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c + free(newkeys); +} + - void - set_newkeys(int mode) - { -@@ -760,21 +790,9 @@ 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) - return (void *)active_state->newkeys[mode]; - } - +static void +packet_destroy_state(struct session_state *state) +{ + 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); -+ 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]); @@ -1776,77 +1723,35 @@ diff -up openssh-6.3p1/packet.c.audit openssh-6.3p1/packet.c +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)); ++ if (active_state != NULL) ++ packet_destroy_state(active_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 + } +} + - /* - * 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) - void - packet_backup_state(void) - { -- struct session_state *tmp; -- - close(active_state->connection_in); - active_state->connection_in = -1; - close(active_state->connection_out); - active_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(); - } - - /* -@@ -2038,9 +2091,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); - if (len > 0) { - buf = buffer_ptr(&backup_state->input); -@@ -2048,4 +2099,10 @@ packet_restore_state(void) - buffer_clear(&backup_state->input); - add_recv_bytes(len); - } -+ backup_state->connection_in = -1; -+ backup_state->connection_out = -1; -+ packet_destroy_state(backup_state); -+ free(backup_state); -+ 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 -@@ -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 */ + 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; + # undef EC_POINT + #endif +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 -@@ -137,7 +137,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; @@ -1855,23 +1760,23 @@ 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 +@@ -576,6 +576,14 @@ do_exec_pty(Session *s, const char *comm /* 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. */ -+ if (!(options.use_login && command == NULL)) ++ if (command != NULL) + audit_count_session_open(); +#endif + /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, -@@ -816,15 +824,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 + if (s->command != NULL || s->command_handle != -1) @@ -1887,12 +1792,12 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c - 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); -@@ -1642,7 +1654,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 */ @@ -1904,15 +1809,17 @@ 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) +@@ -1757,6 +1772,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; } -@@ -1951,6 +1967,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1839,6 +1857,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1923,7 +1830,7 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/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; +} @@ -1932,7 +1839,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 +@@ -2351,6 +2382,32 @@ session_exit_message(Session *s, int sta chan_write_failed(c); } @@ -1941,7 +1848,8 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c +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; @@ -1952,7 +1860,8 @@ diff -up openssh-6.3p1/session.c.audit openssh-6.3p1/session.c +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; @@ -1963,8 +1872,8 @@ 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) - debug("session_close: session %d pid %ld", s->self, (long)s->pid); +@@ -2365,6 +2422,10 @@ session_close(Session *s) + if (s->ttyfd != -1) session_pty_cleanup(s); +#ifdef SSH_AUDIT_EVENTS @@ -1974,7 +1883,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) +@@ -2575,6 +2636,15 @@ do_authenticated2(Authctxt *authctxt) server_loop2(authctxt); } @@ -1990,16 +1899,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) +@@ -2626,7 +2696,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-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 + + /* 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 @@ -60,6 +60,12 @@ struct Session { char *name; char *val; @@ -2024,27 +1935,27 @@ 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 -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" - #include "roaming.h" +#include "audit.h" #include "ssh-sandbox.h" #include "version.h" - -@@ -260,7 +261,7 @@ Buffer loginmsg; + #include "ssherr.h" +@@ -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); - static void do_ssh1_kex(void); -@@ -279,6 +280,15 @@ close_listen_socks(void) +@@ -261,6 +262,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2054,13 +1965,13 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c + */ +int listening_for_clients(void) +{ -+ return num_listen_socks > 0; ++ return num_listen_socks >= 0; +} + static void close_startup_pipes(void) { -@@ -550,22 +560,47 @@ sshd_exchange_identification(int sock_in +@@ -473,18 +483,45 @@ sshd_exchange_identification(struct ssh } } @@ -2074,34 +1985,32 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c +destroy_sensitive_data(int privsep) { int i; ++#ifdef SSH_AUDIT_EVENTS + pid_t pid; + uid_t uid; - if (sensitive_data.server_key) { - key_free(sensitive_data.server_key); - sensitive_data.server_key = NULL; - } + pid = getpid(); + uid = getuid(); ++#endif for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { + 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 = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); + else + fp = NULL; 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); + } } @@ -2111,81 +2020,68 @@ 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 - demote_sensitive_data(void) +@@ -497,12 +534,30 @@ 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) { -@@ -587,13 +624,27 @@ demote_sensitive_data(void) - sensitive_data.server_key = tmp; - } + pid = getpid(); + uid = getuid(); ++#endif for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { + 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 = 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]); 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); ++#endif + free(fp); + } } /* Certs do not need demotion */ } -@@ -652,7 +703,7 @@ privsep_preauth(Authctxt *authctxt) +@@ -585,7 +640,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) - } - } - -+extern Newkeys *current_keys[]; -+ - static void - privsep_postauth(Authctxt *authctxt) - { -@@ -732,6 +785,10 @@ 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); -+ 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 */ -@@ -1178,6 +1235,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); + destroy_sensitive_data(0); close_listen_socks(); - unlink(options.pid_file); - exit(received_sigterm == SIGTERM ? 0 : 255); -@@ -2093,6 +2151,7 @@ main(int ac, char **av) + 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); @@ -2193,46 +2089,17 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/sshd.c exit(0); } -@@ -2135,7 +2194,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, -@@ -2145,6 +2204,9 @@ main(int ac, char **av) +@@ -2148,6 +2207,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", -@@ -2302,6 +2364,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"); -+#endif -+ - debug("Encryption type: %.200s", cipher_name(cipher_type)); - - /* Get the encrypted integer. */ -@@ -2368,7 +2434,7 @@ do_ssh1_kex(void) - session_id[i] = session_key[i] ^ session_key[i + 16]; - } - /* Destroy the private and public keys. No longer. */ -- destroy_sensitive_data(); -+ destroy_sensitive_data(0); - - if (use_privsep) - mm_ssh1_session_id(session_id); -@@ -2480,6 +2546,16 @@ do_ssh2_kex(void) + (unsigned long long)obytes, (unsigned long long)ibytes); +@@ -2321,6 +2383,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { @@ -2248,8 +2115,8 @@ 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) + if (use_privsep && privsep_is_preauth && +@@ -2332,9 +2404,14 @@ cleanup_exit(int i) pmonitor->m_pid, strerror(errno)); } } @@ -2265,3 +2132,51 @@ diff -up openssh-6.3p1/sshd.c.audit openssh-6.3p1/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) + } + + int ++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_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 /* 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-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 **); + 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 --git a/openssh-7.4p1-authorized_keys_command.patch b/openssh-7.4p1-authorized_keys_command.patch new file mode 100644 index 0000000..86f887d --- /dev/null +++ b/openssh-7.4p1-authorized_keys_command.patch @@ -0,0 +1,38 @@ +From ddd3d34e5c7979ca6f4a3a98a7d219a4ed3d98c2 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Fri, 30 Dec 2016 22:08:02 +0000 +Subject: [PATCH] upstream commit + +fix deadlock when keys/principals command produces a lot of +output and a key is matched early; bz#2655, patch from jboning AT gmail.com + +Upstream-ID: e19456429bf99087ea994432c16d00a642060afe +--- + auth2-pubkey.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index 20f3309e1..70c021589 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -727,6 +727,9 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key) + + ok = process_principals(f, NULL, pw, cert); + ++ fclose(f); ++ f = NULL; ++ + if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0) + goto out; + +@@ -1050,6 +1053,9 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) + + ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); + ++ fclose(f); ++ f = NULL; ++ + if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0) + goto out; + + diff --git a/openssh-7.4p1-canonize-pkcs11-provider.patch b/openssh-7.4p1-canonize-pkcs11-provider.patch new file mode 100644 index 0000000..f626a1d --- /dev/null +++ b/openssh-7.4p1-canonize-pkcs11-provider.patch @@ -0,0 +1,50 @@ +diff --git a/ssh-agent.c b/ssh-agent.c +index 1320cda..2441329 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -821,7 +821,7 @@ send: + static void + process_remove_smartcard_key(SocketEntry *e) + { +- char *provider = NULL, *pin = NULL; ++ char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; + int r, version, success = 0; + Identity *id, *nxt; + Idtab *tab; +@@ -831,6 +831,13 @@ process_remove_smartcard_key(SocketEntry *e) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + free(pin); + ++ if (realpath(provider, canonical_provider) == NULL) { ++ verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", ++ provider, strerror(errno)); ++ goto send; ++ } ++ ++ debug("%s: remove %.100s", __func__, canonical_provider); + for (version = 1; version < 3; version++) { + tab = idtab_lookup(version); + for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { +@@ -838,18 +845,19 @@ process_remove_smartcard_key(SocketEntry *e) + /* Skip file--based keys */ + if (id->provider == NULL) + continue; +- if (!strcmp(provider, id->provider)) { ++ if (!strcmp(canonical_provider, id->provider)) { + TAILQ_REMOVE(&tab->idlist, id, next); + free_identity(id); + tab->nentries--; + } + } + } +- if (pkcs11_del_provider(provider) == 0) ++ if (pkcs11_del_provider(canonical_provider) == 0) + success = 1; + else + error("process_remove_smartcard_key:" + " pkcs11_del_provider failed"); ++send: + free(provider); + send_status(e, success); + } + diff --git a/openssh-7.4p1-cbc-weakness.patch b/openssh-7.4p1-cbc-weakness.patch new file mode 100644 index 0000000..f05b564 --- /dev/null +++ b/openssh-7.4p1-cbc-weakness.patch @@ -0,0 +1,30 @@ +commit 0fb1a617a07b8df5de188dd5a0c8bf293d4bfc0e +Author: markus@openbsd.org +Date: Sat Mar 11 13:07:35 2017 +0000 + + upstream commit + + Don't count the initial block twice when computing how + many bytes to discard for the work around for the attacks against CBC-mode. + ok djm@; report from Jean Paul, Kenny, Martin and Torben @ RHUL + + Upstream-ID: f445f509a4e0a7ba3b9c0dae7311cb42458dc1e2 + +diff --git a/packet.c b/packet.c +index 01e2d45..2f3a2ec 100644 +--- a/packet.c ++++ b/packet.c +@@ -1850,11 +1850,11 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + if (r != SSH_ERR_MAC_INVALID) + goto out; + logit("Corrupted MAC on input."); +- if (need > 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); ++ PACKET_MAX_SIZE - need - block_size); + } + /* Remove MAC from input buffer */ + DBG(debug("MAC #%d ok", state->p_read.seqnr)); diff --git a/openssh-7.4p1-coverity.patch b/openssh-7.4p1-coverity.patch new file mode 100644 index 0000000..a80d4d5 --- /dev/null +++ b/openssh-7.4p1-coverity.patch @@ -0,0 +1,574 @@ +diff -up openssh-7.4p1/auth-pam.c.coverity openssh-7.4p1/auth-pam.c +diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c +--- openssh-7.4p1/channels.c.coverity 2017-02-09 14:58:32.786064600 +0100 ++++ openssh-7.4p1/channels.c 2017-02-09 15:01:28.869890219 +0100 +@@ -266,11 +266,11 @@ channel_register_fds(Channel *c, int rfd + channel_max_fd = MAXIMUM(channel_max_fd, wfd); + channel_max_fd = MAXIMUM(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; +@@ -288,11 +288,11 @@ channel_register_fds(Channel *c, int rfd + + /* enable nonblocking mode */ + if (nonblock) { +- if (rfd != -1) ++ if (rfd >= 0) + set_nonblock(rfd); +- if (wfd != -1) ++ if (wfd >= 0) + set_nonblock(wfd); +- if (efd != -1) ++ if (efd >= 0) + set_nonblock(efd); + } + } +diff -up openssh-7.4p1/clientloop.c.coverity openssh-7.4p1/clientloop.c +diff -up openssh-7.4p1/key.c.coverity openssh-7.4p1/key.c +diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c +--- openssh-7.4p1/monitor.c.coverity 2017-02-09 14:58:32.793064593 +0100 ++++ openssh-7.4p1/monitor.c 2017-02-09 14:58:32.805064581 +0100 +@@ -411,7 +411,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); +diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1/monitor_wrap.c.coverity 2017-02-09 14:58:32.797064589 +0100 ++++ openssh-7.4p1/monitor_wrap.c 2017-02-09 14:58:32.805064581 +0100 +@@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, + if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || + (tmp2 = dup(pmonitor->m_recvfd)) == -1) { + error("%s: cannot allocate fds for pty", __func__); +- if (tmp1 > 0) ++ if (tmp1 >= 0) + close(tmp1); +- if (tmp2 > 0) +- close(tmp2); ++ /*DEAD CODE if (tmp2 >= 0) ++ close(tmp2);*/ + return 0; + } + close(tmp1); +diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c +--- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/openbsd-compat/bindresvport.c 2017-02-09 14:58:32.805064581 +0100 +@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr + struct sockaddr_in6 *in6; + u_int16_t *portp; + u_int16_t port; +- socklen_t salen; ++ socklen_t salen = sizeof(struct sockaddr_storage); + int i; + + if (sa == NULL) { +diff -up openssh-7.4p1/packet.c.coverity openssh-7.4p1/packet.c +diff -up openssh-7.4p1/progressmeter.c.coverity openssh-7.4p1/progressmeter.c +diff -up openssh-7.4p1/scp.c.coverity openssh-7.4p1/scp.c +--- openssh-7.4p1/scp.c.coverity 2017-02-09 14:58:32.761064625 +0100 ++++ openssh-7.4p1/scp.c 2017-02-09 14:58:38.590058852 +0100 +@@ -157,7 +157,7 @@ killchild(int signo) + { + if (do_cmd_pid > 1) { + kill(do_cmd_pid, signo ? signo : SIGTERM); +- waitpid(do_cmd_pid, NULL, 0); ++ (void) waitpid(do_cmd_pid, NULL, 0); + } + + if (signo) +diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.coverity 2017-02-09 14:58:32.801064585 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-09 14:58:38.591058851 +0100 +@@ -1544,7 +1544,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++) +@@ -1635,8 +1635,9 @@ process_server_config_line(ServerOptions + if (*activep && *charptr == NULL) { + *charptr = tilde_expand_filename(arg, getuid()); + /* increase optional counter */ +- if (intptr != NULL) +- *intptr = *intptr + 1; ++ /* DEAD CODE intptr is still NULL ;) ++ if (intptr != NULL) ++ *intptr = *intptr + 1; */ + } + break; + +diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c +--- openssh-7.4p1/serverloop.c.coverity 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/serverloop.c 2017-02-09 14:58:38.592058850 +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("notify_done: reading"); + } + +@@ -518,7 +518,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-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 2017-02-09 14:58:38.598058844 +0100 +@@ -224,7 +224,7 @@ killchild(int signo) + { + if (sshpid > 1) { + kill(sshpid, SIGTERM); +- waitpid(sshpid, NULL, 0); ++ (void) waitpid(sshpid, NULL, 0); + } + + _exit(1); +diff -up openssh-7.4p1/sftp-client.c.coverity openssh-7.4p1/sftp-client.c +--- openssh-7.4p1/sftp-client.c.coverity 2017-02-09 14:58:38.596058846 +0100 ++++ openssh-7.4p1/sftp-client.c 2017-02-09 15:20:18.893624636 +0100 +@@ -973,7 +973,7 @@ do_symlink(struct sftp_conn *conn, const + } + + int +-do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len) ++do_fsync(struct sftp_conn *conn, const u_char *handle, u_int handle_len) + { + struct sshbuf *msg; + u_int status, id; +--- openssh-7.4p1/sftp-client.h.coverity 2017-02-10 09:28:10.951155129 +0100 ++++ openssh-7.4p1/sftp-client.h 2017-02-10 09:27:28.685069870 +0100 +@@ -107,7 +107,7 @@ int do_hardlink(struct sftp_conn *, cons + int do_symlink(struct sftp_conn *, const char *, const char *); + + /* Call fsync() on open file 'handle' */ +-int do_fsync(struct sftp_conn *conn, u_char *, u_int); ++int do_fsync(struct sftp_conn *conn, const u_char *, u_int); + + /* + * Download 'remote_path' to 'local_path'. Preserve permissions and times +diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c +--- openssh-7.4p1/ssh-agent.c.coverity 2017-02-09 14:58:38.599058843 +0100 ++++ openssh-7.4p1/ssh-agent.c 2017-02-09 15:29:21.938917065 +0100 +@@ -1220,8 +1220,8 @@ main(int ac, char **av) + sanitise_stdfd(); + + /* drop */ +- setegid(getgid()); +- setgid(getgid()); ++ (void) setegid(getgid()); ++ (void) setgid(getgid()); + + platform_disable_tracing(0); /* strict=no */ + +diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.coverity 2017-02-09 14:58:38.600058842 +0100 ++++ openssh-7.4p1/sshd.c 2017-02-09 15:30:33.403800831 +0100 +@@ -679,8 +679,10 @@ privsep_preauth(Authctxt *authctxt) + + privsep_preauth_child(); + setproctitle("%s", "[net]"); +- if (box != NULL) ++ if (box != NULL) { + ssh_sandbox_child(box); ++ free(box); ++ } + + return 0; + } +@@ -1382,6 +1384,9 @@ server_accept_loop(int *sock_in, int *so + if (num_listen_socks < 0) + break; + } ++ ++ if (fdset != NULL) ++ free(fdset); + } + + /* +diff --git a/auth-pam.c b/auth-pam.c +index e554ec4..bd16d80 100644 +--- a/auth-pam.c ++++ b/auth-pam.c +@@ -834,6 +834,8 @@ fake_password(const char *wire_password) + fatal("%s: password length too long: %zu", __func__, l); + + ret = malloc(l + 1); ++ if (ret == NULL) ++ return NULL; + for (i = 0; i < l; i++) + ret[i] = junk[i % (sizeof(junk) - 1)]; + ret[i] = '\0'; +diff --git a/clientloop.c b/clientloop.c +index c6a4138..9b00e12 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -2290,7 +2290,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) + free(response); + response = read_passphrase("Accept updated hostkeys? " + "(yes/no): ", RP_ECHO); +- if (strcasecmp(response, "yes") == 0) ++ if (response != NULL && strcasecmp(response, "yes") == 0) + break; + else if (quit_pending || response == NULL || + strcasecmp(response, "no") == 0) { +diff --git a/digest-openssl.c b/digest-openssl.c +index 13b63c2..dfa9b8d 100644 +--- a/digest-openssl.c ++++ b/digest-openssl.c +@@ -158,7 +158,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) + const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); + u_int l = dlen; + +- if (dlen > UINT_MAX) ++ if (digest == NULL || dlen > UINT_MAX) + return SSH_ERR_INVALID_ARGUMENT; + if (dlen < digest->digest_len) /* No truncation allowed */ + return SSH_ERR_INVALID_ARGUMENT; +diff --git a/kex.c b/kex.c +index a30dabe..a8ac91f 100644 +--- a/kex.c ++++ b/kex.c +@@ -178,7 +178,7 @@ kex_names_valid(const char *names) + char * + kex_names_cat(const char *a, const char *b) + { +- char *ret = NULL, *tmp = NULL, *cp, *p; ++ char *ret = NULL, *tmp = NULL, *cp, *p, *m; + size_t len; + + if (a == NULL || *a == '\0') +@@ -195,8 +195,10 @@ kex_names_cat(const char *a, const char *b) + } + strlcpy(ret, a, len); + for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { +- if (match_list(ret, p, NULL) != NULL) ++ if ((m = match_list(ret, p, NULL)) != NULL) { ++ free(m); + continue; /* Algorithm already present */ ++ } + if (strlcat(ret, ",", len) >= len || + strlcat(ret, p, len) >= len) { + free(tmp); +@@ -651,8 +653,10 @@ choose_enc(struct sshenc *enc, char *client, char *server) + #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; + enc->enabled = 0; + enc->iv = NULL; +@@ -670,8 +674,10 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) + #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 */ + if (ssh->compat & SSH_BUG_HMAC) + mac->key_len = 16; +@@ -695,6 +701,7 @@ choose_comp(struct sshcomp *comp, char *client, char *server) + } else if (strcmp(name, "none") == 0) { + comp->type = COMP_NONE; + } else { ++ free(name); + return SSH_ERR_INTERNAL_ERROR; + } + comp->name = name; +diff --git a/readconf.c b/readconf.c +index 3e7a5d8..acc1391 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -1500,6 +1500,7 @@ parse_keytypes: + if (r == GLOB_NOMATCH) { + debug("%.200s line %d: include %s matched no " + "files",filename, linenum, arg2); ++ free(arg2); + continue; + } else if (r != 0 || gl.gl_pathc < 0) + fatal("%.200s line %d: glob failed for %s.", +diff --git a/servconf.c b/servconf.c +index 6ab1cb4..5f2464a 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -2284,8 +2284,6 @@ dump_cfg_fmtint(ServerOpCodes code, int val) + static void + dump_cfg_string(ServerOpCodes code, const char *val) + { +- if (val == NULL) +- return; + printf("%s %s\n", lookup_opcode_name(code), + val == NULL ? "none" : val); + } +diff --git a/sshconnect.c b/sshconnect.c +index 07f80cd..5d4b41b 100644 +--- a/sshconnect.c ++++ b/sshconnect.c +@@ -1533,6 +1533,7 @@ maybe_add_key_to_agent(char *authfile, Key *private, char *comment, + if (options.add_keys_to_agent == 2 && + !ask_permission("Add key %s (%s) to agent?", authfile, comment)) { + debug3("user denied adding this key"); ++ close(auth_sock); + return; + } + +@@ -1541,4 +1542,5 @@ maybe_add_key_to_agent(char *authfile, Key *private, char *comment, + debug("identity added to agent: %s", authfile); + else + debug("could not add identity to agent: %s (%d)", authfile, r); ++ close(auth_sock); + } +diff --git a/sshconnect2.c b/sshconnect2.c +index f31c24c..aecf765 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -1061,6 +1061,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) + + if (key_to_blob(id->key, &blob, &bloblen) == 0) { + /* we cannot handle this key */ ++ free(blob); + debug3("sign_and_send_pubkey: cannot handle key"); + return 0; + } +@@ -1170,6 +1171,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id) + + if (key_to_blob(id->key, &blob, &bloblen) == 0) { + /* we cannot handle this key */ ++ free(blob); + debug3("send_pubkey_test: cannot handle key"); + return 0; + } +diff --git a/sshkey.c b/sshkey.c +index 85fd1bd..58c1051 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -1375,8 +1375,6 @@ sshkey_read(struct sshkey *ret, char **cpp) + retval = 0; + /*XXXX*/ + sshkey_free(k); +- if (retval != 0) +- break; + break; + default: + return SSH_ERR_INVALID_ARGUMENT; +diff --git a/krl.c b/krl.c +index e271a19..69bec99 100644 +--- a/krl.c ++++ b/krl.c +@@ -1089,7 +1089,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, + break; + case KRL_SECTION_SIGNATURE: + /* Handled above, but still need to stay in synch */ +- sshbuf_reset(sect); ++ sshbuf_free(sect); + sect = NULL; + if ((r = sshbuf_skip_string(copy)) != 0) + goto out; +@@ -1288,7 +1288,8 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key) + debug2("%s: checking KRL %s", __func__, path); + r = ssh_krl_check_key(krl, key); + out: +- close(fd); ++ if (fd != -1) ++ close(fd); + sshbuf_free(krlbuf); + ssh_krl_free(krl); + if (r != 0) +diff --git a/readconf.c b/readconf.c +index acc1391..c4dff15 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -1185,7 +1185,7 @@ parse_int: + value = cipher_number(arg); + if (value == -1) + fatal("%.200s line %d: Bad cipher '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (*activep && *intptr == -1) + *intptr = value; + break; +@@ -1196,7 +1196,7 @@ parse_int: + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) + fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (*activep && options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; +@@ -1207,7 +1207,7 @@ parse_int: + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (!mac_valid(*arg == '+' ? arg + 1 : arg)) + fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (*activep && options->macs == NULL) + options->macs = xstrdup(arg); + break; +@@ -1220,7 +1220,7 @@ parse_int: + filename, linenum); + if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) + fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (*activep && options->kex_algorithms == NULL) + options->kex_algorithms = xstrdup(arg); + break; +@@ -1235,7 +1235,7 @@ parse_keytypes: + filename, linenum); + if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) + fatal("%s line %d: Bad key types '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; +@@ -1248,7 +1248,7 @@ parse_keytypes: + value = proto_spec(arg); + if (value == SSH_PROTO_UNKNOWN) + fatal("%.200s line %d: Bad protocol spec '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (*activep && *intptr == SSH_PROTO_UNKNOWN) + *intptr = value; + break; +diff --git a/servconf.c b/servconf.c +index 5f2464a..4564494 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1217,7 +1217,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, + filename, linenum); + if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) + fatal("%s line %d: Bad key types '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; +@@ -1476,7 +1476,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, + fatal("%s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) + fatal("%s line %d: Bad SSH2 cipher spec '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; +@@ -1487,7 +1487,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, + fatal("%s line %d: Missing argument.", filename, linenum); + if (!mac_valid(*arg == '+' ? arg + 1 : arg)) + fatal("%s line %d: Bad SSH2 mac spec '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (options->macs == NULL) + options->macs = xstrdup(arg); + break; +@@ -1500,7 +1500,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, + filename, linenum); + if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) + fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", +- filename, linenum, arg ? arg : ""); ++ filename, linenum, arg); + if (options->kex_algorithms == NULL) + options->kex_algorithms = xstrdup(arg); + break; +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +index aaf712d..62a76b3 100644 +--- a/ssh-pkcs11.c ++++ b/ssh-pkcs11.c +@@ -536,8 +536,8 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, + X509_free(x509); + } + if (rsa && rsa->n && rsa->e && +- pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { +- key = sshkey_new(KEY_UNSPEC); ++ pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0 && ++ (key = sshkey_new(KEY_UNSPEC)) != NULL) { + key->rsa = rsa; + key->type = KEY_RSA; + key->flags |= SSHKEY_FLAG_EXT; +diff --git a/sshconnect1.c b/sshconnect1.c +index a045361..0e1a506 100644 +--- a/sshconnect1.c ++++ b/sshconnect1.c +@@ -520,7 +520,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr) + cookie[i] = packet_get_char(); + + /* 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); +@@ -532,7 +533,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr) + logit("Warning: This may be due to an old implementation of ssh."); + } + /* 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); +diff --git a/sshkey.c b/sshkey.c +index 58c1051..6afacb5 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -1239,6 +1239,9 @@ sshkey_read(struct sshkey *ret, char **cpp) + u_long bits; + #endif /* WITH_SSH1 */ + ++ if (ret == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ + cp = *cpp; + + switch (ret->type) { diff --git a/openssh-6.3p1-ctr-cavstest.patch b/openssh-7.4p1-ctr-cavstest.patch similarity index 86% rename from openssh-6.3p1-ctr-cavstest.patch rename to openssh-7.4p1-ctr-cavstest.patch index 5cd9997..eb43c79 100644 --- a/openssh-6.3p1-ctr-cavstest.patch +++ b/openssh-7.4p1-ctr-cavstest.patch @@ -1,6 +1,44 @@ -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 -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 + 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@ +@@ -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) + + 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 $(KEYCATLIBS) $(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 + $(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) ; \ + 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 -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 @@ +/* + * @@ -95,7 +133,7 @@ diff -up openssh-6.2p1/ctr-cavstest.c.ctr-cavs openssh-6.2p1/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; +} @@ -103,8 +141,8 @@ diff -up openssh-6.2p1/ctr-cavstest.c.ctr-cavs openssh-6.2p1/ctr-cavstest.c +int main (int argc, char *argv[]) +{ + -+ Cipher *c; -+ CipherContext cc; ++ const struct sshcipher *c; ++ struct sshcipher_ctx *cc; + char *algo = "aes128-ctr"; + char *hexkey = NULL; + char *hexiv = "00000000000000000000000000000000"; @@ -194,11 +232,11 @@ 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); + -+ cipher_cleanup(&cc); ++ cipher_free(cc); + + for (p = outdata; datalen > 0; ++p, --datalen) { + printf("%02X", (unsigned char)*p); @@ -210,41 +248,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-7.4p1-debian-restore-tcp-wrappers.patch b/openssh-7.4p1-debian-restore-tcp-wrappers.patch new file mode 100644 index 0000000..5fcc451 --- /dev/null +++ b/openssh-7.4p1-debian-restore-tcp-wrappers.patch @@ -0,0 +1,140 @@ +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 " Solaris process contract support: $SPC_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-7.4p1-expose-pam.patch b/openssh-7.4p1-expose-pam.patch new file mode 100644 index 0000000..e4e6d82 --- /dev/null +++ b/openssh-7.4p1-expose-pam.patch @@ -0,0 +1,517 @@ +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) + { + 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 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->version_addendum = NULL; + options->use_kuserok = -1; + options->enable_k5users = -1; ++ options->expose_auth_methods = -1; + options->fingerprint_hash = -1; + options->disable_forwarding = -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; + 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) +@@ -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(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); ++ dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + + /* string arguments */ +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.4p1-fips.patch b/openssh-7.4p1-fips.patch new file mode 100644 index 0000000..4c3ff51 --- /dev/null +++ b/openssh-7.4p1-fips.patch @@ -0,0 +1,798 @@ +diff -up openssh-7.4p1/cipher.c.fips openssh-7.4p1/cipher.c +--- openssh-7.4p1/cipher.c.fips 2017-02-09 14:53:47.174347449 +0100 ++++ openssh-7.4p1/cipher.c 2017-02-09 14:53:47.182347441 +0100 +@@ -39,6 +39,8 @@ + + #include + ++#include ++ + #include + #include + #include +@@ -116,6 +118,24 @@ static const struct sshcipher ciphers[] + { NULL, SSH_CIPHER_INVALID, 0, 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 }, ++ { "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 }, ++ { "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 }, ++ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } ++}; ++ + /*--*/ + + /* Returns a comma-separated list of supported ciphers. */ +@@ -126,7 +142,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->number != SSH_CIPHER_SSH2) + continue; + if (auth_only && c->auth_len == 0) +@@ -222,7 +238,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; +@@ -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.4p1/cipher-ctr.c.fips openssh-7.4p1/cipher-ctr.c +--- openssh-7.4p1/cipher-ctr.c.fips 2017-02-09 14:53:47.125347498 +0100 ++++ openssh-7.4p1/cipher-ctr.c 2017-02-09 14:53:47.182347441 +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-7.4p1/clientloop.c.fips openssh-7.4p1/clientloop.c +--- openssh-7.4p1/clientloop.c.fips 2017-05-30 19:10:26.537505598 +0200 ++++ openssh-7.4p1/clientloop.c 2017-05-30 19:10:26.571505583 +0200 +@@ -2452,7 +2452,7 @@ client_input_hostkeys(void) + /* Check that the key is accepted in HostkeyAlgorithms */ + if (match_pattern_list(sshkey_ssh_name(key), + options.hostkeyalgorithms ? options.hostkeyalgorithms : +- KEX_DEFAULT_PK_ALG, 0) != 1) { ++ (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), 0) != 1) { + debug3("%s: %s key not permitted by HostkeyAlgorithms", + __func__, sshkey_ssh_name(key)); + continue; +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 2017-02-09 14:53:47.182347441 +0100 +@@ -51,6 +51,7 @@ u_int dh_estimate(int); + * Miniumum increased in light of DH precomputation attacks. + */ + #define DH_GRP_MIN 1024 ++#define DH_GRP_MIN_FIPS 2048 + #define DH_GRP_MAX 8192 + + /* +diff -up openssh-7.4p1/entropy.c.fips openssh-7.4p1/entropy.c +--- openssh-7.4p1/entropy.c.fips 2017-02-09 14:53:47.116347507 +0100 ++++ openssh-7.4p1/entropy.c 2017-02-09 14:53:47.182347441 +0100 +@@ -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 -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c +--- openssh-7.4p1/kex.c.fips 2017-02-09 14:53:47.174347449 +0100 ++++ openssh-7.4p1/kex.c 2017-02-09 14:53:47.183347440 +0100 +@@ -35,6 +35,7 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include + #endif + + #include "ssh2.h" +@@ -124,6 +125,28 @@ static const struct kexalg kexalgs[] = { + { NULL, -1, -1, -1}, + }; + ++static const struct kexalg kexalgs_fips[] = { ++ { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { 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 }, ++ { 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, -1}, ++}; ++ + char * + kex_alg_list(char sep) + { +@@ -151,7 +169,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 +@@ -177,7 +195,10 @@ kex_names_valid(const char *names) + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (kex_alg_by_name(p) == NULL) { +- error("Unsupported KEX algorithm \"%.100s\"", p); ++ if (FIPS_mode()) ++ error("\"%.100s\" is not allowed in FIPS mode", p); ++ else ++ error("Unsupported KEX algorithm \"%.100s\"", p); + free(s); + return 0; + } +diff -up openssh-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 2017-02-09 14:53:47.183347440 +0100 +@@ -28,6 +28,7 @@ + + #ifdef WITH_OPENSSL + ++#include + #include + + #include +@@ -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-7.4p1/kexgexs.c.fips openssh-7.4p1/kexgexs.c +--- openssh-7.4p1/kexgexs.c.fips 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/kexgexs.c 2017-02-09 14:53:47.183347440 +0100 +@@ -83,9 +83,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.4p1/mac.c.fips openssh-7.4p1/mac.c +--- openssh-7.4p1/mac.c.fips 2017-02-09 14:53:47.175347448 +0100 ++++ openssh-7.4p1/mac.c 2017-02-09 14:53:47.183347440 +0100 +@@ -27,6 +27,8 @@ + + #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 }, +@@ -89,6 +91,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) +@@ -97,7 +117,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); +@@ -136,7 +156,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.4p1/Makefile.in.fips openssh-7.4p1/Makefile.in +--- openssh-7.4p1/Makefile.in.fips 2017-02-09 14:53:47.175347448 +0100 ++++ openssh-7.4p1/Makefile.in 2017-02-09 14:53:47.184347440 +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 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) +@@ -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 +- $(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.4p1/myproposal.h.fips openssh-7.4p1/myproposal.h +--- openssh-7.4p1/myproposal.h.fips 2017-05-30 19:10:26.535505599 +0200 ++++ openssh-7.4p1/myproposal.h 2017-05-30 19:10:26.574505582 +0200 +@@ -119,6 +119,14 @@ + "ssh-rsa," \ + "ssh-dss" + ++#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_CLIENT_ENCRYPT \ +@@ -144,6 +152,38 @@ + + #define KEX_CLIENT_MAC KEX_SERVER_MAC + ++#define KEX_FIPS_ENCRYPT \ ++ "aes128-ctr,aes192-ctr,aes256-ctr" \ ++ AESGCM_CIPHER_MODES "," \ ++ "aes128-cbc,3des-cbc," \ ++ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" ++#ifdef HAVE_EVP_SHA256 ++# 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," \ ++ "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 ++ + #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 2017-02-09 14:53:47.185347438 +0100 ++++ openssh-7.4p1/readconf.c 2017-02-09 14:56:24.840191308 +0100 +@@ -2104,12 +2104,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__); + +@@ -2559,7 +2564,8 @@ dump_client_config(Options *o, const cha + char buf[8]; + + /* This is normally prepared in ssh_kex2 */ +- if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) ++ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG), &o->hostkeyalgorithms) != 0) + fatal("%s: kex_assemble_names failed", __func__); + + /* Most interesting options first: user, host, port */ +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 2017-02-09 14:53:47.177347446 +0100 ++++ openssh-7.4p1/sandbox-seccomp-filter.c 2017-02-09 14:53:47.185347438 +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 2017-06-07 13:07:28.403983349 +0200 ++++ openssh-7.4p1/servconf.c 2017-06-07 13:09:46.710997099 +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((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"); + } + +@@ -2390,8 +2396,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 ? "none" : o->banner); + dump_cfg_string(sForceCommand, o->adm_forced_command); + dump_cfg_string(sChrootDirectory, o->chroot_directory); +@@ -2406,14 +2414,17 @@ 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); ++ o->hostbased_key_types : (FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG)); + dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? +- o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); ++ o->hostkeyalgorithms : (FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG)); + dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? +- o->pubkey_key_types : KEX_DEFAULT_PK_ALG); ++ o->pubkey_key_types : (FIPS_mode() ? KEX_FIPS_PK_ALG ++ : KEX_DEFAULT_PK_ALG)); + + /* string arguments requiring a lookup */ + dump_cfg_string(sLogLevel, log_level_name(o->log_level)); +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 2017-02-09 14:53:47.185347438 +0100 +@@ -76,6 +76,8 @@ + #include + #include + #endif ++#include ++#include + #include "openbsd-compat/openssl-compat.h" + #include "openbsd-compat/sys-queue.h" + +@@ -530,6 +532,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 (FIPS_mode()) ++ fatal("FIPS integrity verification test failed."); ++ else ++ logit("FIPS integrity verification test failed."); ++ } + + #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); + + #ifdef WITH_OPENSSL +- OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); + #endif + +@@ -1175,6 +1187,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); + +@@ -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.4p1/sshconnect2.c.fips openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1/sshconnect2.c.fips 2017-02-09 14:53:47.162347461 +0100 ++++ openssh-7.4p1/sshconnect2.c 2017-02-09 14:53:47.186347437 +0100 +@@ -44,6 +44,8 @@ + #include + #endif + ++#include ++ + #include "openbsd-compat/sys-queue.h" + + #include "xmalloc.h" +@@ -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) { +- /* Add the GSSAPI mechanisms currently supported on this +- * client to the key exchange algorithm proposal */ +- orig = options.kex_algorithms; +- +- 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_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 +@@ -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.4p1/sshd.c.fips openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.fips 2017-02-09 14:53:47.178347445 +0100 ++++ openssh-7.4p1/sshd.c 2017-02-09 14:53:47.186347437 +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 + +@@ -1471,6 +1474,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,7 +1634,7 @@ main(int ac, char **av) + else + closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); + +-#ifdef WITH_OPENSSL ++#if 0 /* FIPS */ + OpenSSL_add_all_algorithms(); + #endif + +@@ -1928,6 +1943,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) +@@ -2282,10 +2301,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 -up openssh-7.4p1/sshkey.c.fips openssh-7.4p1/sshkey.c +--- openssh-7.4p1/sshkey.c.fips 2017-02-09 14:53:47.179347444 +0100 ++++ openssh-7.4p1/sshkey.c 2017-02-09 14:58:02.117094971 +0100 +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #endif + + #include "crypto_api.h" +@@ -57,6 +58,7 @@ + #include "sshkey.h" + #include "match.h" + #include "xmalloc.h" ++#include "log.h" + + /* openssh private key file format */ + #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" +@@ -1555,6 +1557,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; + } +@@ -3921,8 +3925,11 @@ sshkey_parse_private_fileblob_type(struc + switch (type) { + #ifdef WITH_SSH1 + case KEY_RSA1: +- return sshkey_parse_private_rsa1(blob, passphrase, +- keyp, commentp); ++ if (! FIPS_mode()) ++ return sshkey_parse_private_rsa1(blob, passphrase, ++ keyp, commentp); ++ error("%s: cannot parse rsa1 key in FIPS mode", __func__); ++ return SSH_ERR_KEY_TYPE_UNKNOWN; + #endif /* WITH_SSH1 */ + #ifdef WITH_OPENSSL + case KEY_DSA: +@@ -3961,8 +3968,9 @@ sshkey_parse_private_fileblob(struct ssh + #ifdef WITH_SSH1 + /* it's a SSH v1 key if the public key part is readable */ + if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) { +- return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, +- passphrase, keyp, commentp); ++ if (!FIPS_mode()) ++ return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, ++ passphrase, keyp, commentp); + } + #endif /* WITH_SSH1 */ + return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, +diff -up openssh-7.4p1/ssh-keygen.c.fips openssh-7.4p1/ssh-keygen.c +--- openssh-7.4p1/ssh-keygen.c.fips 2017-05-22 13:50:06.731776762 +0200 ++++ openssh-7.4p1/ssh-keygen.c 2017-05-22 13:50:11.843773909 +0200 +@@ -215,6 +215,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-6.4p1-gsissh.patch b/openssh-7.4p1-gsissh.patch similarity index 53% rename from openssh-6.4p1-gsissh.patch rename to openssh-7.4p1-gsissh.patch index edd513a..06d92e2 100644 --- a/openssh-6.4p1-gsissh.patch +++ b/openssh-7.4p1-gsissh.patch @@ -1,7 +1,7 @@ -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-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c +--- openssh-7.4p1.orig/auth2.c 2019-08-07 23:53:43.366924029 +0200 ++++ openssh-7.4p1/auth2.c 2019-08-07 23:54:19.617546829 +0200 +@@ -228,7 +228,27 @@ user = packet_get_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(NULL); @@ -30,12 +30,13 @@ diff -Nur openssh-6.4p1.orig/auth2.c openssh-6.4p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -@@ -245,23 +265,48 @@ +@@ -239,23 +259,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 +47,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 +57,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 +83,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 +315,10 @@ userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); @@ -96,18 +97,18 @@ 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 -@@ -47,6 +47,7 @@ +diff -Nur openssh-7.4p1.orig/auth2-gss.c openssh-7.4p1/auth2-gss.c +--- openssh-7.4p1.orig/auth2-gss.c 2019-08-07 23:53:43.361924081 +0200 ++++ openssh-7.4p1/auth2-gss.c 2019-08-08 09:15:33.820693618 +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; @@ -118,7 +119,7 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/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); @@ -134,13 +135,13 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/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 */)); + } + } @@ -149,19 +150,18 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/auth2-gss.c free(mic.value); return (authenticated); -@@ -102,7 +117,10 @@ - u_int len; - u_char *doid = NULL; +@@ -133,7 +148,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(); -@@ -171,7 +189,7 @@ +@@ -171,7 +188,7 @@ Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; @@ -170,7 +170,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 @@ +@@ -189,6 +206,7 @@ free(recv_tok.value); if (GSS_ERROR(maj_status)) { @@ -178,8 +178,8 @@ 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 @@ - gss_release_buffer(&maj_status, &send_tok); +@@ -254,6 +272,32 @@ + return 0; } +static void @@ -211,7 +211,13 @@ 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 @@ +@@ -264,11 +308,13 @@ + input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) + { + Authctxt *authctxt = ctxt; +- int authenticated; ++ int authenticated = 0; + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) fatal("No authentication or GSSAPI context"); @@ -220,7 +226,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 @@ +@@ -276,8 +322,11 @@ packet_check_eom(); @@ -229,40 +235,41 @@ diff -Nur openssh-6.4p1.orig/auth2-gss.c openssh-6.4p1/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 */)); -+ } else { -+ authenticated = 0; ++ authctxt->pw, 1 /* gssapi-keyex */)); + } - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -316,9 +368,16 @@ + if (authenticated) + authctxt->last_details = ssh_gssapi_get_displayname(); +@@ -322,11 +371,17 @@ gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_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; ++ authctxt->pw, 0 /* !gssapi-keyex */)); + } - else ++ } else { logit("GSSAPI MIC check failed"); ++ } -@@ -335,6 +394,23 @@ - userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); + if (authenticated) + authctxt->last_details = ssh_gssapi_get_displayname(); +@@ -345,6 +400,23 @@ + return 0; } +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); @@ -279,52 +286,20 @@ 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 -@@ -74,6 +74,9 @@ - #include "krl.h" - #include "compat.h" - -+#include "version.h" -+#include "ssh-globus-usage.h" -+ - /* import */ - extern ServerOptions options; - extern int use_privsep; -@@ -298,7 +301,8 @@ +diff -Nur openssh-7.4p1.orig/auth.c openssh-7.4p1/auth.c +--- openssh-7.4p1.orig/auth.c 2019-08-07 23:53:43.366924029 +0200 ++++ openssh-7.4p1/auth.c 2019-08-07 23:54:19.619546808 +0200 +@@ -314,7 +314,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(), - compat20 ? "ssh2" : "ssh1", -@@ -324,6 +328,21 @@ - if (authenticated == 0 && !authctxt->postponed) - audit_event(audit_classify_auth(method)); - #endif -+ if (authenticated) { -+ char *userdn = NULL; -+ char *mech_name = NULL; -+ ssh_gssapi_get_client_info(&userdn, &mech_name); -+ debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)", -+ SSH_RELEASE, SSLeay_version(SSLEAY_VERSION), -+ method, mech_name?mech_name:"NULL", get_remote_ipaddr(), -+ (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(), -+ authctxt->user, userdn); -+ } - } - - /* -@@ -604,6 +623,10 @@ + ssh_remote_ipaddr(ssh), + ssh_remote_port(ssh), + authctxt->info != NULL ? ": " : "", +@@ -642,6 +643,10 @@ #endif pw = getpwnam(user); @@ -335,42 +310,31 @@ 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 @@ +@@ -661,7 +666,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-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 -@@ -122,6 +122,10 @@ - */ + 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 2019-08-07 23:53:43.392923758 +0200 ++++ openssh-7.4p1/auth-pam.c 2019-08-07 23:54:19.620546798 +0200 +@@ -129,6 +129,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; ++# 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 -@@ -277,6 +281,55 @@ + struct pam_ctxt { +@@ -285,6 +289,56 @@ # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif @@ -399,12 +363,13 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/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)); + 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); @@ -420,13 +385,13 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/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 sshpam_password_change_required(int reqd) { -@@ -299,7 +352,7 @@ +@@ -307,7 +361,7 @@ static void import_environments(Buffer *b) { @@ -435,70 +400,79 @@ 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 @@ +@@ -317,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)); + 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)); + } /* Import environment from subprocess */ num_env = buffer_get_int(b); -@@ -473,6 +537,13 @@ +@@ -340,7 +405,7 @@ + /* Errors are not fatal here */ + if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { + error("PAM: pam_putenv: %s", +- pam_strerror(sshpam_handle, sshpam_err)); ++ pam_strerror(sshpam_handle, err)); + } + #endif + } +@@ -468,6 +533,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; -@@ -493,6 +564,11 @@ +@@ -488,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); + 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); + } /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) -@@ -910,6 +986,18 @@ +@@ -945,6 +1022,18 @@ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); + 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) { sshpam_account_status = 0; return (sshpam_account_status); -@@ -1207,6 +1295,9 @@ +@@ -1231,6 +1320,9 @@ pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); @@ -506,32 +480,32 @@ diff -Nur openssh-6.4p1.orig/auth-pam.c openssh-6.4p1/auth-pam.c + sshpam_check_userchanged(); + } 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 -@@ -46,5 +46,6 @@ - void sshpam_cleanup(void); - int sshpam_auth_passwd(Authctxt *, const char *); + 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 2019-08-07 23:53:43.203925725 +0200 ++++ openssh-7.4p1/auth-pam.h 2019-08-07 23:54:19.620546798 +0200 +@@ -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-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 -@@ -16,6 +16,7 @@ - +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 2019-08-07 23:54:19.620546798 +0200 +@@ -17,6 +17,7 @@ #include #include + #include +#include /* for MAXHOSTNAMELEN */ #include #include -@@ -451,3 +452,33 @@ +@@ -202,3 +203,33 @@ { - return get_port(1); + return get_sock_port(sock, 1); } + +void @@ -563,20 +537,20 @@ 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 -@@ -26,4 +26,6 @@ - int get_sock_port(int, int); - void clear_cached_addr(void); +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 2019-08-07 23:54:19.621546787 +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-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-7.4p1.orig/configure.ac openssh-7.4p1/configure.ac +--- openssh-7.4p1.orig/configure.ac 2019-08-07 23:53:43.323924476 +0200 ++++ openssh-7.4p1/configure.ac 2019-08-07 23:54:19.622546777 +0200 +@@ -4428,6 +4428,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -591,7 +565,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 @@ +@@ -4467,6 +4475,40 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) @@ -613,39 +587,29 @@ diff -Nur openssh-6.4p1.orig/configure.ac openssh-6.4p1/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 + -+ 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 + - # 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 -@@ -38,6 +38,7 @@ + # 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 2019-08-07 23:53:43.299924726 +0200 ++++ openssh-7.4p1/gss-genr.c 2019-08-07 23:54:19.623546766 +0200 +@@ -39,6 +39,7 @@ #include "xmalloc.h" #include "buffer.h" #include "log.h" @@ -662,13 +626,13 @@ diff -Nur openssh-6.4p1.orig/gss-genr.c openssh-6.4p1/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); @@ -681,29 +645,31 @@ 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-7.4p1.orig/gss-serv.c openssh-7.4p1/gss-serv.c +--- openssh-7.4p1.orig/gss-serv.c 2019-08-07 23:53:43.308924632 +0200 ++++ openssh-7.4p1/gss-serv.c 2019-08-08 09:09:24.848556910 +0200 +@@ -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, 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}; ++ { {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 = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -63,14 +65,23 @@ +@@ -62,14 +64,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[]= { @@ -711,6 +677,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c &gssapi_kerberos_mech, #endif +#ifdef GSI ++ &gssapi_gsi_mech_micv2, + &gssapi_gsi_mech, +#endif &gssapi_null_mech, @@ -719,20 +686,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. +@@ -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"); @@ -743,14 +701,17 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c } return (status); -@@ -231,6 +247,17 @@ +@@ -248,6 +266,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 +722,16 @@ 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 @@ +@@ -308,21 +340,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; } @@ -770,12 +740,36 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/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); -@@ -342,9 +372,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)) { +@@ -337,9 +372,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; +@@ -356,12 +391,17 @@ + i++; + } + ++ if (client->oid.elements == NULL) ++ client->oid = *ctx->oid; if (client->mech == NULL) return GSS_S_FAILURE; @@ -786,11 +780,27 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/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); } -@@ -371,6 +404,10 @@ +@@ -378,16 +418,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; @@ -801,7 +811,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c return (ctx->major); } -@@ -378,6 +415,7 @@ +@@ -395,6 +444,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -809,7 +819,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 @@ +@@ -410,6 +460,14 @@ gssapi_client.store.data = NULL; } } @@ -824,43 +834,49 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/gss-serv.c } /* As user */ -@@ -400,6 +446,11 @@ +@@ -417,6 +475,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"); -@@ -423,8 +474,9 @@ - } +@@ -451,15 +514,17 @@ /* 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; -@@ -433,6 +485,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; -@@ -451,6 +509,24 @@ +@@ -470,6 +535,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; +@@ -479,6 +545,24 @@ return (0); } @@ -868,24 +884,24 @@ diff -Nur openssh-6.4p1.orig/gss-serv.c openssh-6.4p1/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. * -@@ -477,6 +553,7 @@ +@@ -505,6 +589,7 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -893,18 +909,18 @@ 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 @@ +@@ -534,6 +619,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); @@ -912,24 +928,10 @@ 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 @@ - return ok; - } - -+/* 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-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 -@@ -0,0 +1,238 @@ +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 2019-08-07 23:54:19.624546756 +0200 +@@ -0,0 +1,329 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * @@ -969,6 +971,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/gss-serv-gsi.c +#include "hostfile.h" +#include "auth.h" +#include "log.h" ++#include "misc.h" +#include "servconf.h" + +#include "buffer.h" @@ -981,8 +984,11 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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); ++ 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==", @@ -995,6 +1001,17 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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 @@ -1010,10 +1027,10 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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 + @@ -1039,10 +1056,10 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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; +} + @@ -1059,7 +1076,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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 + @@ -1085,7 +1102,7 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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; +} @@ -1100,9 +1117,9 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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, @@ -1111,47 +1128,113 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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); +} @@ -1166,16 +1249,26 @@ diff -Nur openssh-6.4p1.orig/gss-serv-gsi.c openssh-6.4p1/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-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 -@@ -263,6 +263,34 @@ +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 2019-08-07 23:53:43.289924830 +0200 ++++ openssh-7.4p1/gss-serv-krb5.c 2019-08-07 23:54:19.624546756 +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 @@ -1186,10 +1279,10 @@ diff -Nur openssh-6.4p1.orig/gss-serv-krb5.c openssh-6.4p1/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", -+ krb5_get_err_text(krb_context,retval)); ++ 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; + } + @@ -1206,7 +1299,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 @@ +@@ -482,7 +510,7 @@ return; } @@ -1215,7 +1308,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 @@ +@@ -553,7 +581,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1224,18 +1317,18 @@ 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 -@@ -44,6 +44,7 @@ - #include "monitor_wrap.h" - #include "servconf.h" +diff -Nur openssh-7.4p1.orig/kexgsss.c openssh-7.4p1/kexgsss.c +--- openssh-7.4p1.orig/kexgsss.c 2019-08-07 23:53:43.255925184 +0200 ++++ openssh-7.4p1/kexgsss.c 2019-08-07 23:54:19.624546756 +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 +@@ -95,8 +96,10 @@ debug2("%s: Acquiring credentials", __func__); @@ -1245,9 +1338,9 @@ diff -Nur openssh-6.4p1.orig/kexgsss.c openssh-6.4p1/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 @@ +@@ -183,12 +186,13 @@ } while (maj_status & GSS_S_CONTINUE_NEEDED); if (GSS_ERROR(maj_status)) { @@ -1262,17 +1355,17 @@ diff -Nur openssh-6.4p1.orig/kexgsss.c openssh-6.4p1/kexgsss.c } if (!(ret_flags & GSS_C_MUTUAL_FLAG)) -@@ -285,4 +289,23 @@ - if (options.gss_store_rekey) +@@ -294,4 +298,23 @@ ssh_gssapi_rekey_creds(); + 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); @@ -1286,46 +1379,21 @@ 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 -@@ -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-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 @@ - 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\ +diff -Nur openssh-7.4p1.orig/Makefile.in openssh-7.4p1/Makefile.in +--- openssh-7.4p1.orig/Makefile.in 2019-08-07 23:53:43.380923883 +0200 ++++ openssh-7.4p1/Makefile.in 2019-08-07 23:54:19.625546745 +0200 +@@ -114,6 +114,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 \ - 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 @@ +diff -Nur openssh-7.4p1.orig/misc.c openssh-7.4p1/misc.c +--- openssh-7.4p1.orig/misc.c 2019-08-07 23:53:43.203925725 +0200 ++++ openssh-7.4p1/misc.c 2019-08-07 23:54:19.625546745 +0200 +@@ -161,11 +161,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1341,7 +1409,7 @@ diff -Nur openssh-6.4p1.orig/misc.c openssh-6.4p1/misc.c int wspace = 0; if (*s == NULL) -@@ -170,6 +173,21 @@ +@@ -173,6 +176,21 @@ old = *s; @@ -1363,7 +1431,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 @@ +@@ -228,6 +246,20 @@ return copy; } @@ -1384,10 +1452,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-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 2019-08-07 23:54:19.626546735 +0200 +@@ -69,6 +69,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1395,10 +1463,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-7.4p1.orig/monitor.c openssh-7.4p1/monitor.c +--- openssh-7.4p1.orig/monitor.c 2019-08-07 23:53:43.387923810 +0200 ++++ openssh-7.4p1/monitor.c 2019-08-07 23:54:19.626546735 +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 *); @@ -1408,35 +1476,38 @@ 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 @@ - struct mon_table mon_dispatch_proto20[] = { +@@ -213,7 +216,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}, -@@ -244,7 +247,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}, -@@ -274,6 +277,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}, +@@ -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_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}, + {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} + }; +@@ -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}, @@ -1444,35 +1515,26 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/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}, -@@ -327,7 +335,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}, -@@ -417,6 +425,8 @@ + #ifdef WITH_OPENSSL +@@ -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; -@@ -535,6 +545,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; -@@ -805,14 +817,17 @@ + + if (!no_pty_flag) { +@@ -759,14 +771,17 @@ debug3("%s", __func__); @@ -1493,24 +1555,24 @@ 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 @@ +@@ -1951,12 +1966,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); -@@ -2319,12 +2337,77 @@ +@@ -1964,7 +1982,10 @@ debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -1520,7 +1582,9 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/monitor.c + else + auth_method = "gssapi-with-mic"; - /* Monitor loop will terminate if authenticated */ + if (authenticated) + authctxt->last_details = ssh_gssapi_get_displayname(); +@@ -1973,6 +1994,68 @@ return (authenticated); } @@ -1555,7 +1619,7 @@ diff -Nur openssh-6.4p1.orig/monitor.c openssh-6.4p1/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); @@ -1589,26 +1653,26 @@ 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-7.4p1.orig/monitor.h openssh-7.4p1/monitor.h +--- openssh-7.4p1.orig/monitor.h 2019-08-07 23:53:43.369923998 +0200 ++++ openssh-7.4p1/monitor.h 2019-08-07 23:54:19.627546725 +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, -- 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 -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 @@ + struct monitor { +diff -Nur openssh-7.4p1.orig/monitor_wrap.c openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1.orig/monitor_wrap.c 2019-08-07 23:53:43.388923800 +0200 ++++ openssh-7.4p1/monitor_wrap.c 2019-08-07 23:54:19.627546725 +0200 +@@ -977,12 +977,13 @@ } int @@ -1623,7 +1687,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 @@ +@@ -995,6 +996,83 @@ return (authenticated); } @@ -1664,10 +1728,10 @@ diff -Nur openssh-6.4p1.orig/monitor_wrap.c openssh-6.4p1/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); @@ -1676,7 +1740,7 @@ diff -Nur openssh-6.4p1.orig/monitor_wrap.c openssh-6.4p1/monitor_wrap.c + } + + buffer_free(&m); -+ ++ + return(major); +} + @@ -1690,15 +1754,15 @@ diff -Nur openssh-6.4p1.orig/monitor_wrap.c openssh-6.4p1/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); @@ -1707,10 +1771,10 @@ 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 -@@ -62,9 +62,13 @@ +diff -Nur openssh-7.4p1.orig/monitor_wrap.h openssh-7.4p1/monitor_wrap.h +--- openssh-7.4p1.orig/monitor_wrap.h 2019-08-07 23:53:43.375923935 +0200 ++++ openssh-7.4p1/monitor_wrap.h 2019-08-07 23:54:19.627546725 +0200 +@@ -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 *); @@ -1720,15 +1784,15 @@ diff -Nur openssh-6.4p1.orig/monitor_wrap.h openssh-6.4p1/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-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-7.4p1.orig/readconf.c openssh-7.4p1/readconf.c +--- openssh-7.4p1.orig/readconf.c 2019-08-07 23:53:43.397923706 +0200 ++++ openssh-7.4p1/readconf.c 2019-08-07 23:54:19.628546714 +0200 +@@ -1974,11 +1974,11 @@ if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) @@ -1741,15 +1805,12 @@ diff -Nur openssh-6.4p1.orig/readconf.c openssh-6.4p1/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; - 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-7.4p1.orig/readconf.h openssh-7.4p1/readconf.h +--- openssh-7.4p1.orig/readconf.h 2019-08-07 23:53:43.333924372 +0200 ++++ openssh-7.4p1/readconf.h 2019-08-07 23:54:19.628546714 +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. */ @@ -1758,10 +1819,10 @@ 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 -@@ -71,6 +71,7 @@ +diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c +--- openssh-7.4p1.orig/servconf.c 2019-08-07 23:53:43.398923696 +0200 ++++ openssh-7.4p1/servconf.c 2019-08-07 23:54:19.629546704 +0200 +@@ -75,6 +75,7 @@ /* Portable-specific options */ options->use_pam = -1; @@ -1769,7 +1830,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -107,9 +108,11 @@ +@@ -115,9 +116,11 @@ options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -1779,18 +1840,9 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/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; -@@ -151,6 +154,8 @@ - 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; - options->trusted_user_ca_keys = NULL; - options->authorized_principals_file = NULL; -@@ -166,6 +171,8 @@ +@@ -210,6 +213,8 @@ /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -1798,8 +1850,8 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c + options->permit_pam_user_change = 0; /* Standard Options */ - if (options->protocol == SSH_PROTO_UNKNOWN) -@@ -244,13 +251,17 @@ + if (options->num_host_key_files == 0) { +@@ -283,13 +288,17 @@ if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) @@ -1818,33 +1870,27 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c + options->gsi_allow_limited_proxy = 0; if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; - if (options->password_authentication == -1) -@@ -333,7 +344,7 @@ + #ifdef GSSAPI +@@ -417,7 +426,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ - sUsePAM, + sUsePAM, sPermitPAMUserChange, /* Standard Options */ - sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, + sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, -@@ -354,11 +365,15 @@ - sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, +@@ -439,6 +448,9 @@ + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sHostKeyAlgorithms, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssDelegateCreds, + sGssCredsPath, + sGsiAllowLimitedProxy, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, - sGssKeyEx, sGssStoreRekey, - sAcceptEnv, sPermitTunnel, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, + sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, -+ sDisUsageStats, sUsageStatsTarg, - sZeroKnowledgePasswordAuthentication, sHostCertificate, - sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, - sKexAlgorithms, sIPQoS, sVersionAddendum, -@@ -380,8 +395,10 @@ +@@ -468,8 +480,10 @@ /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, @@ -1855,13 +1901,12 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -424,15 +441,25 @@ +@@ -515,7 +529,14 @@ { "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 }, @@ -1871,26 +1916,27 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, +@@ -523,7 +544,10 @@ + { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, #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 }, -@@ -497,6 +524,8 @@ +@@ -592,6 +616,8 @@ { "permitopen", sPermitOpen, 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 }, -@@ -889,6 +918,10 @@ +@@ -1056,6 +1082,10 @@ intptr = &options->use_pam; goto parse_flag; @@ -1901,7 +1947,7 @@ diff -Nur openssh-6.4p1.orig/servconf.c openssh-6.4p1/servconf.c /* Standard Options */ case sBadOption: return -1; -@@ -1104,6 +1137,10 @@ +@@ -1262,6 +1292,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1912,7 +1958,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 @@ +@@ -1270,6 +1304,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -1923,9 +1969,9 @@ 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 @@ - intptr = &options->gss_store_rekey; - goto parse_flag; +@@ -1290,6 +1328,12 @@ + options->gss_kex_algorithms = strdup(arg); + break; +#ifdef GSI + case sGsiAllowLimitedProxy: @@ -1936,37 +1982,18 @@ 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 @@ - *charptr = xstrdup(arg); - break; +@@ -2061,6 +2105,7 @@ -+ case sDisUsageStats: -+ intptr = &options->disable_usage_stats; -+ goto parse_flag; -+ -+ 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; -@@ -1801,6 +1860,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 @@ + M_CP_INTOPT(hostbased_authentication); +diff -Nur openssh-7.4p1.orig/servconf.h openssh-7.4p1/servconf.h +--- openssh-7.4p1.orig/servconf.h 2019-08-07 23:53:43.315924560 +0200 ++++ openssh-7.4p1/servconf.h 2019-08-07 23:54:19.629546704 +0200 +@@ -118,9 +118,12 @@ * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -1976,10 +2003,10 @@ diff -Nur openssh-6.4p1.orig/servconf.h openssh-6.4p1/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 -@@ -169,6 +172,7 @@ + char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ +@@ -177,6 +180,7 @@ char *adm_forced_command; int use_pam; /* Enable auth via PAM */ @@ -1987,21 +2014,10 @@ diff -Nur openssh-6.4p1.orig/servconf.h openssh-6.4p1/servconf.h int permit_tun; -@@ -176,6 +180,10 @@ - - int use_kuserok; - char *chroot_directory; -+ -+ int disable_usage_stats; -+ char *usage_stats_targets; -+ - 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-7.4p1.orig/ssh.1 openssh-7.4p1/ssh.1 +--- openssh-7.4p1.orig/ssh.1 2019-08-07 23:53:43.310924612 +0200 ++++ openssh-7.4p1/ssh.1 2019-08-07 23:54:19.629546704 +0200 +@@ -1436,6 +1436,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2020,10 +2036,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-7.4p1.orig/ssh.c openssh-7.4p1/ssh.c +--- openssh-7.4p1.orig/ssh.c 2019-08-07 23:53:43.382923862 +0200 ++++ openssh-7.4p1/ssh.c 2019-08-07 23:54:19.630546693 +0200 +@@ -472,6 +472,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2039,24 +2055,30 @@ 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, host_arg, ++ &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | ++ (post_canon ? SSHCONF_POSTCANON : 0)); +#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, host_arg, ++ &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | ++ (post_canon ? SSHCONF_POSTCANON : 0)); +#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, host_arg, ++ &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | ++ (post_canon ? SSHCONF_POSTCANON : 0)); +#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 @@ +@@ -1191,8 +1223,12 @@ logit("FIPS mode initialized"); } @@ -2068,29 +2090,27 @@ 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 -@@ -24,10 +24,10 @@ + 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 2019-08-07 23:53:43.260925132 +0200 ++++ openssh-7.4p1/ssh_config 2019-08-07 23:54:19.630546693 +0200 +@@ -24,9 +24,9 @@ # RSAAuthentication yes # 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-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-7.4p1.orig/ssh_config.5 openssh-7.4p1/ssh_config.5 +--- openssh-7.4p1.orig/ssh_config.5 2019-08-07 23:53:43.333924372 +0200 ++++ openssh-7.4p1/ssh_config.5 2019-08-07 23:54:19.631546683 +0200 @@ -55,6 +55,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2104,10 +2124,51 @@ 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 @@ +@@ -748,7 +754,7 @@ + .It Cm GSSAPIAuthentication + Specifies whether user authentication based on GSSAPI is allowed. + The default is +-.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 GSSAPIRenewalForcesRekey + If set to + .Dq yes +@@ -794,7 +800,6 @@ + .Pp + The default is + .Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- . +-This option only applies to protocol version 2 connections using GSSAPI. + .It Cm HashKnownHosts + Indicates that + .Xr ssh 1 +@@ -1215,7 +1220,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.4p1.orig/sshconnect2.c openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1.orig/sshconnect2.c 2019-08-07 23:53:43.394923738 +0200 ++++ openssh-7.4p1/sshconnect2.c 2019-08-08 09:41:04.634608855 +0200 +@@ -727,6 +727,11 @@ int ok = 0; const char *gss_host = NULL; @@ -2119,59 +2180,65 @@ 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 @@ - free(lang); +@@ -816,7 +821,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 { +@@ -964,6 +970,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 && \ -+ (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) { -@@ -950,8 +964,16 @@ +@@ -981,6 +1001,11 @@ return (0); } +#ifdef GSI -+ if (options.implicit && is_gsi_oid(gss_kex_context->oid)) { ++ if (options.implicit && is_gsi_oid(gss_kex_context->oid)) + ssh_gssapi_buildmic(&b, "", authctxt->service, "gssapi-keyex"); -+ } else { ++ else +#endif ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, "gssapi-keyex"); -+#ifdef GSI -+ } -+#endif - gssbuf.value = buffer_ptr(&b); - gssbuf.length = buffer_len(&b); -@@ -962,7 +984,15 @@ +@@ -993,6 +1018,11 @@ } 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-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-7.4p1.orig/sshd.8 openssh-7.4p1/sshd.8 +--- openssh-7.4p1.orig/sshd.8 2019-08-07 23:53:43.324924466 +0200 ++++ openssh-7.4p1/sshd.8 2019-08-07 23:54:19.631546683 +0200 +@@ -740,6 +740,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed @@ -2179,21 +2246,6 @@ diff -Nur openssh-6.4p1.orig/sshd.8 openssh-6.4p1/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 @@ -2216,32 +2268,10 @@ 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 -@@ -124,6 +124,7 @@ - #include "audit.h" - #include "ssh-sandbox.h" - #include "version.h" -+#include "ssh-globus-usage.h" - - #ifdef USE_SECURITY_SESSION_API - #include -@@ -1681,6 +1682,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; -@@ -2266,7 +2274,7 @@ +diff -Nur openssh-7.4p1.orig/sshd.c openssh-7.4p1/sshd.c +--- openssh-7.4p1.orig/sshd.c 2019-08-07 23:53:43.391923769 +0200 ++++ openssh-7.4p1/sshd.c 2019-08-07 23:54:19.632546673 +0200 +@@ -2218,7 +2218,7 @@ #endif #ifdef GSSAPI @@ -2250,27 +2280,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,11 @@ +diff -Nur openssh-7.4p1.orig/sshd_config openssh-7.4p1/sshd_config +--- openssh-7.4p1.orig/sshd_config 2019-08-07 23:53:43.353924164 +0200 ++++ openssh-7.4p1/sshd_config 2019-08-07 23:54:19.632546673 +0200 +@@ -76,10 +76,11 @@ #KerberosUseKuserok yes # GSSAPI options --#GSSAPIAuthentication no -GSSAPIAuthentication yes +#GSSAPIAuthentication yes +#GSSAPIDelegateCredentials yes - #GSSAPICleanupCredentials yes --GSSAPICleanupCredentials yes + GSSAPICleanupCredentials no #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 -@@ -110,6 +109,10 @@ - #UsePAM no + # Set this to 'yes' to enable PAM authentication, account processing, +@@ -95,6 +96,10 @@ + # problems. UsePAM yes +# Set to 'yes' to allow the PAM stack to change the user name during @@ -2280,664 +2308,92 @@ 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 - # AllowTcpForwarding 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 @@ - 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 -+.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 , -@@ -484,6 +493,10 @@ +diff -Nur openssh-7.4p1.orig/sshd_config.5 openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1.orig/sshd_config.5 2019-08-07 23:53:43.353924164 +0200 ++++ openssh-7.4p1/sshd_config.5 2019-08-07 23:54:19.633546662 +0200 +@@ -644,20 +644,39 @@ + to allow the client to select the address to which the forwarding is bound. 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. + .Cm no . ++.It Cm GSIAllowLimitedProxy ++Specifies whether to accept limited proxy credentials for authentication. +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. -@@ -496,6 +509,22 @@ ++.Cm no . + .It Cm GSSAPIAuthentication + Specifies whether user authentication based on GSSAPI is allowed. The default is - .Dq yes . - Note that this option applies to protocol version 2 only. +-.Cm no . ++.Cm yes . + .It Cm GSSAPICleanupCredentials + Specifies whether to automatically destroy the user's credentials cache + on logout. + The default is + .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 +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 . - .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. If -@@ -1160,6 +1189,121 @@ ++.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 . ++.Dq yes . + .It Cm GSSAPIEnablek5users + Specifies whether to look at .k5users file for GSSAPI authentication + access control. Further details are described in +@@ -694,7 +713,6 @@ .Pp - To disable TCP keepalive messages, the value should be set to - .Dq no . -+.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 -+.Dq default -+is specified, the tags -+.Dq 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 -+and -+.Dq 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 -+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 -+.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. -+.Pp - .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 @@ + The default is + .Dq gss-gex-sha1-,gss-group1-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. +@@ -1548,6 +1566,12 @@ as a non-root user. The default is - .Dq no . + .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 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 -@@ -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) -+ return GLOBUS_SUCCESS; -+ -+ result = globus_module_activate(GLOBUS_USAGE_MODULE); -+ if (result != GLOBUS_SUCCESS) -+ { -+ error("ERROR: couldn't activate USAGE STATS module"); -+ return result; -+ } -+ -+ if (!usage_stats_targets || -+ !strcasecmp(usage_stats_targets, "default")) -+ target_str = strdup(CILOGON_COLLECTOR); -+ else -+ 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(char *ssh_release, const char *ssl_release, -+ char *method, char *mechanism, const char *clientip, -+ char *username, 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 = 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 = method; -+ break; -+ -+ case SSH_GLOBUS_USAGE_MECHANISM: -+ key = "MECH"; -+ value = mechanism?:""; -+ break; -+ -+ case SSH_GLOBUS_USAGE_CLIENTIP: -+ key = "CLIENTIP"; -+ value = (char *) clientip?:""; -+ break; -+ -+ case SSH_GLOBUS_USAGE_USERNAME: -+ key = "USER"; -+ value = username?:""; -+ break; -+ -+ case SSH_GLOBUS_USAGE_USERDN: -+ key = "USERDN"; -+ value = 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(char *ssh_release, const char *ssl_release, -+ char *method, char *mechanism, const char *client_ip, -+ char *username, 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-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 -@@ -0,0 +1,46 @@ -+/* -+ * 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" -+ -+#define CILOGON_COLLECTOR "usage-stats.cilogon.org:4810" -+ -+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(char *ssh_release, const char *ssl_release, -+ char *method, char *mechanism, const char *client_ip, -+ 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 -@@ -91,6 +91,7 @@ - gss_name_t name; +diff -Nur openssh-7.4p1.orig/ssh-gss.h openssh-7.4p1/ssh-gss.h +--- openssh-7.4p1.orig/ssh-gss.h 2019-08-07 23:53:43.311924601 +0200 ++++ openssh-7.4p1/ssh-gss.h 2019-08-07 23:54:19.633546662 +0200 +@@ -90,12 +90,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; -@@ -111,7 +112,7 @@ +@@ -116,7 +118,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -2946,7 +2402,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 @@ +@@ -149,6 +151,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2956,28 +2412,21 @@ 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 @@ +@@ -159,7 +164,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 *); - void ssh_gssapi_cleanup_creds(void); -@@ -162,6 +166,7 @@ - int ssh_gssapi_oid_table_ok(); +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 2019-08-08 09:45:04.022089731 +0200 +@@ -2,5 +2,19 @@ - int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); -+void ssh_gssapi_get_client_info(char **userdn, char **mech); - #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 -@@ -1,6 +1,21 @@ - /* $OpenBSD: version.h,v 1.68 2013/11/08 01:38:11 djm Exp $ */ + #define SSH_VERSION "OpenSSH_7.4" +#ifdef GSI +#define GSI_VERSION " GSI" @@ -2991,11 +2440,8 @@ diff -Nur openssh-6.4p1.orig/version.h openssh-6.4p1/version.h +#define KRB5_VERSION "" +#endif + -+#define NCSA_VERSION " GSI_GSSAPI_20131109" -+ - #define SSH_VERSION "OpenSSH_6.4" - #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 "c-GSI" ++#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ ++ GSI_VERSION KRB5_VERSION diff --git a/openssh-7.4p1-gss-strict-acceptor.patch b/openssh-7.4p1-gss-strict-acceptor.patch new file mode 100644 index 0000000..878ce1a --- /dev/null +++ b/openssh-7.4p1-gss-strict-acceptor.patch @@ -0,0 +1,28 @@ +From 13bd2e2d622d01dc85d22b94520a5b243d006049 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Fri, 6 Jan 2017 03:45:41 +0000 +Subject: [PATCH] upstream commit + +sshd_config is documented to set +GSSAPIStrictAcceptorCheck=yes by default, so actually make it do this. +bz#2637 ok dtucker + +Upstream-ID: 99ef8ac51f17f0f7aec166cb2e34228d4d72a665 +--- + servconf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/servconf.c b/servconf.c +index 795ddbab7..c9105a592 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -270,7 +270,7 @@ fill_default_server_options(ServerOptions *options) + 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) + diff --git a/openssh-7.4p1-gssKexAlgorithms.patch b/openssh-7.4p1-gssKexAlgorithms.patch new file mode 100644 index 0000000..c83636e --- /dev/null +++ b/openssh-7.4p1-gssKexAlgorithms.patch @@ -0,0 +1,410 @@ +diff -up openssh-7.4p1/gss-genr.c.gsskexalg openssh-7.4p1/gss-genr.c +--- openssh-7.4p1/gss-genr.c.gsskexalg 2017-02-09 10:46:50.417893132 +0100 ++++ openssh-7.4p1/gss-genr.c 2017-02-09 10:46:50.448893107 +0100 +@@ -77,7 +77,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; + +@@ -85,12 +86,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; +@@ -99,6 +100,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++) +@@ -112,6 +114,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + buffer_init(&buf); + + oidpos = 0; ++ s = cp = strdup(kex); + for (i = 0; i < gss_supported->count; i++) { + if (gss_supported->elements[i].length < 128 && + (*check)(NULL, &(gss_supported->elements[i]), host, client)) { +@@ -130,26 +133,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.4p1/gss-serv.c.gsskexalg openssh-7.4p1/gss-serv.c +--- openssh-7.4p1/gss-serv.c.gsskexalg 2017-02-09 10:46:50.449893106 +0100 ++++ openssh-7.4p1/gss-serv.c 2017-02-09 10:55:12.189422901 +0100 +@@ -149,7 +149,7 @@ 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.4p1/kex.c.gsskexalg openssh-7.4p1/kex.c +--- openssh-7.4p1/kex.c.gsskexalg 2017-02-09 10:46:50.449893106 +0100 ++++ openssh-7.4p1/kex.c 2017-02-09 10:55:44.008393539 +0100 +@@ -248,6 +248,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 = strdup(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.4p1/kex.h.gsskexalg openssh-7.4p1/kex.h +--- openssh-7.4p1/kex.h.gsskexalg 2017-02-09 10:46:50.452893104 +0100 ++++ openssh-7.4p1/kex.h 2017-02-09 11:02:35.313012903 +0100 +@@ -179,6 +179,7 @@ struct kex { + 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.4p1/readconf.c.gsskexalg openssh-7.4p1/readconf.c +--- openssh-7.4p1/readconf.c.gsskexalg 2017-02-09 10:46:50.420893129 +0100 ++++ openssh-7.4p1/readconf.c 2017-02-09 10:56:06.759372540 +0100 +@@ -64,6 +64,7 @@ + #include "uidswap.h" + #include "myproposal.h" + #include "digest.h" ++#include "ssh-gss.h" + + /* Format of the configuration file: + +@@ -161,7 +162,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, +@@ -213,6 +214,7 @@ static struct { + { "gssapiclientidentity", oGssClientIdentity }, + { "gssapiserveridentity", oGssServerIdentity }, + { "gssapirenewalforcesrekey", oGssRenewalRekey }, ++ { "gssapikexalgorithms", oGssKexAlgorithms }, + #else + { "gssapiauthentication", oUnsupported }, + { "gssapikeyexchange", oUnsupported }, +@@ -220,6 +222,7 @@ static struct { + { "gssapitrustdns", oUnsupported }, + { "gssapiclientidentity", oUnsupported }, + { "gssapirenewalforcesrekey", oUnsupported }, ++ { "gssapikexalgorithms", oUnsupported }, + #endif + { "fallbacktorsh", oDeprecated }, + { "usersh", oDeprecated }, +@@ -996,6 +999,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 = strdup(arg); ++ break; ++ + case oBatchMode: + intptr = &options->batch_mode; + goto parse_flag; +@@ -1813,6 +1828,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; +@@ -1964,6 +1980,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) +diff -up openssh-7.4p1/readconf.h.gsskexalg openssh-7.4p1/readconf.h +--- openssh-7.4p1/readconf.h.gsskexalg 2017-02-09 10:46:50.420893129 +0100 ++++ openssh-7.4p1/readconf.h 2017-02-09 10:46:50.450893106 +0100 +@@ -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.4p1/servconf.c.gsskexalg openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.gsskexalg 2017-02-09 10:46:50.446893109 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-09 10:57:15.784309297 +0100 +@@ -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); +@@ -117,6 +117,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; +@@ -280,6 +281,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->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) +@@ -422,7 +425,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, +@@ -501,6 +504,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 }, +@@ -508,6 +512,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 }, +@@ -1249,6 +1254,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 = strdup(arg); ++ break; ++ + case sPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; +@@ -2304,6 +2321,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.4p1/servconf.h.gsskexalg openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.gsskexalg 2017-02-09 10:46:50.450893106 +0100 ++++ openssh-7.4p1/servconf.h 2017-02-09 10:57:33.717292870 +0100 +@@ -116,6 +116,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.4p1/ssh.1.gsskexalg openssh-7.4p1/ssh.1 +--- openssh-7.4p1/ssh.1.gsskexalg 2017-02-09 10:46:50.443893111 +0100 ++++ openssh-7.4p1/ssh.1 2017-02-09 10:46:50.451893105 +0100 +@@ -517,6 +517,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.4p1/ssh_config.5.gsskexalg openssh-7.4p1/ssh_config.5 +--- openssh-7.4p1/ssh_config.5.gsskexalg 2017-02-09 10:46:50.452893104 +0100 ++++ openssh-7.4p1/ssh_config.5 2017-02-09 11:00:39.053122745 +0100 +@@ -782,6 +782,18 @@ the name of the host being connected 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-group1-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.4p1/sshconnect2.c.gsskexalg openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1/sshconnect2.c.gsskexalg 2017-02-09 10:46:50.451893105 +0100 ++++ openssh-7.4p1/sshconnect2.c 2017-02-09 10:58:08.533260973 +0100 +@@ -181,7 +181,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, +diff -up openssh-7.4p1/sshd_config.5.gsskexalg openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.gsskexalg 2017-02-09 10:46:50.452893104 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-02-09 11:01:55.141050861 +0100 +@@ -666,6 +666,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-group1-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.4p1/ssh-gss.h.gsskexalg openssh-7.4p1/ssh-gss.h +--- openssh-7.4p1/ssh-gss.h.gsskexalg 2017-02-09 10:46:50.425893125 +0100 ++++ openssh-7.4p1/ssh-gss.h 2017-02-09 10:46:50.451893105 +0100 +@@ -76,6 +76,11 @@ 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_GRP1_SHA1_ID "," \ ++ KEX_GSS_GRP14_SHA1_ID ++ + typedef struct { + char *filename; + char *envvar; +@@ -147,9 +152,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-6.3p1-gsskex.patch b/openssh-7.4p1-gsskex.patch similarity index 66% rename from openssh-6.3p1-gsskex.patch rename to openssh-7.4p1-gsskex.patch index eefd792..0ab2e04 100644 --- a/openssh-6.3p1-gsskex.patch +++ b/openssh-7.4p1-gsskex.patch @@ -1,146 +1,36 @@ -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 - 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 +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; + #ifdef GSSAPI ++extern Authmethod method_gsskeyex; + extern Authmethod method_gssapi; + #endif -@@ -93,7 +94,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ - 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 \ -+ 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 - static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); - static void input_gssapi_errtok(int, u_int32_t, void *); +@@ -77,6 +78,7 @@ Authmethod *authmethods[] = { + &method_none, + &method_pubkey, + #ifdef GSSAPI ++ &method_gsskeyex, + &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 +@@ -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. @@ -179,7 +69,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, +@@ -238,7 +273,8 @@ input_gssapi_exchange_complete(int type, packet_check_eom(); @@ -189,7 +79,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 +@@ -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)))) @@ -199,8 +89,8 @@ 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 - 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 = { @@ -212,31 +102,12 @@ 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 -@@ -69,6 +69,7 @@ extern Authmethod method_passwd; - extern Authmethod method_kbdint; - extern Authmethod method_hostbased; - #ifdef GSSAPI -+extern Authmethod method_gsskeyex; - extern Authmethod method_gssapi; - #endif - #ifdef JPAKE -@@ -79,6 +80,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 -@@ -111,6 +111,10 @@ - #include "msg.h" - #include "roaming.h" +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" +#ifdef GSSAPI +#include "ssh-gss.h" @@ -245,26 +116,30 @@ 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 +@@ -1664,9 +1668,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)) { ++ ssh_gssapi_credentials_updated(NULL)) { + debug("credentials updated - forcing rekey"); + need_rekeying = 1; + } +#endif ++ } + - 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(" + /* 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(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -293,12 +168,12 @@ diff -up openssh-6.3p1/configure.ac.gsskex openssh-6.3p1/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-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 -@@ -39,12 +39,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" @@ -466,7 +341,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 +@@ -198,7 +353,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -475,7 +350,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 +@@ -228,8 +383,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } OM_uint32 @@ -518,7 +393,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 +@@ -237,6 +426,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -538,7 +413,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 +@@ -250,11 +452,16 @@ ssh_gssapi_buildmic(Buffer *b, const cha } int @@ -556,7 +431,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 +@@ -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); @@ -567,7 +442,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 +@@ -273,10 +484,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } @@ -587,7 +462,6 @@ diff -up openssh-6.3p1/gss-genr.c.gsskex openssh-6.3p1/gss-genr.c + 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); + @@ -636,155 +510,25 @@ 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 - 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) { -@@ -174,11 +174,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); -+#endif - - #ifdef USE_PAM - if (options.use_pam) -@@ -187,9 +202,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", -@@ -197,7 +279,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-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 -@@ -45,15 +45,20 @@ - #include "channels.h" +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" -+#include "servconf.h" + #include "servconf.h" +#include "uidswap.h" #include "ssh-gss.h" +#include "monitor_wrap.h" -+ -+extern ServerOptions options; + + 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, 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}; @@ -792,64 +536,16 @@ 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) - char lname[MAXHOSTNAMELEN]; - 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)) { -+ 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); -+ } -+ -+ 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; - } -- -- 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 */ -@@ -114,6 +126,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 */ @@ -869,7 +565,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 +@@ -151,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -880,7 +576,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 +@@ -277,8 +304,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -902,11 +598,11 @@ diff -up openssh-6.3p1/gss-serv.c.gsskex openssh-6.3p1/gss-serv.c + 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); @@ -930,7 +626,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 +@@ -293,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g if (client->mech == NULL) return GSS_S_FAILURE; @@ -944,7 +640,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 +@@ -310,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g return (ctx->major); } @@ -953,7 +649,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 +@@ -320,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g void ssh_gssapi_cleanup_creds(void) { @@ -979,7 +675,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 +@@ -357,7 +442,7 @@ ssh_gssapi_do_child(char ***envp, u_int /* Privileged */ int @@ -988,7 +684,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) +@@ -367,9 +452,11 @@ ssh_gssapi_userok(char *user) return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) @@ -1002,7 +698,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) +@@ -383,14 +470,90 @@ ssh_gssapi_userok(char *user) return (0); } @@ -1099,12 +795,142 @@ 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 -@@ -51,6 +51,10 @@ - #include "roaming.h" - #include "audit.h" +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; + OM_uint32 maj_status, min_status; +- int len; ++ const char *new_ccname, *new_cctype; + const char *errmsg; + + if (client->creds == NULL) { +@@ -181,11 +181,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); ++#endif + + #ifdef USE_PAM + if (options.use_pam) +@@ -194,9 +209,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", +@@ -204,7 +286,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-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" +#ifdef GSSAPI +#include "ssh-gss.h" @@ -1113,19 +939,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 }, - #endif +@@ -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, 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) +@@ -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; @@ -1138,48 +964,10 @@ 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, - KEX_DH_GEX_SHA256, - KEX_ECDH_SHA2, -+ KEX_GSS_GRP1_SHA1, -+ KEX_GSS_GRP14_SHA1, -+ KEX_GSS_GEX_SHA1, - KEX_MAX - }; - -@@ -133,6 +136,12 @@ struct Kex { - int flags; - const EVP_MD *evp_md; - 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)(Key *); -@@ -162,6 +171,11 @@ void kexgex_server(Kex *); - void kexecdh_client(Kex *); - void kexecdh_server(Kex *); - -+#ifdef GSSAPI -+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 -@@ -0,0 +1,334 @@ +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. + * @@ -1224,22 +1012,23 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c +#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; @@ -1247,21 +1036,23 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + 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; @@ -1270,7 +1061,7 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + 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); @@ -1295,11 +1086,11 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + 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(); @@ -1312,7 +1103,7 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + 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)) { @@ -1445,38 +1236,39 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + 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->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, + dh->pub_key, /* e */ + dh_server_pub, /* f */ + shared_secret, /* K */ -+ &hash, &hashlen ++ hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: + kexgex_hash( -+ kex->evp_md, -+ 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; @@ -1494,13 +1286,13 @@ diff -up openssh-6.3p1/kexgssc.c.gsskex openssh-6.3p1/kexgssc.c + 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) @@ -1508,16 +1300,16 @@ 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(ssh, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); -+ kex_finish(kex); ++ return kex_send_newkeys(ssh); +} + +#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 -@@ -0,0 +1,288 @@ +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. + * @@ -1562,12 +1354,15 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c +#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; + @@ -1582,15 +1377,18 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + 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; ++ 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; + + /* Initialise GSSAPI */ + @@ -1602,8 +1400,8 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + 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"); + @@ -1612,7 +1410,7 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + 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; @@ -1622,11 +1420,12 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/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", @@ -1643,10 +1442,10 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + 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"); @@ -1729,43 +1528,44 @@ diff -up openssh-6.3p1/kexgsss.c.gsskex openssh-6.3p1/kexgsss.c + 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), ++ 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), + 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->evp_md, -+ 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, ++ cmin, nbits, cmax, + 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; @@ -1796,42 +1596,80 @@ 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(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 -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", - KEY_DSA_CERT_V00, 0, 1 }, -+ { "null", "null", KEY_NULL, 0, 0 }, - { NULL, NULL, -1, -1, 0 } +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, ++#ifdef GSSAPI ++ KEX_GSS_GRP1_SHA1, ++ KEX_GSS_GRP14_SHA1, ++ KEX_GSS_GEX_SHA1, ++#endif + KEX_MAX }; -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, - 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 +@@ -147,6 +152,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; +@@ -196,6 +207,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-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 \ ++ 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 \ + 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-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 *); @@ -1840,15 +1678,13 @@ 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}, +@@ -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 - #ifdef JPAKE - {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, -@@ -283,6 +286,12 @@ struct mon_table mon_dispatch_proto20[] + {0, 0, NULL} }; struct mon_table mon_dispatch_postauth20[] = { @@ -1858,35 +1694,35 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c + {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}, -@@ -405,6 +414,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); + #endif +@@ -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; -@@ -519,6 +532,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); -@@ -1968,6 +1985,13 @@ mm_get_kex(Buffer *m) - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - kex->kex[KEX_ECDH_SHA2] = kexecdh_server; + + 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; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; @@ -1894,30 +1730,28 @@ diff -up openssh-6.3p1/monitor.c.gsskex openssh-6.3p1/monitor.c + 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); -@@ -2192,6 +2216,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer + 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 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__); -@@ -2219,6 +2246,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); -@@ -2236,6 +2266,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); @@ -1925,30 +1759,30 @@ 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 +@@ -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); -@@ -2273,7 +2307,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); -@@ -2286,6 +2324,74 @@ 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); } @@ -2022,11 +1856,10 @@ 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 -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, #endif @@ -2035,10 +1868,10 @@ 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 -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 @@ -2047,7 +1880,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) +@@ -960,5 +960,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -2085,24 +1918,23 @@ 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 -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 *); @@ -2114,10 +1946,10 @@ 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 -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, @@ -2126,7 +1958,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 { +@@ -205,10 +207,19 @@ static struct { { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2146,7 +1978,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: +@@ -961,10 +972,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2177,7 +2009,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) +@@ -1776,7 +1807,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2190,7 +2022,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) +@@ -1920,8 +1956,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2205,10 +2037,10 @@ 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 -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. */ int gss_authentication; /* Try GSS authentication */ @@ -2221,21 +2053,81 @@ 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 -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 + +-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-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 + +-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-//'` + + 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 +@@ -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-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="" + 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-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; + 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; -@@ -241,8 +244,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; @@ -2243,37 +2135,32 @@ diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/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) -@@ -342,7 +351,9 @@ typedef enum { - sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, -- sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, -+ sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, -+ sGssKeyEx, sGssStoreRekey, -+ sAcceptEnv, sPermitTunnel, +@@ -410,7 +416,7 @@ typedef enum { + sHostKeyAlgorithms, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, +- sAcceptEnv, sPermitTunnel, ++ sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, - sZeroKnowledgePasswordAuthentication, sHostCertificate, -@@ -409,10 +420,20 @@ static struct { - #ifdef GSSAPI + sHostCertificate, +@@ -484,11 +490,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 @@ -2282,7 +2169,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 +@@ -1211,6 +1223,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2293,11 +2180,10 @@ diff -up openssh-6.3p1/servconf.c.gsskex openssh-6.3p1/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; +@@ -1219,6 +1235,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; @@ -2305,7 +2191,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) +@@ -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); @@ -2313,27 +2199,421 @@ 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 -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 */ + 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.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 -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 + .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-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 + # GSSAPIDelegateCredentials no ++# GSSAPIKeyExchange no ++# GSSAPITrustDNS no + # 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 + 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_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); +@@ -192,6 +217,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 ++ * '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); ++ free(gss); ++ } ++#endif ++ + if (options.rekey_limit || options.rekey_interval) + packet_set_rekey_limits((u_int32_t)options.rekey_limit, + (time_t)options.rekey_interval); +@@ -212,11 +248,31 @@ 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 ++ + dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); + + /* 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 *); ++int userauth_gsskeyex(Authctxt *authctxt); + #endif + + void userauth(Authctxt *, char *); +@@ -327,6 +384,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, +@@ -652,19 +714,31 @@ userauth_gssapi(Authctxt *authctxt) + static u_int mech = 0; + OM_uint32 min; + int 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++; +@@ -761,8 +835,8 @@ input_gssapi_response(int type, u_int32_ + { + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; +- int oidlen; +- char *oidv; ++ u_int oidlen; ++ u_char *oidv; + + if (authctxt == NULL) + fatal("input_gssapi_response: no authentication context"); +@@ -875,6 +949,48 @@ input_gssapi_error(int type, u_int32_t p + free(lang); + return 0; + } ++ ++int ++userauth_gsskeyex(Authctxt *authctxt) ++{ ++ Buffer b; ++ 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); ++ } ++ ++ ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, ++ "gssapi-keyex"); ++ ++ gssbuf.value = buffer_ptr(&b); ++ gssbuf.length = buffer_len(&b); ++ ++ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { ++ buffer_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(); ++ ++ buffer_free(&b); ++ gss_release_buffer(&ms, &mic); ++ ++ return (1); ++} ++ + #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) + + #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); + if (nkeys == 0) +- fatal("%s: no hostkeys", __func__); +- packet_send(); ++ debug3("%s: no hostkeys", __func__); ++ else ++ packet_send(); + sshbuf_free(buf); + } + +@@ -1739,7 +1740,8 @@ main(int ac, char **av) + key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); + free(fp); + } +- 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); + } +@@ -2196,6 +2198,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)); +@@ -2213,6 +2257,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-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 + .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. +@@ -642,6 +647,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 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 + # 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-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.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 +2676,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,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 *); @@ -2426,475 +2706,295 @@ diff -up openssh-6.3p1/ssh-gss.h.gsskex openssh-6.3p1/ssh-gss.h +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.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 - 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 -+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 . --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 -+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 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 . -+This option only applies to protocol version 2 connections using GSSAPI. - .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 - { - Kex *kex; +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 */ ++ { "null", "null", KEY_NULL, 0, 0, 1 }, + { NULL, NULL, -1, -1, 0, 0 } + }; -+#ifdef GSSAPI -+ char *orig = NULL, *gss = NULL; -+ char *gss_host = NULL; -+#endif -+ - xxx_host = host; - xxx_hostaddr = hostaddr; +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, + KEY_ED25519_CERT, ++ KEY_NULL, + KEY_UNSPEC + }; -+#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); -+ } -+ } -+#endif -+ - 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 - if (options.kex_algorithms != NULL) - myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; - -+#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); -+ free(gss); -+ } -+#endif -+ - 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; - kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; - kex->kex[KEX_ECDH_SHA2] = kexecdh_client; -+#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->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 -+ - xxx_kex = kex; - - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); -@@ -317,6 +373,7 @@ void input_gssapi_token(int type, u_int3 - 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 *); -+int userauth_gsskeyex(Authctxt *authctxt); - #endif - - void userauth(Authctxt *, char *); -@@ -332,6 +389,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, -@@ -636,19 +698,31 @@ userauth_gssapi(Authctxt *authctxt) - static u_int mech = 0; - OM_uint32 min; - int 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(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++; -@@ -745,8 +819,8 @@ input_gssapi_response(int type, u_int32_ - { - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; -- int oidlen; -- char *oidv; -+ u_int oidlen; -+ u_char *oidv; - - if (authctxt == NULL) - fatal("input_gssapi_response: no authentication context"); -@@ -855,6 +929,48 @@ input_gssapi_error(int type, u_int32_t p - free(msg); - free(lang); +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 */ + -+int -+userauth_gsskeyex(Authctxt *authctxt) ++/**************** 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) +{ -+ Buffer b; -+ gss_buffer_desc gssbuf; -+ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ms; ++ 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); + -+ static int attempt = 0; -+ if (attempt++ >= 1) -+ return (0); -+ -+ if (gss_kex_context == NULL) { -+ debug("No valid Key exchange context"); -+ return (0); ++ /* 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); + } + -+ ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, -+ "gssapi-keyex"); ++ ipv64_normalise_mapped(&from, &fromlen); ++ if (from.ss_family == AF_INET6) ++ fromlen = sizeof(struct sockaddr_in6); + -+ gssbuf.value = buffer_ptr(&b); -+ gssbuf.length = buffer_len(&b); -+ -+ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { -+ buffer_free(&b); -+ return (0); ++ 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); + } + -+ 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(); ++ /* ++ * 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); ++ } + -+ buffer_free(&b); -+ gss_release_buffer(&ms, &mic); ++ /* Names are stored in lowercase. */ ++ lowercase(name); + -+ return (1); ++ /* ++ * 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); +} + - #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 @@ - #include "ssh-sandbox.h" - #include "version.h" - -+#ifdef USE_SECURITY_SESSION_API -+#include -+#endif ++/* ++ * 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. ++ */ + - #ifdef LIBWRAP - #include - #include -@@ -1794,10 +1798,13 @@ main(int ac, char **av) - logit("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; - } -+#ifndef GSSAPI -+ /* 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))) { - 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; ++const char * ++get_canonical_hostname(struct ssh *ssh, int use_dns) ++{ ++ static char *dnsname; + -+ 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); -+ } ++ if (!use_dns) ++ return ssh_remote_ipaddr(ssh); ++ else if (dnsname != NULL) ++ return dnsname; ++ else { ++ dnsname = remote_hostname(ssh); ++ return dnsname; + } -+#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) ++} + #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 @@ - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); + #ifndef _PORT_LINUX_H + #define _PORT_LINUX_H ++#include "packet.h" -+#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 */ - 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; - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - kex->kex[KEX_ECDH_SHA2] = kexecdh_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-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 - 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. - 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 -+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 -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 yes -+#GSSAPIStrictAcceptorCheck yes -+#GSSAPIKeyExchange no + #ifdef WITH_SELINUX + int ssh_selinux_enabled(void); +@@ -36,4 +37,8 @@ void oom_adjust_setup(void); - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will + 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.4p1-hpn-14.13-modified.patch b/openssh-7.4p1-hpn-14.13-modified.patch new file mode 100644 index 0000000..a6f42ba --- /dev/null +++ b/openssh-7.4p1-hpn-14.13-modified.patch @@ -0,0 +1,2314 @@ +diff -Nur openssh-7.4p1.orig/auth2.c openssh-7.4p1/auth2.c +--- openssh-7.4p1.orig/auth2.c 2020-10-23 19:51:51.143651213 +0200 ++++ openssh-7.4p1/auth2.c 2020-10-23 19:50:35.480399467 +0200 +@@ -74,6 +74,8 @@ + extern Authmethod method_gssapi; + #endif + ++static int log_flag = 0; ++ + Authmethod *authmethods[] = { + &method_none, + &method_pubkey, +@@ -249,6 +251,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(active_state), ssh_remote_port(active_state), user); ++ log_flag = 1; ++ } + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + + #ifdef WITH_SELINUX +diff -Nur openssh-7.4p1.orig/channels.c openssh-7.4p1/channels.c +--- openssh-7.4p1.orig/channels.c 2020-10-23 19:51:51.035652281 +0200 ++++ openssh-7.4p1/channels.c 2020-10-23 19:50:35.484399428 +0200 +@@ -191,6 +191,9 @@ + static int connect_next(struct channel_connect *); + static void channel_connect_ctx_free(struct channel_connect *); + ++static int hpn_disabled = 0; ++static int hpn_buffer_size = 2 * 1024 * 1024; ++ + /* -- channel core */ + + Channel * +@@ -356,6 +359,7 @@ + c->local_window_max = window; + c->local_consumed = 0; + c->local_maxpacket = maxpack; ++ c->dynamic_window = 0; + c->remote_id = -1; + c->remote_name = xstrdup(remote_name); + c->remote_window = 0; +@@ -904,11 +908,39 @@ + FD_SET(c->sock, writeset); + } + ++static int ++channel_tcpwinsz(void) ++{ ++ u_int32_t tcpwinsz = 0; ++ socklen_t optsz = sizeof(tcpwinsz); ++ int ret = -1; ++ ++ /* if we aren't on a socket return 128KB */ ++ if (!packet_connection_is_on_socket()) ++ return 128 * 1024; ++ ++ ret = getsockopt(packet_get_connection_in(), ++ 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: %d for connection: %d", tcpwinsz, ++ packet_get_connection_in()); ++ return tcpwinsz; ++} ++ + static void + channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) + { + u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); + ++ /* check buffer limits */ ++ if (!c->tcpwinsz || c->dynamic_window > 0) ++ c->tcpwinsz = channel_tcpwinsz(); ++ ++ limit = MIN(limit, 2 * c->tcpwinsz); ++ + if (c->istate == CHAN_INPUT_OPEN && + limit > 0 && + buffer_len(&c->input) < limit && +@@ -1926,14 +1958,21 @@ + c->local_maxpacket*3) || + c->local_window < c->local_window_max/2) && + c->local_consumed > 0) { ++ u_int addition = 0; ++ /* adjust max window size if we are in a dynamic environment */ ++ if (c->dynamic_window && c->tcpwinsz > c->local_window_max) { ++ /* grow the window somewhat aggressively to maintain pressure */ ++ addition = 1.5 * (c->tcpwinsz - c->local_window_max); ++ c->local_window_max += addition; ++ } + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); +- packet_put_int(c->local_consumed); ++ packet_put_int(c->local_consumed + addition); + packet_send(); + 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_consumed = 0; + } + return 1; +@@ -3179,6 +3218,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(int type, struct Forward *fwd, + int *allocated_listen_port, struct ForwardOptions *fwd_opts) +@@ -3307,8 +3354,10 @@ + } + + /* Allocate a channel number for the socket. */ ++ /* explicitly test for hpn disabled option. if true use smaller window size */ + c = channel_new("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; +@@ -4321,7 +4370,9 @@ + sock = socks[n]; + nc = channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, +- CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, ++ /* Is this really necassary? */ ++ 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-7.4p1.orig/channels.h openssh-7.4p1/channels.h +--- openssh-7.4p1.orig/channels.h 2020-10-23 19:51:50.955653073 +0200 ++++ openssh-7.4p1/channels.h 2020-10-23 19:50:35.484399428 +0200 +@@ -135,8 +135,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 */ + +@@ -319,4 +321,7 @@ + void chan_write_failed(Channel *); + void chan_obuf_empty(Channel *); + ++/* hpn handler */ ++void channel_set_hpn(int, int); ++ + #endif +diff -Nur openssh-7.4p1.orig/cipher.c openssh-7.4p1/cipher.c +--- openssh-7.4p1.orig/cipher.c 2020-10-23 19:51:51.027652360 +0200 ++++ openssh-7.4p1/cipher.c 2020-10-23 19:50:35.488399388 +0200 +@@ -59,6 +59,13 @@ + extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); + #endif + ++/* for multi-threaded aes-ctr cipher */ ++extern const EVP_CIPHER *evp_aes_ctr_mt(void); ++ ++/* no longer needed. replaced by evp pointer swap */ ++/* extern void ssh_aes_ctr_thread_destroy(EVP_CIPHER_CTX *ctx); */ ++/* extern void ssh_aes_ctr_thread_reconstruction(EVP_CIPHER_CTX *ctx); */ ++ + struct sshcipher_ctx { + int plaintext; + int encrypt; +@@ -68,7 +75,7 @@ + const struct sshcipher *cipher; + }; + +-static const struct sshcipher ciphers[] = { ++static struct sshcipher ciphers[] = { + #ifdef WITH_SSH1 + { "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 }, +@@ -118,7 +125,7 @@ + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } + }; + +-static const struct sshcipher fips_ciphers[] = { ++static 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 }, +@@ -165,6 +172,29 @@ + return ret; + } + ++/* 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) + { +@@ -238,10 +268,10 @@ + return mask; + } + +-const struct sshcipher * ++struct sshcipher * + cipher_by_name(const char *name) + { +- const struct sshcipher *c; ++ struct sshcipher *c; + for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) + if (strcmp(c->name, name) == 0) + return c; +@@ -273,7 +303,8 @@ + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { + c = cipher_by_name(p); +- if (c == NULL || c->number != SSH_CIPHER_SSH2) { ++ if (c == NULL || (c->number != SSH_CIPHER_SSH2 && ++ c->number != SSH_CIPHER_NONE)) { + free(cipher_list); + return 0; + } +@@ -605,6 +636,7 @@ + + switch (c->number) { + #ifdef WITH_OPENSSL ++ case SSH_CIPHER_NONE: + case SSH_CIPHER_SSH2: + case SSH_CIPHER_DES: + case SSH_CIPHER_BLOWFISH: +@@ -653,6 +685,7 @@ + + switch (c->number) { + #ifdef WITH_OPENSSL ++ case SSH_CIPHER_NONE: + case SSH_CIPHER_SSH2: + case SSH_CIPHER_DES: + case SSH_CIPHER_BLOWFISH: +diff -Nur openssh-7.4p1.orig/cipher-ctr-mt.c openssh-7.4p1/cipher-ctr-mt.c +--- openssh-7.4p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.4p1/cipher-ctr-mt.c 2020-10-23 19:50:35.488399388 +0200 +@@ -0,0 +1,602 @@ ++/* ++ * 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" ++ ++/* compatibility with old or broken OpenSSL versions */ ++#include "openbsd-compat/openssl-compat.h" ++ ++#ifndef USE_BUILTIN_RIJNDAEL ++#include ++#endif ++ ++#include ++ ++/*-------------------- TUNABLES --------------------*/ ++/* Number of pregen threads to use */ ++#define CIPHER_THREADS 2 ++ ++/* Number of keystream queues */ ++#define NUMKQ (CIPHER_THREADS + 2) ++ ++/* 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("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 ++{ ++ struct kq q[NUMKQ]; ++ AES_KEY aes_ctx; ++ STATS_STRUCT(stats); ++ u_char aes_counter[AES_BLOCK_SIZE]; ++ pthread_t tid[CIPHER_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 *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 *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++) { ++ 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++) { ++ 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 *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 *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(ctx->iv, 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 ++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 *c; ++ int i; ++ ++ 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(ctx->iv, iv, AES_BLOCK_SIZE); ++ c->state |= HAVE_IV; ++ } ++ ++ if (c->state == (HAVE_KEY | HAVE_IV)) { ++ /* Clear queues */ ++ memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE); ++ c->q[0].qstate = KQINIT; ++ for (i = 1; i < NUMKQ; i++) { ++ memcpy(c->q[i].ctr, ctx->iv, 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++) { ++ debug("spawned a thread"); ++ pthread_rwlock_wrlock(&c->tid_lock); ++ pthread_create(&c->tid[i], NULL, thread_loop, c); ++ 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 *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 *c; ++ int i; ++ c = EVP_CIPHER_CTX_get_app_data(ctx); ++ /* reconstruct threads */ ++ for (i = 0; i < CIPHER_THREADS; i++) { ++ debug("spawned a thread"); ++ pthread_rwlock_wrlock(&c->tid_lock); ++ pthread_create(&c->tid[i], NULL, thread_loop, c); ++ pthread_rwlock_unlock(&c->tid_lock); ++ } ++} ++ ++static int ++ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) ++{ ++ struct ssh_aes_ctr_ctx *c; ++ ++ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { ++#ifdef CIPHER_THREAD_STATS ++ debug("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) ++{ ++ 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 ++ return &aes_ctr; ++} ++ ++#endif /* defined(WITH_OPENSSL) */ +diff -Nur openssh-7.4p1.orig/cipher.h openssh-7.4p1/cipher.h +--- openssh-7.4p1.orig/cipher.h 2020-10-23 19:51:51.015652479 +0200 ++++ openssh-7.4p1/cipher.h 2020-10-23 19:50:35.488399388 +0200 +@@ -83,8 +83,11 @@ + }; + struct sshcipher_ctx; + ++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); ++ + u_int cipher_mask_ssh1(int); +-const struct sshcipher *cipher_by_name(const char *); ++struct sshcipher *cipher_by_name(const char *); + const struct sshcipher *cipher_by_number(int); + int cipher_number(const char *); + char *cipher_name(int); +@@ -106,7 +109,9 @@ + 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 *); + u_int cipher_ctx_get_number(struct sshcipher_ctx *); + +diff -Nur openssh-7.4p1.orig/clientloop.c openssh-7.4p1/clientloop.c +--- openssh-7.4p1.orig/clientloop.c 2020-10-23 19:51:51.043652202 +0200 ++++ openssh-7.4p1/clientloop.c 2020-10-23 19:50:35.488399388 +0200 +@@ -2005,7 +2005,9 @@ + return NULL; + c = channel_new("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; + } +@@ -2030,7 +2032,8 @@ + } + c = channel_new("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; +@@ -2059,7 +2062,8 @@ + } + + c = channel_new("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-7.4p1.orig/compat.c openssh-7.4p1/compat.c +--- openssh-7.4p1.orig/compat.c 2020-10-23 19:51:51.007652558 +0200 ++++ openssh-7.4p1/compat.c 2020-10-23 19:50:35.492399348 +0200 +@@ -213,6 +213,13 @@ + debug("match: %s pat %s compat 0x%08x", + version, check[i].pat, check[i].bugs); + datafellows = check[i].bugs; /* XXX for now */ ++ /* Check to see if the remote side is OpenSSH and not HPN */ ++ if (strstr(version, "OpenSSH") != NULL) { ++ if (strstr(version, "hpn") == NULL) { ++ datafellows |= SSH_BUG_LARGEWINDOW; ++ debug("Remote is NON-HPN aware"); ++ } ++ } + return check[i].bugs; + } + } +diff -Nur openssh-7.4p1.orig/compat.h openssh-7.4p1/compat.h +--- openssh-7.4p1.orig/compat.h 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/compat.h 2020-10-23 19:50:35.492399348 +0200 +@@ -62,6 +62,7 @@ + #define SSH_BUG_CURVE25519PAD 0x10000000 + #define SSH_BUG_HOSTKEYS 0x20000000 + #define SSH_BUG_DHGEX_LARGE 0x40000000 ++#define SSH_BUG_LARGEWINDOW 0x80000000 + + void enable_compat13(void); + void enable_compat20(void); +diff -Nur openssh-7.4p1.orig/HPN-README openssh-7.4p1/HPN-README +--- openssh-7.4p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-7.4p1/HPN-README 2020-10-23 20:00:09.598723849 +0200 +@@ -0,0 +1,136 @@ ++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 ++ ++BUFFER SIZES: ++ ++If HPN is disabled the receive buffer size will be set to the ++OpenSSH default of 64K. ++ ++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. ++ ++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. ++ This work was financed, in part, by Cisco System, Inc., the National ++ Library of Medicine, and the National Science Foundation. +diff -Nur openssh-7.4p1.orig/kex.c openssh-7.4p1/kex.c +--- openssh-7.4p1.orig/kex.c 2020-10-23 19:51:51.043652202 +0200 ++++ openssh-7.4p1/kex.c 2020-10-23 19:50:35.492399348 +0200 +@@ -841,6 +841,11 @@ + int nenc, nmac, ncomp; + u_int mode, ctos, need, dh_need, authlen; + int r, first_kex_follows; ++ int log_flag = 0; ++ int auth_flag; ++ ++ 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) +@@ -911,11 +916,35 @@ + peer[ncomp] = NULL; + goto out; + } ++ debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); ++ if (strcmp(newkeys->enc.name, "none") == 0) { ++ debug("Requesting NONE. Authflag is %d", auth_flag); ++ if (auth_flag == 1) ++ debug("None requested post authentication."); ++ else ++ fatal("Pre-authentication none cipher requests are not allowed."); ++ } + 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++) { +diff -Nur openssh-7.4p1.orig/Makefile.in openssh-7.4p1/Makefile.in +--- openssh-7.4p1.orig/Makefile.in 2020-10-23 19:51:51.167650975 +0200 ++++ openssh-7.4p1/Makefile.in 2020-10-23 19:50:35.508399190 +0200 +@@ -49,7 +49,7 @@ + LD=@LD@ + CFLAGS=@CFLAGS@ + CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ +-LIBS=@LIBS@ ++LIBS=@LIBS@ -lpthread + K5LIBS=@K5LIBS@ + GSSLIBS=@GSSLIBS@ + SSHLIBS=@SSHLIBS@ +@@ -85,7 +85,7 @@ + LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + authfd.o authfile.o bufaux.o bufbn.o bufec.o buffer.o \ + canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ +- cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ ++ cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \ + compat.o crc32.o deattack.o fatal.o hostfile.o \ + log.o match.o md-sha256.o moduli.o nchan.o packet.o opacket.o \ + readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ +diff -Nur openssh-7.4p1.orig/opacket.c openssh-7.4p1/opacket.c +--- openssh-7.4p1.orig/opacket.c 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/opacket.c 2020-10-23 19:50:35.492399348 +0200 +@@ -294,13 +294,15 @@ + sshpkt_fatal(active_state, __func__, r); + } + +-void ++int + packet_write_poll(void) + { + int r; + + if ((r = ssh_packet_write_poll(active_state)) != 0) + sshpkt_fatal(active_state, __func__, r); ++ ++ return r; + } + + void +diff -Nur openssh-7.4p1.orig/opacket.h openssh-7.4p1/opacket.h +--- openssh-7.4p1.orig/opacket.h 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/opacket.h 2020-10-23 19:50:35.492399348 +0200 +@@ -44,7 +44,7 @@ + int packet_read_poll_seqnr(u_int32_t *); + void packet_process_incoming(const char *buf, u_int len); + void packet_write_wait(void); +-void packet_write_poll(void); ++int packet_write_poll(void); + void packet_read_expect(int expected_type); + #define packet_set_timeout(timeout, count) \ + ssh_packet_set_timeout(active_state, (timeout), (count)) +diff -Nur openssh-7.4p1.orig/packet.c openssh-7.4p1/packet.c +--- openssh-7.4p1.orig/packet.c 2020-10-23 19:51:51.019652440 +0200 ++++ openssh-7.4p1/packet.c 2020-10-23 19:50:35.496399309 +0200 +@@ -291,7 +291,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) { +@@ -1036,6 +1036,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; ++} ++ ++/* this determines if authentciation has happened as of yet. Needed for ++ * NONE cipher switching. */ ++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) +@@ -1062,6 +1080,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 methods -cjr */ ++ if (rekey_requested == 1) { ++ rekey_requested = 0; ++ return 1; ++ } ++ + /* Time-based rekeying */ + if (state->rekey_interval != 0 && + state->rekey_time + state->rekey_interval <= monotime()) +@@ -3105,3 +3130,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-7.4p1.orig/packet.h openssh-7.4p1/packet.h +--- openssh-7.4p1.orig/packet.h 2020-10-23 19:51:51.019652440 +0200 ++++ openssh-7.4p1/packet.h 2020-10-23 19:50:35.496399309 +0200 +@@ -146,6 +146,10 @@ + int ssh_packet_set_maxsize(struct ssh *, u_int); + u_int ssh_packet_get_maxsize(struct ssh *); + ++/* for forced packet rekeying post auth */ ++void packet_request_rekeying(void); ++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 *); + +@@ -159,6 +163,7 @@ + + void *ssh_packet_get_input(struct ssh *); + void *ssh_packet_get_output(struct ssh *); ++void *ssh_packet_get_send_context(struct ssh *); + + /* new API */ + int sshpkt_start(struct ssh *ssh, u_char type); +diff -Nur openssh-7.4p1.orig/progressmeter.c openssh-7.4p1/progressmeter.c +--- openssh-7.4p1.orig/progressmeter.c 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/progressmeter.c 2020-10-23 19:50:35.496399309 +0200 +@@ -69,6 +69,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 */ +@@ -128,12 +130,17 @@ + int hours, minutes, seconds; + int i, len; + int file_len; ++ off_t delta_pos; + + transferred = *counter - (cur_pos ? cur_pos : start_pos); + cur_pos = *counter; + 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 { +@@ -158,7 +165,7 @@ + + /* filename */ + buf[0] = '\0'; +- file_len = win_size - 35; ++ file_len = win_size - 45; + if (file_len > 0) { + len = snprintf(buf, file_len + 1, "\r%s", file); + if (len < 0) +@@ -188,6 +195,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; +@@ -224,6 +240,7 @@ + + atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); + last_update = now; ++ last_pos = cur_pos; + } + + /*ARGSUSED*/ +diff -Nur openssh-7.4p1.orig/readconf.c openssh-7.4p1/readconf.c +--- openssh-7.4p1.orig/readconf.c 2020-10-23 19:51:51.151651134 +0200 ++++ openssh-7.4p1/readconf.c 2020-10-23 19:50:35.496399309 +0200 +@@ -66,6 +66,7 @@ + #include "uidswap.h" + #include "myproposal.h" + #include "digest.h" ++#include "sshbuf.h" + #include "ssh-gss.h" + + /* Format of the configuration file: +@@ -167,6 +168,9 @@ + oSendEnv, oControlPath, oControlMaster, oControlPersist, + oHashKnownHosts, + oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, ++ oNoneEnabled, oNoneSwitch, ++ oDisableMTAES, ++ oTcpRcvBufPoll, oTcpRcvBuf, oHPNDisabled, oHPNBufferSize, + oVisualHostKey, + oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, + oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, +@@ -295,6 +299,9 @@ + { "kexalgorithms", oKexAlgorithms }, + { "ipqos", oIPQoS }, + { "requesttty", oRequestTTY }, ++ { "noneenabled", oNoneEnabled }, ++ { "noneswitch", oNoneSwitch }, ++ { "disablemtaes", oDisableMTAES }, + { "proxyusefdpass", oProxyUseFdpass }, + { "canonicaldomains", oCanonicalDomains }, + { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, +@@ -311,6 +318,11 @@ + { "ignoreunknown", oIgnoreUnknown }, + { "proxyjump", oProxyJump }, + ++ { "tcprcvbufpoll", oTcpRcvBufPoll }, ++ { "tcprcvbuf", oTcpRcvBuf }, ++ { "hpndisabled", oHPNDisabled }, ++ { "hpnbuffersize", oHPNBufferSize }, ++ + { NULL, oBadOption } + }; + +@@ -1019,6 +1031,42 @@ + intptr = &options->check_host_ip; + goto parse_flag; + ++ case oNoneEnabled: ++ intptr = &options->none_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 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 oVerifyHostKeyDNS: + intptr = &options->verify_host_key_dns; + multistate_ptr = multistate_yesnoask; +@@ -1211,6 +1259,10 @@ + intptr = &options->connection_attempts; + goto parse_int; + ++ case oTcpRcvBuf: ++ intptr = &options->tcp_rcv_buf; ++ goto parse_int; ++ + case oCipher: + intptr = &options->cipher; + arg = strdelim(&s); +@@ -1900,6 +1952,13 @@ + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->request_tty = -1; ++ options->none_switch = -1; ++ options->none_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; +@@ -2073,6 +2132,32 @@ + options->server_alive_interval = 0; + if (options->server_alive_count_max == -1) + options->server_alive_count_max = 3; ++ if (options->none_switch == -1) ++ options->none_switch = 0; ++ if (options->none_enabled == -1) ++ options->none_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) { ++ /* 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->control_master == -1) + options->control_master = 0; + if (options->control_persist == -1) { +diff -Nur openssh-7.4p1.orig/readconf.h openssh-7.4p1/readconf.h +--- openssh-7.4p1.orig/readconf.h 2020-10-23 19:51:51.151651134 +0200 ++++ openssh-7.4p1/readconf.h 2020-10-23 19:50:35.496399309 +0200 +@@ -64,6 +64,10 @@ + int compression_level; /* Compression level 1 (fast) to 9 + * (best). */ + 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 */ + LogLevel log_level; /* Level for logging. */ +@@ -127,7 +131,11 @@ + + int enable_ssh_keysign; + int64_t rekey_limit; ++ int none_switch; /* Use none cipher */ ++ int none_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-7.4p1.orig/regress/allow-deny-users.sh openssh-7.4p1/regress/allow-deny-users.sh +--- openssh-7.4p1.orig/regress/allow-deny-users.sh 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/regress/allow-deny-users.sh 2020-10-23 19:50:35.496399309 +0200 +@@ -4,7 +4,7 @@ + tid="AllowUsers/DenyUsers" + + me="$LOGNAME" +-if [ "x$me" == "x" ]; then ++if [ "x$me" = "x" ]; then + me=`whoami` + fi + other="nobody" +diff -Nur openssh-7.4p1.orig/sandbox-seccomp-filter.c openssh-7.4p1/sandbox-seccomp-filter.c +--- openssh-7.4p1.orig/sandbox-seccomp-filter.c 2020-10-23 19:51:51.031652321 +0200 ++++ openssh-7.4p1/sandbox-seccomp-filter.c 2020-10-23 19:50:35.496399309 +0200 +@@ -172,6 +172,9 @@ + #if defined(__NR_flock) && defined(__s390__) + SC_ALLOW(flock), + #endif ++#ifdef __NR_getpeername /* not defined on archs that go via socketcall(2) */ ++ SC_ALLOW(getpeername), ++#endif + #ifdef __NR_getpgid + SC_ALLOW(getpgid), + #endif +@@ -238,6 +241,9 @@ + #ifdef __NR_sigprocmask + SC_ALLOW(sigprocmask), + #endif ++#ifdef __NR_socketcall ++ SC_ALLOW(socketcall), ++#endif + #ifdef __NR_time + SC_ALLOW(time), + #endif +diff -Nur openssh-7.4p1.orig/scp.c openssh-7.4p1/scp.c +--- openssh-7.4p1.orig/scp.c 2020-10-23 19:51:51.039652242 +0200 ++++ openssh-7.4p1/scp.c 2020-10-23 19:50:35.496399309 +0200 +@@ -766,7 +766,7 @@ + off_t i, statbytes; + size_t amt, nr; + int fd = -1, haderr, indx; +- char *last, *name, buf[2048], encname[PATH_MAX]; ++ char *last, *name, buf[16384], encname[PATH_MAX]; + int len; + + for (indx = 0; indx < argc; ++indx) { +@@ -934,7 +934,7 @@ + off_t size, statbytes; + unsigned long long ull; + int setimes, targisdir, wrerrno = 0; +- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; ++ char ch, *cp, *np, *targ, *why, *vect[1], buf[16384], visbuf[16384]; + struct timeval tv[2]; + + #define atime tv[0] +diff -Nur openssh-7.4p1.orig/servconf.c openssh-7.4p1/servconf.c +--- openssh-7.4p1.orig/servconf.c 2020-10-23 19:51:51.155651094 +0200 ++++ openssh-7.4p1/servconf.c 2020-10-23 19:50:35.496399309 +0200 +@@ -57,6 +57,7 @@ + #include "auth.h" + #include "myproposal.h" + #include "digest.h" ++#include "sshbuf.h" + #include "ssh-gss.h" + + static void add_listen_addr(ServerOptions *, char *, int); +@@ -168,6 +169,11 @@ + options->authorized_principals_file = NULL; + options->authorized_principals_command = NULL; + options->authorized_principals_command_user = NULL; ++ options->none_enabled = -1; ++ options->disable_multithreaded = -1, ++ options->tcp_rcv_buf_poll = -1; ++ options->hpn_disabled = -1; ++ options->hpn_buffer_size = -1; + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->version_addendum = NULL; +@@ -209,6 +215,10 @@ + fill_default_server_options(ServerOptions *options) + { + int i; ++ /* needed for hpn socket tests */ ++ int sock; ++ int socksize; ++ int socksizelen = sizeof(int); + + /* Portable-specific options */ + if (options->use_pam == -1) +@@ -353,6 +363,45 @@ + } + if (options->permit_tun == -1) + options->permit_tun = SSH_TUNMODE_NO; ++ if (options->none_enabled == -1) ++ options->none_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_LOWDELAY; + if (options->ip_qos_bulk == -1) +@@ -437,6 +486,9 @@ + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, ++ sNoneEnabled, ++ sDisableMTAES, ++ sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize, + sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, + sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, + sPermitUserEnvironment, sAllowTcpForwarding, sCompression, +@@ -622,6 +674,11 @@ + { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, + { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, + { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, ++ { "noneenabled", sNoneEnabled, SSHCFG_ALL }, ++ { "disableMTAES", sDisableMTAES, SSHCFG_ALL }, ++ { "hpndisabled", sHPNDisabled, SSHCFG_ALL }, ++ { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL }, ++ { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, + { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, +@@ -1234,10 +1291,30 @@ + *intptr = value; + break; + ++ 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; + goto parse_flag; + ++ case sNoneEnabled: ++ intptr = &options->none_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-7.4p1.orig/servconf.h openssh-7.4p1/servconf.h +--- openssh-7.4p1.orig/servconf.h 2020-10-23 19:51:51.155651094 +0200 ++++ openssh-7.4p1/servconf.h 2020-10-23 19:50:35.496399309 +0200 +@@ -181,6 +181,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 permit_tun; + +diff -Nur openssh-7.4p1.orig/serverloop.c openssh-7.4p1/serverloop.c +--- openssh-7.4p1.orig/serverloop.c 2020-10-23 19:51:51.039652242 +0200 ++++ openssh-7.4p1/serverloop.c 2020-10-23 19:50:35.496399309 +0200 +@@ -84,6 +84,9 @@ + extern Authctxt *the_authctxt; + extern int use_privsep; + ++static u_long stdin_bytes = 0; /* Number of bytes written to stdin. */ ++static u_long fdout_bytes = 0; /* Number of stdout bytes read from program. */ ++ + static int no_more_sessions = 0; /* Disallow further sessions. */ + + /* +@@ -100,6 +103,20 @@ + static void server_init_dispatch(void); + + /* ++ * Returns current time in seconds from Jan 1, 1970 with the maximum ++ * available resolution. ++ */ ++ ++static double ++get_current_time(void) ++{ ++ struct timeval tv; ++ gettimeofday(&tv, NULL); ++ return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; ++} ++ ++ ++/* + * we write to this pipe if a SIGCHLD is caught in order to avoid + * the race between select() and child_terminated + */ +@@ -305,6 +322,7 @@ + } else { + /* Buffer any received data. */ + packet_process_incoming(buf, len); ++ fdout_bytes += len; + } + } + return 0; +@@ -318,7 +336,7 @@ + { + /* Send any buffered packet data to the client. */ + if (FD_ISSET(connection_out, writeset)) +- packet_write_poll(); ++ stdin_bytes += packet_write_poll(); + } + + static void +@@ -353,11 +371,13 @@ + server_loop2(Authctxt *authctxt) + { + fd_set *readset = NULL, *writeset = NULL; ++ double start_time, total_time; + int max_fd; + u_int nalloc = 0, connection_in, connection_out; + u_int64_t rekey_timeout_ms = 0; + + debug("Entering interactive session for SSH2."); ++ start_time = get_current_time(); + + mysignal(SIGCHLD, sigchld_handler); + child_terminated = 0; +@@ -415,6 +435,11 @@ + + /* free remaining sessions, e.g. remove wtmp entries */ + session_destroy_all(NULL); ++ total_time = get_current_time() - 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(active_state), ssh_remote_port(active_state), ++ stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, ++ fdout_bytes / total_time); + } + + static int +@@ -528,7 +553,8 @@ + if (sock < 0) + goto done; + c = channel_new("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) +@@ -564,6 +590,8 @@ + c = channel_new("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(c); +diff -Nur openssh-7.4p1.orig/session.c openssh-7.4p1/session.c +--- openssh-7.4p1.orig/session.c 2020-10-23 19:51:51.023652400 +0200 ++++ openssh-7.4p1/session.c 2020-10-23 19:50:35.496399309 +0200 +@@ -225,6 +225,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("auth socket", + SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, +@@ -2248,7 +2249,8 @@ + channel_set_fds(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-7.4p1.orig/sftp.1 openssh-7.4p1/sftp.1 +--- openssh-7.4p1.orig/sftp.1 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sftp.1 2020-10-23 19:50:35.496399309 +0200 +@@ -266,7 +266,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-7.4p1.orig/sftp.c openssh-7.4p1/sftp.c +--- openssh-7.4p1.orig/sftp.c 2020-10-23 19:51:51.039652242 +0200 ++++ openssh-7.4p1/sftp.c 2020-10-23 19:50:35.500399269 +0200 +@@ -72,7 +72,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-7.4p1.orig/sshbuf.h openssh-7.4p1/sshbuf.h +--- openssh-7.4p1.orig/sshbuf.h 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sshbuf.h 2020-10-23 19:50:35.500399269 +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-7.4p1.orig/ssh.c openssh-7.4p1/ssh.c +--- openssh-7.4p1.orig/ssh.c 2020-10-23 19:51:51.155651094 +0200 ++++ openssh-7.4p1/ssh.c 2020-10-23 19:50:35.500399269 +0200 +@@ -954,6 +954,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); +@@ -1569,6 +1573,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) +@@ -1962,6 +1968,78 @@ + NULL, fileno(stdin), &command, environ); + } + ++static void ++hpn_options_init(void) ++{ ++ /* ++ * 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 (datafellows & SSH_BUG_LARGEWINDOW) { ++ debug("HPN to Non-HPN Connection"); ++ } else { ++ 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(void) +@@ -1988,9 +2066,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; + } +@@ -1999,6 +2079,10 @@ + window, packetmax, CHAN_EXTENDED_WRITE, + "client-session", /*nonblock*/0); + ++ if (options.tcp_rcv_buf_poll > 0 && !options.hpn_disabled) { ++ c->dynamic_window = 1; ++ debug("Enabled Dynamic Window Scaling"); ++ } + debug3("ssh_session2_open: channel_new: %d", c->self); + + channel_send_open(c->self); +@@ -2014,6 +2098,13 @@ + { + int id = -1; + ++ /* ++ * 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(); ++ + /* XXX should be pre-session */ + if (!options.control_persist) + ssh_init_stdio_forwarding(); +diff -Nur openssh-7.4p1.orig/sshconnect2.c openssh-7.4p1/sshconnect2.c +--- openssh-7.4p1.orig/sshconnect2.c 2020-10-23 19:51:51.155651094 +0200 ++++ openssh-7.4p1/sshconnect2.c 2020-10-23 19:50:35.500399269 +0200 +@@ -85,6 +85,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 + */ + +@@ -157,6 +164,8 @@ + return ret; + } + ++static char *myproposal[PROPOSAL_MAX]; ++static const char *myproposal_default[PROPOSAL_MAX] = { KEX_CLIENT }; + void + ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) + { +@@ -170,6 +179,8 @@ + char *gss_host = NULL; + #endif + ++ memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); ++ + xxx_host = host; + xxx_hostaddr = hostaddr; + +@@ -480,6 +491,47 @@ + + if (!authctxt.success) + fatal("Authentication failed."); ++ ++ /* ++ * If the user wants to use the none cipher, 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"; ++ kex_prop2buf(active_state->kex->my, myproposal); ++ packet_request_rekeying(); ++ fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n"); ++ } 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(active_state); ++ ++ /* 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-7.4p1.orig/sshconnect.c openssh-7.4p1/sshconnect.c +--- openssh-7.4p1.orig/sshconnect.c 2020-10-23 19:51:51.043652202 +0200 ++++ openssh-7.4p1/sshconnect.c 2020-10-23 19:50:35.500399269 +0200 +@@ -267,6 +267,30 @@ + } + + /* ++ * 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 (possibly privileged) socket for use as the ssh connection. + */ + static int +@@ -282,6 +306,9 @@ + } + fcntl(sock, F_SETFD, FD_CLOEXEC); + ++ if (options.tcp_rcv_buf > 0) ++ ssh_set_socket_recvbuf(sock); ++ + /* Bind the socket to an alternative local IP address */ + if (options.bind_address == NULL && !privileged) + return sock; +@@ -526,10 +553,10 @@ + /* Send our own protocol version identification. */ + if (compat20) { + xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", +- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION); ++ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE); + } else { + xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", +- PROTOCOL_MAJOR_1, minor1, SSH_VERSION); ++ PROTOCOL_MAJOR_1, minor1, SSH_RELEASE); + } + if (atomicio(vwrite, connection_out, client_version_string, + strlen(client_version_string)) != strlen(client_version_string)) +diff -Nur openssh-7.4p1.orig/sshd.c openssh-7.4p1/sshd.c +--- openssh-7.4p1.orig/sshd.c 2020-10-23 19:51:51.155651094 +0200 ++++ openssh-7.4p1/sshd.c 2020-10-23 19:50:35.500399269 +0200 +@@ -390,8 +390,8 @@ + char buf[256]; /* Must not be larger than remote_version. */ + 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, ++ xasprintf(&server_version_string, "SSH-%d.%d-%s-%.100s%s%s\r\n", ++ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, + (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, + *options.version_addendum == '\0' ? "" : " ", + options.version_addendum); +@@ -447,6 +447,9 @@ + } + debug("Client protocol version %d.%d; client software version %.100s", + remote_major, remote_minor, remote_version); ++ 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); + + ssh->compat = compat_datafellows(remote_version); + +@@ -1115,6 +1118,8 @@ + int ret, listen_sock, on = 1; + struct addrinfo *ai; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; ++ int socksize; ++ int socksizelen = sizeof(int); + + for (ai = options.listen_addrs; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) +@@ -1155,6 +1160,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) < 0) { + error("Bind to port %s on %s failed: %.200s.", +@@ -1716,6 +1726,13 @@ + /* 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); ++ } ++ + /* challenge-response is implemented via keyboard interactive */ + if (options.challenge_response_authentication) + options.kbd_interactive_authentication = 1; +@@ -2148,6 +2165,9 @@ + remote_ip, remote_port, laddr, ssh_local_port(ssh)); + 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 +@@ -2250,6 +2270,26 @@ + notify_hostkeys(active_state); + + /* Start session. */ ++ ++#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(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 ++ + do_authenticated(authctxt); + + /* The connection has been terminated. */ +@@ -2315,6 +2355,9 @@ + struct kex *kex; + int r; + ++ if (options.none_enabled == 1) ++ debug("WARNING: None cipher enabled"); ++ + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( + options.kex_algorithms); + myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal( +diff -Nur openssh-7.4p1.orig/sshd_config openssh-7.4p1/sshd_config +--- openssh-7.4p1.orig/sshd_config 2020-10-23 19:51:51.155651094 +0200 ++++ openssh-7.4p1/sshd_config 2020-10-23 20:00:42.918394357 +0200 +@@ -136,6 +136,25 @@ + # 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 ++ ++# 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-7.4p1.orig/version.h openssh-7.4p1/version.h +--- openssh-7.4p1.orig/version.h 2020-10-23 19:51:51.159651054 +0200 ++++ openssh-7.4p1/version.h 2020-10-23 19:50:35.500399269 +0200 +@@ -16,5 +16,6 @@ + + #define SSH_PORTABLE "p1" + #define GSI_PORTABLE "c-GSI" ++#define SSH_HPN "-hpn14v13" + #define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ +- GSI_VERSION KRB5_VERSION ++ GSI_VERSION SSH_HPN KRB5_VERSION diff --git a/openssh-7.4p1-kdf-cavs.patch b/openssh-7.4p1-kdf-cavs.patch new file mode 100644 index 0000000..65feb96 --- /dev/null +++ b/openssh-7.4p1-kdf-cavs.patch @@ -0,0 +1,611 @@ +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 ++ $(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) + +@@ -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,380 @@ ++/* ++ * 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); ++ ++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-7.4p1-kuserok.patch b/openssh-7.4p1-kuserok.patch new file mode 100644 index 0000000..ff0d6d4 --- /dev/null +++ b/openssh-7.4p1-kuserok.patch @@ -0,0 +1,288 @@ +diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c +--- openssh-7.4p1/auth-krb5.c.kuserok 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/auth-krb5.c 2017-02-09 09:20:00.958084311 +0100 +@@ -54,6 +54,21 @@ + + extern ServerOptions options; + ++int ++ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client, ++ int k5login_exists) ++{ ++ if (options.use_kuserok || !k5login_exists) ++ return krb5_kuserok(krb5_ctx, krb5_user, client); ++ else { ++ char kuser[65]; ++ ++ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) ++ return 0; ++ return strcmp(kuser, client) == 0; ++ } ++} ++ + static int + krb5_init(void *context) + { +@@ -157,8 +172,9 @@ auth_krb5_password(Authctxt *authctxt, c + if (problem) + goto out; + +- if (!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-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c +--- openssh-7.4p1/gss-serv-krb5.c.kuserok 2017-02-09 09:20:00.955084317 +0100 ++++ openssh-7.4p1/gss-serv-krb5.c 2017-02-09 09:20:00.958084311 +0100 +@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr + int); + + static krb5_context krb_context = NULL; ++extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int); + + /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ + +@@ -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 + /* 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) ++ && k5login_exists) { + 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 + 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 -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.kuserok 2017-02-09 09:20:00.951084326 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-09 09:21:29.802896034 +0100 +@@ -165,6 +165,7 @@ initialize_server_options(ServerOptions + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->version_addendum = NULL; ++ options->use_kuserok = -1; + options->fingerprint_hash = -1; + options->disable_forwarding = -1; + } +@@ -334,6 +335,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; + 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) +@@ -399,7 +402,7 @@ typedef enum { + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsRSAAuthentication, sRSAAuthentication, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +- sKerberosGetAFSToken, ++ sKerberosGetAFSToken, sKerberosUseKuserok, + sKerberosTgtPassing, sChallengeResponseAuthentication, + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, +@@ -478,11 +481,13 @@ static struct { + #else + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, + #endif ++ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, + #else + { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, + { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, ++ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, + #endif + { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, + { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, +@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions + *activep = value; + break; + ++ case sKerberosUseKuserok: ++ intptr = &options->use_kuserok; ++ goto parse_flag; ++ + case sPermitOpen: + arg = strdelim(&cp); + if (!arg || *arg == '\0') +@@ -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); + +@@ -2308,6 +2318,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(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + + /* string arguments */ +diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.kuserok 2017-02-09 09:20:00.951084326 +0100 ++++ openssh-7.4p1/servconf.h 2017-02-09 09:20:00.959084309 +0100 +@@ -174,6 +174,7 @@ typedef struct { + + int num_permitted_opens; + ++ int use_kuserok; + char *chroot_directory; + char *revoked_keys_file; + char *trusted_user_ca_keys; +diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.kuserok 2017-02-09 09:20:00.959084309 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-02-09 09:22:33.517761012 +0100 +@@ -846,6 +846,10 @@ Specifies whether to automatically destr + file on logout. + The default is + .Cm yes . ++.It Cm KerberosUseKuserok ++Specifies whether to look at .k5login file for user's aliases. ++The default is ++.Cm yes . + .It Cm KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. + Multiple algorithms must be comma-separated. +@@ -1074,6 +1078,7 @@ Available keywords are + .Cm IPQoS , + .Cm KbdInteractiveAuthentication , + .Cm KerberosAuthentication , ++.Cm KerberosUseKuserok , + .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 2017-02-09 09:20:00.953084322 +0100 ++++ openssh-7.4p1/sshd_config 2017-02-09 09:20:00.959084309 +0100 +@@ -73,6 +73,7 @@ ChallengeResponseAuthentication no + #KerberosOrLocalPasswd yes + #KerberosTicketCleanup yes + #KerberosGetAFSToken no ++#KerberosUseKuserok yes + + # GSSAPI options + GSSAPIAuthentication yes diff --git a/openssh-7.4p1-legacy-algorithms.patch b/openssh-7.4p1-legacy-algorithms.patch new file mode 100644 index 0000000..1d8178c --- /dev/null +++ b/openssh-7.4p1-legacy-algorithms.patch @@ -0,0 +1,263 @@ +diff -up openssh-7.4p1/dh.h.legacy openssh-7.4p1/dh.h +--- openssh-7.4p1/dh.h.legacy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/dh.h 2017-03-02 17:00:37.640695985 +0100 +@@ -50,7 +50,7 @@ u_int dh_estimate(int); + * Max value from RFC4419. + * Miniumum increased in light of DH precomputation attacks. + */ +-#define DH_GRP_MIN 2048 ++#define DH_GRP_MIN 1024 + #define DH_GRP_MAX 8192 + + /* +diff -up openssh-7.4p1/moduli.legacy openssh-7.4p1/moduli +--- openssh-7.4p1/moduli.legacy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/moduli 2017-03-02 17:00:37.642695983 +0100 +@@ -1,5 +1,83 @@ + # $OpenBSD: moduli,v 1.18 2016/08/11 01:42:11 dtucker Exp $ + # Time Type Tests Tries Size Generator Modulus ++20150520233853 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2AC62AF ++20150520233854 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2BCC50F ++20150520233854 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2C241F3 ++20150520233855 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2DDF347 ++20150520233856 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2E3FDBB ++20150520233857 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3006603 ++20150520233858 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA31D9C37 ++20150520233859 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA333355B ++20150520233900 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3428B23 ++20150520233902 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA37C9A43 ++20150520233903 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA384B367 ++20150520233903 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3903453 ++20150520233904 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3946C77 ++20150520233904 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA39F6A9B ++20150520233904 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3A0E88B ++20150520233905 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3A37763 ++20150520233906 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BBDD57 ++20150520233906 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BDCDD7 ++20150520233906 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BF5D73 ++20150520233907 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3C9BB83 ++20150520233908 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3E5ADCF ++20150520233909 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3F82077 ++20150520233910 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA406944F ++20150520233910 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA40F7457 ++20150520233912 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA438733B ++20150520233913 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA44707FB ++20150520233914 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA4588A2B ++20150520233916 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA48CC01B ++20150520233917 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA4960077 ++20150522025931 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD18DA1F ++20150522025936 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD3763B3 ++20150522025942 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD702B8B ++20150522025943 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD77C283 ++20150522025947 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD96C25B ++20150522025953 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADD9B3DB ++20150522025956 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADE84F07 ++20150522025957 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADEC1DB3 ++20150522030001 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE0E297F ++20150522030004 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE2A1E23 ++20150522030005 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE2ADE53 ++20150522030008 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE47B9F7 ++20150522030009 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE4E1343 ++20150522030014 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE715CBB ++20150522030016 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE7BC9EF ++20150522030018 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE84579B ++20150522030019 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE8A564B ++20150522030023 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAEAF7AD7 ++20150522030025 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAEB9DC53 ++20150522030027 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAECD976F ++20150522030034 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF07F063 ++20150522030034 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF08ACBB ++20150522030037 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF192C07 ++20150522030039 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF241333 ++20150522030040 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF255B3B ++20150522030044 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF3DEC37 ++20150522030048 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF60F05B ++20150522030049 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF6255DF ++20150522030055 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF8EE01F ++20150522030059 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFAD237B ++20150522030104 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFD13587 ++20150522030105 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFD2BE6F ++20150522030108 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFECF32F ++20150522030112 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFFDEED7 ++20150522030115 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB01CAA63 ++20150522030116 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB01F3647 ++20150522030119 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB034B30F ++20150522030122 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB04822EF ++20150522030124 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0528867 ++20150522030131 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB08D3CAB ++20150522030136 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0B10C6F ++20150522030138 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0C688A7 ++20150522030140 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0CCDF9B ++20150522030141 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0CFD81B ++20150522030145 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0F59763 ++20150522030148 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB10339FB ++20150522030149 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB10E3ACB ++20150522030150 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB11127F3 ++20150522030159 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB15B8BDB + 20160301052556 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D19F4647 + 20160301052601 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1A5C13B + 20160301052612 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1B7A3EF +diff -up openssh-7.4p1/myproposal.h.legacy openssh-7.4p1/myproposal.h +--- openssh-7.4p1/myproposal.h.legacy 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/myproposal.h 2017-03-02 17:05:12.353352522 +0100 +@@ -96,34 +96,40 @@ + KEX_SHA2_METHODS + + #define KEX_SERVER_KEX KEX_COMMON_KEX \ ++ "diffie-hellman-group-exchange-sha1," \ + KEX_SHA2_GROUP14 \ +- "diffie-hellman-group14-sha1" \ ++ "diffie-hellman-group14-sha1," \ ++ "diffie-hellman-group1-sha1" + + #define KEX_CLIENT_KEX KEX_COMMON_KEX \ + "diffie-hellman-group-exchange-sha1," \ + KEX_SHA2_GROUP14 \ +- "diffie-hellman-group14-sha1" ++ "diffie-hellman-group14-sha1," \ ++ "diffie-hellman-group1-sha1" + + #define KEX_DEFAULT_PK_ALG \ + HOSTKEY_ECDSA_CERT_METHODS \ + "ssh-ed25519-cert-v01@openssh.com," \ + "ssh-rsa-cert-v01@openssh.com," \ ++ "ssh-dss-cert-v01@openssh.com," \ + HOSTKEY_ECDSA_METHODS \ + "ssh-ed25519," \ + "rsa-sha2-512," \ + "rsa-sha2-256," \ +- "ssh-rsa" ++ "ssh-rsa," \ ++ "ssh-dss" + + /* the actual algorithms */ + +-#define KEX_SERVER_ENCRYPT \ ++#define KEX_CLIENT_ENCRYPT \ + "chacha20-poly1305@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr" \ +- AESGCM_CIPHER_MODES +- +-#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \ ++ AESGCM_CIPHER_MODES "," \ + "aes128-cbc,aes192-cbc,aes256-cbc" + ++#define KEX_SERVER_ENCRYPT KEX_CLIENT_ENCRYPT "," \ ++ "blowfish-cbc,cast128-cbc,3des-cbc" ++ + #define KEX_SERVER_MAC \ + "umac-64-etm@openssh.com," \ + "umac-128-etm@openssh.com," \ +diff -up openssh-7.4p1/ssh_config.5.legacy openssh-7.4p1/ssh_config.5 +--- openssh-7.4p1/ssh_config.5.legacy 2017-03-02 17:00:37.620696010 +0100 ++++ openssh-7.4p1/ssh_config.5 2017-03-02 17:00:37.642695983 +0100 +@@ -833,8 +833,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, ++ssh-dss-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-ssh-ed25519,ssh-rsa ++ssh-ed25519,ssh-rsa,ssh-dss + .Ed + .Pp + The +@@ -856,8 +857,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, ++ssh-dss-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-ssh-ed25519,ssh-rsa ++ssh-ed25519,ssh-rsa,ssh-dss + .Ed + .Pp + If hostkeys are known for the destination host then this default is modified +@@ -1075,7 +1077,8 @@ curve25519-sha256,curve25519-sha256@libs + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, + diffie-hellman-group-exchange-sha256, + diffie-hellman-group-exchange-sha1, +-diffie-hellman-group14-sha1 ++diffie-hellman-group14-sha1, ++diffie-hellman-group1-sha1 + .Ed + .Pp + The list of available key exchange algorithms may also be obtained using +@@ -1313,8 +1316,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, ++ssh-dss-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-ssh-ed25519,ssh-rsa ++ssh-ed25519,ssh-rsa,ssh-dsa + .Ed + .Pp + The list of available key types may also be obtained using +diff -up openssh-7.4p1/sshd_config.5.legacy openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.legacy 2017-03-02 17:00:37.636695990 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-03-02 17:04:17.528421067 +0100 +@@ -481,7 +481,9 @@ 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-cbc,aes192-cbc,aes256-cbc, ++blowfish-cbc,cast128-cbc,3des-cbc + .Ed + .Pp + The list of available ciphers may also be obtained using +@@ -707,8 +709,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, ++ssh-dss-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-ssh-ed25519,ssh-rsa ++ssh-ed25519,ssh-rsa,ssh-dss + .Ed + .Pp + The list of available key types may also be obtained using +@@ -785,8 +788,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, ++ssh-dss-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-ssh-ed25519,ssh-rsa ++ssh-ed25519,ssh-rsa,ssh-dss + .Ed + .Pp + The list of available key types may also be obtained using +@@ -926,7 +930,8 @@ The default is: + curve25519-sha256,curve25519-sha256@libssh.org, + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, + diffie-hellman-group-exchange-sha256, +-diffie-hellman-group14-sha1 ++diffie-hellman-group14-sha1, ++diffie-hellman-group1-sha1 + .Ed + .Pp + The list of available key exchange algorithms may also be obtained using +@@ -1040,7 +1045,8 @@ umac-64-etm@openssh.com,umac-128-etm@ope + 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 ++hmac-sha2-256,hmac-sha2-512,hmac-sha1, ++hmac-sha1-etm@openssh.com + .Ed + .Pp + The list of available MAC algorithms may also be obtained using +@@ -1344,8 +1350,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-ed25519-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com, ++ssh-dss-cert-v01@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-ssh-ed25519,ssh-rsa ++ssh-ed25519,ssh-rsa,ssh-dss + .Ed + .Pp + The list of available key types may also be obtained using diff --git a/openssh-7.4p1-legacy-ssh-copy-id.patch b/openssh-7.4p1-legacy-ssh-copy-id.patch new file mode 100644 index 0000000..c6770ff --- /dev/null +++ b/openssh-7.4p1-legacy-ssh-copy-id.patch @@ -0,0 +1,36 @@ +diff -up openssh-7.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id openssh-7.4p1/contrib/ssh-copy-id.1 +--- openssh-7.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/contrib/ssh-copy-id.1 2017-02-09 09:23:25.366651136 +0100 +@@ -185,6 +185,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-7.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id openssh-7.4p1/contrib/ssh-copy-id +--- openssh-7.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id 2017-02-09 09:23:25.366651136 +0100 ++++ openssh-7.4p1/contrib/ssh-copy-id 2017-02-09 09:33:07.896518169 +0100 +@@ -99,6 +99,9 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L + GET_ID="ssh-add -L" + fi + ++# legacy environment variable implies forced copy ++[ "x$SSH_COPY_ID_LEGACY" != "x" ] && FORCED=1 ++ + while test "$#" -gt 0 + do + [ "${SEEN_OPT_I}" ] && expr "$1" : "[-]i" >/dev/null && { diff --git a/openssh-7.4p1-log-in-chroot.patch b/openssh-7.4p1-log-in-chroot.patch new file mode 100644 index 0000000..eedd198 --- /dev/null +++ b/openssh-7.4p1-log-in-chroot.patch @@ -0,0 +1,285 @@ +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 2017-02-09 09:51:07.571909000 +0100 +@@ -250,6 +250,11 @@ debug3(const char *fmt,...) + void + log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) + { ++ log_init_handler(av0, level, facility, on_stderr, 1); ++} ++ ++void ++log_init_handler(char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) { + #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) + struct syslog_data sdata = SYSLOG_DATA_INIT; + #endif +@@ -273,8 +278,10 @@ log_init(char *av0, LogLevel level, Sysl + exit(1); + } + +- log_handler = NULL; +- log_handler_ctx = NULL; ++ if (reset_handler) { ++ log_handler = NULL; ++ log_handler_ctx = NULL; ++ } + + log_on_stderr = on_stderr; + if (on_stderr) +diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h +--- openssh-7.4p1/log.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/log.h 2017-02-09 09:51:07.571909000 +0100 +@@ -49,6 +49,7 @@ typedef enum { + typedef void (log_handler_fn)(LogLevel, const char *, void *); + + void log_init(char *, LogLevel, SyslogFacility, int); ++void log_init_handler(char *, LogLevel, SyslogFacility, int, int); + void 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 2017-02-09 09:51:07.554909017 +0100 ++++ openssh-7.4p1/monitor.c 2017-02-09 10:05:21.067174230 +0100 +@@ -307,6 +307,8 @@ monitor_child_preauth(Authctxt *_authctx + close(pmonitor->m_log_sendfd); + pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; + ++ pmonitor->m_state = "preauth"; ++ + authctxt = _authctxt; + memset(authctxt, 0, sizeof(*authctxt)); + +@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p + close(pmonitor->m_recvfd); + pmonitor->m_recvfd = -1; + ++ pmonitor->m_state = "postauth"; ++ + monitor_set_child_handler(pmonitor->m_pid); + signal(SIGHUP, &monitor_child_handler); + signal(SIGTERM, &monitor_child_handler); +@@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito + if (log_level_name(level) == NULL) + fatal("%s: invalid log level %u (corrupted message?)", + __func__, level); +- do_log2(level, "%s [preauth]", msg); ++ do_log2(level, "%s [%s]", msg, pmonitor->m_state); + + buffer_free(&logmsg); + free(msg); +@@ -1719,13 +1723,28 @@ monitor_init(void) + mon = xcalloc(1, sizeof(*mon)); + monitor_openfds(mon, 1); + ++ mon->m_state = ""; ++ + return mon; + } + + void +-monitor_reinit(struct monitor *mon) ++monitor_reinit(struct monitor *mon, const char *chroot_dir) + { +- monitor_openfds(mon, 0); ++ struct stat dev_log_stat; ++ char *dev_log_path; ++ int do_logfds = 0; ++ ++ if (chroot_dir != NULL) { ++ xasprintf(&dev_log_path, "%s/dev/log", chroot_dir); ++ ++ if (stat(dev_log_path, &dev_log_stat) != 0) { ++ debug("%s: /dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", __func__, chroot_dir); ++ do_logfds = 1; ++ } ++ free(dev_log_path); ++ } ++ monitor_openfds(mon, do_logfds); + } + + #ifdef GSSAPI +diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h +--- openssh-7.4p1/monitor.h.log-in-chroot 2017-02-09 09:51:07.571909000 +0100 ++++ openssh-7.4p1/monitor.h 2017-02-09 10:05:49.792146561 +0100 +@@ -83,10 +83,11 @@ struct monitor { + int m_log_sendfd; + struct kex **m_pkex; + pid_t m_pid; ++ char *m_state; + }; + + struct monitor *monitor_init(void); +-void monitor_reinit(struct monitor *); ++void monitor_reinit(struct monitor *, const char *); + + struct Authctxt; + void monitor_child_preauth(struct 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 2017-02-09 09:51:07.570909002 +0100 ++++ openssh-7.4p1/session.c 2017-02-09 10:08:16.241005497 +0100 +@@ -160,6 +160,7 @@ login_cap_t *lc; + + static int is_child = 0; + static int in_chroot = 0; ++static int have_dev_log = 1; + + /* 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); + +@@ -619,6 +620,7 @@ do_exec(Session *s, const char *command) + int ret; + const char *forced = NULL, *tty = NULL; + char session_type[1024]; ++ struct stat dev_log_stat; + + if (options.adm_forced_command) { + original_command = command; +@@ -676,6 +678,10 @@ do_exec(Session *s, const char *command) + tty += 5; + } + ++ if (lstat("/dev/log", &dev_log_stat) != 0) { ++ have_dev_log = 0; ++ } ++ + verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", + session_type, + tty == NULL ? "" : " on ", +@@ -1490,14 +1496,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); + } + + /* +@@ -1633,8 +1631,6 @@ do_child(Session *s, const char *command + exit(1); + } + +- closefrom(STDERR_FILENO + 1); +- + do_rc_files(s, shell); + + /* restore SIGPIPE for child */ +@@ -1658,9 +1654,17 @@ do_child(Session *s, const char *command + argv[i] = NULL; + optind = optreset = 1; + __progname = argv[0]; +- exit(sftp_server_main(i, argv, s->pw)); ++ exit(sftp_server_main(i, argv, s->pw, have_dev_log)); + } + ++ /* ++ * Close any extra open file descriptors so that we don't have them ++ * hanging around in clients. Note that we want to do this after ++ * initgroups, because at least on Solaris 2.3 it leaves file ++ * descriptors open. ++ */ ++ closefrom(STDERR_FILENO + 1); ++ + fflush(NULL); + + /* Get the last component of the shell name. */ +diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h +--- openssh-7.4p1/sftp.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sftp.h 2017-02-09 09:51:07.572908999 +0100 +@@ -97,5 +97,5 @@ + + struct passwd; + +-int sftp_server_main(int, char **, struct passwd *); ++int sftp_server_main(int, char **, struct passwd *, int); + void sftp_server_cleanup_exit(int) __attribute__((noreturn)); +diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c +--- openssh-7.4p1/sftp-server.c.log-in-chroot 2017-02-09 09:51:07.572908999 +0100 ++++ openssh-7.4p1/sftp-server.c 2017-02-09 10:09:39.662925141 +0100 +@@ -1497,7 +1497,7 @@ sftp_server_usage(void) + } + + int +-sftp_server_main(int argc, char **argv, struct passwd *user_pw) ++sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler) + { + fd_set *rset, *wset; + int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; +@@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv, + + 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); + + pw = pwcopy(user_pw); + +@@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv, + } + } + +- log_init(__progname, log_level, log_facility, log_stderr); ++ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); + + /* + * On platforms where we can, avoid making /proc/self/{mem,maps} +diff -up openssh-7.4p1/sftp-server-main.c.log-in-chroot openssh-7.4p1/sftp-server-main.c +--- openssh-7.4p1/sftp-server-main.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/sftp-server-main.c 2017-02-09 09:51:07.572908999 +0100 +@@ -49,5 +49,5 @@ main(int argc, char **argv) + return 1; + } + +- return (sftp_server_main(argc, argv, user_pw)); ++ return (sftp_server_main(argc, argv, user_pw, 0)); + } +diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.log-in-chroot 2017-02-09 09:51:07.557909015 +0100 ++++ openssh-7.4p1/sshd.c 2017-02-09 09:51:07.573908998 +0100 +@@ -642,7 +642,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) +@@ -660,6 +660,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-7.4p1-newline-banner.patch b/openssh-7.4p1-newline-banner.patch new file mode 100644 index 0000000..32ff492 --- /dev/null +++ b/openssh-7.4p1-newline-banner.patch @@ -0,0 +1,22 @@ +diff -up openssh-7.4p1/sshd.c.newline-banner openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd.c.newline-banner 2017-02-17 14:00:47.237168594 +0100 ++++ openssh-7.4p1/sshd.c 2017-02-17 14:02:10.933096707 +0100 +@@ -369,15 +369,15 @@ sshd_exchange_identification(struct ssh + { + u_int i; + int remote_major, remote_minor; +- char *s, *newline = "\n"; ++ char *s; + char buf[256]; /* Must not be larger than remote_version. */ + 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, + (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, + *options.version_addendum == '\0' ? "" : " ", +- options.version_addendum, newline); ++ options.version_addendum); + + /* Send our protocol version identification. */ + if (atomicio(vwrite, sock_out, server_version_string, diff --git a/openssh-7.4p1-permit-root-login.patch b/openssh-7.4p1-permit-root-login.patch new file mode 100644 index 0000000..3689fdd --- /dev/null +++ b/openssh-7.4p1-permit-root-login.patch @@ -0,0 +1,36 @@ +diff -up openssh-7.4p1/servconf.c.permit-root openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.permit-root 2017-02-10 10:27:18.109487568 +0100 ++++ openssh-7.4p1/servconf.c 2017-02-10 10:28:12.385776132 +0100 +@@ -231,7 +231,7 @@ fill_default_server_options(ServerOption + if (options->login_grace_time == -1) + options->login_grace_time = 120; + if (options->permit_root_login == PERMIT_NOT_SET) +- options->permit_root_login = PERMIT_NO_PASSWD; ++ options->permit_root_login = PERMIT_YES; + if (options->ignore_rhosts == -1) + options->ignore_rhosts = 1; + if (options->ignore_user_known_hosts == -1) +diff -up openssh-7.4p1/sshd_config.5.permit-root openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.permit-root 2017-02-10 10:28:24.174605582 +0100 ++++ openssh-7.4p1/sshd_config.5 2017-02-10 10:28:42.254344023 +0100 +@@ -1227,7 +1227,7 @@ The argument must be + or + .Cm no . + The default is +-.Cm prohibit-password . ++.Cm yes . + .Pp + If this option is set to + .Cm prohibit-password +diff -up openssh-7.4p1/sshd_config.permit-root openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.permit-root 2017-02-10 10:26:52.256797645 +0100 ++++ openssh-7.4p1/sshd_config 2017-02-10 10:26:52.276797405 +0100 +@@ -35,7 +35,7 @@ SyslogFacility AUTHPRIV + # Authentication: + + #LoginGraceTime 2m +-#PermitRootLogin prohibit-password ++#PermitRootLogin yes + #StrictModes yes + #MaxAuthTries 6 + #MaxSessions 10 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/openssh-7.4p1-rekeying-timeouts.patch b/openssh-7.4p1-rekeying-timeouts.patch new file mode 100644 index 0000000..50e4257 --- /dev/null +++ b/openssh-7.4p1-rekeying-timeouts.patch @@ -0,0 +1,18 @@ +diff --git a/serverloop.c b/serverloop.c +index b5eb3440..1535eeb2 100644 +--- a/serverloop.c ++++ b/serverloop.c +@@ -225,9 +225,10 @@ wait_until_can_do_something(int connection_in, int connection_out, + uint64_t keepalive_ms = + (uint64_t)options.client_alive_interval * 1000; + +- client_alive_scheduled = 1; +- if (max_time_ms == 0 || max_time_ms > keepalive_ms) ++ if (max_time_ms == 0 || max_time_ms > keepalive_ms) { + max_time_ms = keepalive_ms; ++ client_alive_scheduled = 1; ++ } + } + + #if 0 + diff --git a/openssh-6.3p1-role-mls.patch b/openssh-7.4p1-role-mls.patch similarity index 61% rename from openssh-6.3p1-role-mls.patch rename to openssh-7.4p1-role-mls.patch index 89d54b3..75c1710 100644 --- a/openssh-6.3p1-role-mls.patch +++ b/openssh-7.4p1-role-mls.patch @@ -1,154 +1,7 @@ -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) - * 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-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 -@@ -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-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 -@@ -59,6 +59,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 */ - 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 -@@ -381,6 +381,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); -@@ -389,11 +392,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-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 - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - int authenticated = 0; -+ char *micuser; - Buffer b; - gss_buffer_desc mic, gssbuf; - u_int len; -@@ -268,7 +269,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); -@@ -280,6 +287,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-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) - 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-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) - } - /* 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 : "", -+ authctxt->role ? "/" : "", -+ authctxt->role ? authctxt->role : ""); - 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 -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 2017-02-08 14:08:30.271308186 +0100 +@@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 Authctxt *authctxt = ctxt; Authmethod *m = NULL; char *user, *service, *method, *style = NULL; @@ -158,7 +11,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 debug("userauth-request for user %s service %s method %s", user, service, method); debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); @@ -170,7 +23,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 use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -187,10 +40,119 @@ 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 -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 2017-02-08 14:08:30.270308187 +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 2017-02-08 14:08:30.270308187 +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 2017-02-08 14:08:30.270308187 +0100 +@@ -151,9 +151,11 @@ 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 : "", ++ authctxt->role ? "/" : "", ++ authctxt->role ? authctxt->role : ""); + 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 2017-02-08 14:08:30.270308187 +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 2017-02-08 14:08:30.270308187 +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 2017-02-08 14:08:30.270308187 +0100 ++++ openssh-7.4p1/auth-pam.h 2017-02-08 14:09:09.711273302 +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 2017-02-08 14:08:30.271308186 +0100 +@@ -432,6 +432,7 @@ char * colon(char *cp) { int flag = 0; @@ -198,7 +160,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) +@@ -447,6 +448,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -212,10 +174,10 @@ 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 -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 2017-02-08 14:18:13.289928913 +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 *); @@ -225,7 +187,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[] +@@ -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}, @@ -235,17 +197,17 @@ 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 - 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 -@@ -894,6 +903,25 @@ mm_answer_authserv(int sock, Buffer *m) +@@ -810,6 +819,25 @@ mm_answer_authserv(int sock, Buffer *m) return (0); } @@ -271,25 +233,25 @@ 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 - monitor_valid_userblob(u_char *data, u_int datalen) +@@ -1208,7 +1236,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; -@@ -1295,6 +1323,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++; - p = buffer_get_cstring(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) + cp = buffer_get_cstring(&b, NULL); ++ if ((r = strchr(cp, '/')) != NULL) + *r = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1330,7 +1360,7 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1269,7 +1299,7 @@ monitor_valid_hostbasedblob(u_char *data char *chost) { Buffer b; @@ -298,7 +260,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 +@@ -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); @@ -307,23 +269,24 @@ 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 -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 2017-02-08 14:08:30.271308186 +0100 +@@ -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 -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 2017-02-08 14:08:30.271308186 +0100 +@@ -345,6 +345,25 @@ mm_inform_authserv(char *service, char * buffer_free(&m); } @@ -349,12 +312,12 @@ 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 -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 *, 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 *); @@ -362,36 +325,122 @@ 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-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_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 @@ +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 2017-02-08 14:08:30.272308185 +0100 +@@ -101,37 +101,6 @@ ssh_selinux_getctxbyname(char *pwname) + return sc; + } - #include "log.h" - #include "xmalloc.h" +-/* 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) +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 2017-02-08 14:08:30.272308185 +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 2017-02-08 14:08:30.272308185 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2017-02-08 14:08:30.272308185 +0100 +@@ -0,0 +1,415 @@ ++/* ++ * 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 "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ +#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 +448,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 +456,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 +550,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 +573,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 +588,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 +596,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 +612,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 +662,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 +691,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 +708,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 +734,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 +765,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 +787,53 @@ 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); - } - --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 */ - - #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); ++ debug3("%s: done", __func__); +} + -+void -+ssh_selinux_setfscreatecon(const char *path) -+{ -+ security_context_t context; ++#endif ++#endif + -+ 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 -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 2017-02-08 14:08:30.272308185 +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-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 2017-02-08 14:08:30.273308184 +0100 +@@ -2053,6 +2053,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/openssh-7.4p1-rsa1-segfault.patch b/openssh-7.4p1-rsa1-segfault.patch new file mode 100644 index 0000000..1128800 --- /dev/null +++ b/openssh-7.4p1-rsa1-segfault.patch @@ -0,0 +1,19 @@ +diff --git a/sshd.c b/sshd.c +--- a/sshd.c ++++ b/sshd.c +@@ -1551,6 +1551,15 @@ main(int ac, char **av) + continue; + key = key_load_private(options.host_key_files[i], "", NULL); + pubkey = key_load_public(options.host_key_files[i], NULL); ++ ++ if ((pubkey != NULL && pubkey->type == KEY_RSA1) || ++ (key != NULL && key->type == KEY_RSA1)) { ++ verbose("Ignoring RSA1 key %s", ++ options.host_key_files[i]); ++ key_free(key); ++ key_free(pubkey); ++ continue; ++ } + if (pubkey == NULL && key != NULL) + pubkey = key_demote(key); + sensitive_data.host_keys[i] = key; diff --git a/openssh-7.4p1-sandbox-ibmca.patch b/openssh-7.4p1-sandbox-ibmca.patch new file mode 100644 index 0000000..c5a3d28 --- /dev/null +++ b/openssh-7.4p1-sandbox-ibmca.patch @@ -0,0 +1,211 @@ +From 5f1596e11d55539678c41f68aed358628d33d86f Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Tue, 14 Mar 2017 13:15:18 +1100 +Subject: [PATCH] support ioctls for ICA crypto card on Linux/s390 + +Based on patch from Eduardo Barretto; ok dtucker@ +--- + sandbox-seccomp-filter.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index af5525a..6ceee33 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -223,6 +223,12 @@ static const struct sock_filter preauth_insns[] = { + SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), + SC_DENY(socketcall, EACCES), + #endif ++#if defined(__NR_ioctl) && defined(__s390__) ++ /* Allow ioctls for ICA crypto card on s390 */ ++ SC_ALLOW_ARG(ioctl, 1, Z90STAT_STATUS_MASK), ++ SC_ALLOW_ARG(ioctl, 1, ICARSAMODEXPO), ++ SC_ALLOW_ARG(ioctl, 1, ICARSACRT), ++#endif /* defined(__NR_ioctl) && defined(__s390__) */ + + /* Default deny */ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), + +From 9e96b41682aed793fadbea5ccd472f862179fb02 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Tue, 14 Mar 2017 12:24:47 +1100 +Subject: [PATCH] Fix weakness in seccomp-bpf sandbox arg inspection + +Syscall arguments are passed via an array of 64-bit values in struct +seccomp_data, but we were only inspecting the bottom 32 bits and not +even those correctly for BE systems. + +Fortunately, the only case argument inspection was used was in the +socketcall filtering so using this for sandbox escape seems +impossible. + +ok dtucker +--- + sandbox-seccomp-filter.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 2e1ed2c..af5525a 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -73,6 +73,16 @@ + # define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP + #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + ++#if __BYTE_ORDER == __LITTLE_ENDIAN ++# define ARG_LO_OFFSET 0 ++# define ARG_HI_OFFSET sizeof(uint32_t) ++#elif __BYTE_ORDER == __BIG_ENDIAN ++# define ARG_LO_OFFSET sizeof(uint32_t) ++# define ARG_HI_OFFSET 0 ++#else ++#error "Unknown endianness" ++#endif ++ + /* Simple helpers to avoid manual errors (but larger BPF programs). */ + #define SC_DENY(_nr, _errno) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ +@@ -81,11 +91,17 @@ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) + #define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ +- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \ +- /* load first syscall argument */ \ ++ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 6), \ ++ /* load and test first syscall argument, low word */ \ ++ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ ++ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ ++ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ ++ ((_arg_val) & 0xFFFFFFFF), 0, 3), \ ++ /* load and test first syscall argument, high word */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ +- offsetof(struct seccomp_data, args[(_arg_nr)])), \ +- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \ ++ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ ++ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ ++ (((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ + /* reload syscall number; all rules expect it in accumulator */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + +From 58b8cfa2a062b72139d7229ae8de567f55776f24 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Wed, 22 Mar 2017 12:43:02 +1100 +Subject: [PATCH] Missing header on Linux/s390 + +Patch from Jakub Jelen +--- + sandbox-seccomp-filter.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index a8d472a..2831e9d 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -50,6 +50,9 @@ + #include + + #include ++#ifdef __s390__ ++#include ++#endif + + #include + #include + +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(getpid), + #endif ++#ifdef __NR_getuid ++ SC_ALLOW(getuid), ++#endif ++#ifdef __NR_getuid32 ++ SC_ALLOW(getuid32), ++#endif ++#ifdef __NR_geteuid ++ SC_ALLOW(geteuid), ++#endif ++#ifdef __NR_geteuid32 ++ SC_ALLOW(geteuid32), ++#endif + #ifdef __NR_getrandom + SC_ALLOW(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(ioctl, 1, Z90STAT_STATUS_MASK), + SC_ALLOW_ARG(ioctl, 1, ICARSAMODEXPO), + SC_ALLOW_ARG(ioctl, 1, ICARSACRT), ++ /* Allow ioctls for EP11 crypto card on s390 */ ++ SC_ALLOW_ARG(ioctl, 1, ZSENDEP11CPRB), + #endif /* defined(__NR_ioctl) && defined(__s390__) */ + + /* Default deny */ +-- +1.9.1 + +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(exit_group), + #endif ++#if defined(__NR_flock) && defined(__s390__) ++ SC_ALLOW(flock), ++#endif + #ifdef __NR_getpgid + SC_ALLOW(getpgid), + #endif +@@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = { + #ifdef __NR_gettimeofday + SC_ALLOW(gettimeofday), + #endif ++#if defined(__NR_ipc) && defined(__s390__) ++ SC_ALLOW(ipc), ++#endif + #ifdef __NR_madvise + SC_ALLOW(madvise), + #endif +-- +1.9.1 diff --git a/openssh-7.4p1-sandbox-ppc64le.patch b/openssh-7.4p1-sandbox-ppc64le.patch new file mode 100644 index 0000000..09eae99 --- /dev/null +++ b/openssh-7.4p1-sandbox-ppc64le.patch @@ -0,0 +1,11 @@ +diff -up openssh-7.4p1/sandbox-seccomp-filter.c.sandbox openssh-7.4p1/sandbox-seccomp-filter.c +--- openssh-7.4p1/sandbox-seccomp-filter.c.sandbox 2017-04-21 13:30:49.692650798 +0200 ++++ openssh-7.4p1/sandbox-seccomp-filter.c 2017-04-21 13:30:52.259647579 +0200 +@@ -215,6 +215,7 @@ static const struct sock_filter preauth_ + #endif + #ifdef __NR_socketcall + SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), ++ SC_DENY(socketcall, EACCES), + #endif + + /* Default deny */ diff --git a/openssh-7.4p1-sha2-signatures.patch b/openssh-7.4p1-sha2-signatures.patch new file mode 100644 index 0000000..951e641 --- /dev/null +++ b/openssh-7.4p1-sha2-signatures.patch @@ -0,0 +1,28 @@ +diff -up openssh-7.4p1/kex.c.sha2 openssh-7.4p1/kex.c +--- openssh-7.4p1/kex.c.sha2 2017-02-17 18:15:53.589835864 +0100 ++++ openssh-7.4p1/kex.c 2017-02-17 18:17:20.404781663 +0100 +@@ -379,21 +379,14 @@ static int + kex_send_ext_info(struct ssh *ssh) + { + int r; +- char *algs; + +- if ((algs = sshkey_alg_list(0, 1, ',')) == NULL) +- return SSH_ERR_ALLOC_FAIL; + if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || + (r = sshpkt_put_u32(ssh, 1)) != 0 || + (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 || +- (r = sshpkt_put_cstring(ssh, algs)) != 0 || ++ (r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 || + (r = sshpkt_send(ssh)) != 0) +- goto out; +- /* success */ +- r = 0; +- out: +- free(algs); +- return r; ++ return r; ++ return 0; + } + + int diff --git a/openssh-7.4p1-show-more-fingerprints.patch b/openssh-7.4p1-show-more-fingerprints.patch new file mode 100644 index 0000000..570f11c --- /dev/null +++ b/openssh-7.4p1-show-more-fingerprints.patch @@ -0,0 +1,315 @@ +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], +- 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); +@@ -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], +- 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); +@@ -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, +- options.fingerprint_hash)) != 0) ++ options.fingerprint_hash[0])) != 0) + error("%s: hostfile_replace_entries failed: %s", + __func__, ssh_err(r)); + } +@@ -2443,7 +2443,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-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: +- 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: +@@ -1905,7 +1907,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; +@@ -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; +- 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++] = (FIPS_mode() ? SSH_DIGEST_SHA1 : SSH_DIGEST_MD5); ++ } + 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 + } + + 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; +@@ -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); +- 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); +@@ -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); ++ dump_cfg_fmtarray(oFingerprintHash, o->num_fingerprint_hash, o->fingerprint_hash); + + /* 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 +@@ -21,6 +21,7 @@ + #define MAX_SEND_ENV 256 + #define SSH_MAX_HOSTS_FILES 32 + #define MAX_CANON_DOMAINS 32 ++#define MAX_SSH_DIGESTS 8 + #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) + + struct allowed_cname { +@@ -162,7 +163,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-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: + .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-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, +- 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); +@@ -966,12 +966,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) +@@ -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 < (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 */ +@@ -1244,7 +1250,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; +@@ -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, +- 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" +@@ -1457,7 +1463,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 -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) { +- 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.4p1-uidswap.patch b/openssh-7.4p1-uidswap.patch new file mode 100644 index 0000000..2ca18b5 --- /dev/null +++ b/openssh-7.4p1-uidswap.patch @@ -0,0 +1,50 @@ +From 26f96ca10ad0ec5da9b05b99de1e1ccea15a11be Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Fri, 15 Jun 2018 07:01:11 +0000 +Subject: [PATCH] upstream: invalidate supplemental group cache used by + +temporarily_use_uid() when the target uid differs; could cause failure to +read authorized_keys under some configurations. patch by Jakub Jelen via +bz2873; ok dtucker, markus + +OpenBSD-Commit-ID: 48a345f0ee90f6c465a078eb5e89566b23abd8a1 +--- + uidswap.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/uidswap.c b/uidswap.c +index 8bf6b244e..1430b822a 100644 +--- a/uidswap.c ++++ b/uidswap.c +@@ -49,6 +49,7 @@ static gid_t saved_egid = 0; + /* Saved effective uid. */ + static int privileged = 0; + static int temporarily_use_uid_effective = 0; ++static uid_t user_groups_uid; + static gid_t *saved_egroups = NULL, *user_groups = NULL; + static int saved_egroupslen = -1, user_groupslen = -1; + +@@ -92,10 +93,11 @@ temporarily_use_uid(struct passwd *pw) + fatal("getgroups: %.100s", strerror(errno)); + } else { /* saved_egroupslen == 0 */ + free(saved_egroups); ++ saved_egroups = NULL; + } + + /* set and save the user's groups */ +- if (user_groupslen == -1) { ++ if (user_groupslen == -1 || user_groups_uid != pw->pw_uid) { + if (initgroups(pw->pw_name, pw->pw_gid) < 0) + fatal("initgroups: %s: %.100s", pw->pw_name, + strerror(errno)); +@@ -110,7 +112,9 @@ temporarily_use_uid(struct passwd *pw) + fatal("getgroups: %.100s", strerror(errno)); + } else { /* user_groupslen == 0 */ + free(user_groups); ++ user_groups = NULL; + } ++ user_groups_uid = pw->pw_uid; + } + /* Set the effective uid to the given (unprivileged) uid. */ + if (setgroups(user_groupslen, user_groups) < 0) + diff --git a/openssh-7.4p1-usedns-yes.patch b/openssh-7.4p1-usedns-yes.patch new file mode 100644 index 0000000..492e9c0 --- /dev/null +++ b/openssh-7.4p1-usedns-yes.patch @@ -0,0 +1,46 @@ +Revert 3cd5103c1e1aaa59bd66f7f52f6ebbcd5deb12f9 + +diff --git a/servconf.c b/servconf.c +index 475076bf2..318546290 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -308,7 +308,7 @@ fill_default_server_options(ServerOptions *options) + if (options->max_sessions == -1) + options->max_sessions = DEFAULT_SESSIONS_MAX; + if (options->use_dns == -1) +- options->use_dns = 0; ++ options->use_dns = 1; + if (options->client_alive_interval == -1) + options->client_alive_interval = 0; + if (options->client_alive_count_max == -1) +diff --git a/sshd_config b/sshd_config +index e9045bc4d..c9042ac3c 100644 +--- a/sshd_config ++++ b/sshd_config +@@ -112,7 +112,7 @@ UsePrivilegeSeparation sandbox # Default for new installations. + #ClientAliveInterval 0 + #ClientAliveCountMax 3 + #ShowPatchLevel no +-#UseDNS no ++#UseDNS yes + #PidFile /var/run/sshd.pid + #MaxStartups 10:30:100 + #PermitTunnel no +diff --git a/sshd_config.5 b/sshd_config.5 +index 4fd93d68e..cf57c609f 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1379,10 +1379,12 @@ should look up the remote host name and check that + should look up the remote host name, and to check that + the resolved host name for the remote IP address maps back to the + very same IP address. ++The default is ++.Dq yes . + .Pp + If this option is set to + .Cm no +-(the default) then only addresses and not host names may be used in ++then only addresses and not host names may be used in + .Pa ~/.ssh/authorized_keys + .Cm from + and diff --git a/openssh-7.4p1-winscp-compat.patch b/openssh-7.4p1-winscp-compat.patch new file mode 100644 index 0000000..55fa6fc --- /dev/null +++ b/openssh-7.4p1-winscp-compat.patch @@ -0,0 +1,31 @@ +commit 2985d4062ebf4204bbd373456a810d558698f9f5 +Author: dtucker@openbsd.org +Date: Tue Jul 25 09:22:25 2017 +0000 + + upstream commit + + Make WinSCP patterns for SSH_OLD_DHGEX more specific to + exclude WinSCP 5.10.x and up. bz#2748, from martin at winscp.net, ok djm@ + + Upstream-ID: 6fd7c32e99af3952db007aa180e73142ddbc741a + +diff --git a/compat.c b/compat.c +index 156a5ea8..d82135e2 100644 +--- a/compat.c ++++ b/compat.c +@@ -177,9 +177,12 @@ compat_datafellows(const char *version) + "TTSSH/2.72*", SSH_BUG_HOSTKEYS }, + { "WinSCP_release_4*," + "WinSCP_release_5.0*," +- "WinSCP_release_5.1*," +- "WinSCP_release_5.5*," +- "WinSCP_release_5.6*," ++ "WinSCP_release_5.1," ++ "WinSCP_release_5.1.*," ++ "WinSCP_release_5.5," ++ "WinSCP_release_5.5.*," ++ "WinSCP_release_5.6," ++ "WinSCP_release_5.6.*," + "WinSCP_release_5.7," + "WinSCP_release_5.7.1," + "WinSCP_release_5.7.2," diff --git a/openssh-7.5p1-sftp-empty-files.patch b/openssh-7.5p1-sftp-empty-files.patch new file mode 100644 index 0000000..c32ad20 --- /dev/null +++ b/openssh-7.5p1-sftp-empty-files.patch @@ -0,0 +1,35 @@ +From 4d827f0d75a53d3952288ab882efbddea7ffadfe Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Tue, 4 Apr 2017 00:24:56 +0000 +Subject: [PATCH] upstream commit + +disallow creation (of empty files) in read-only mode; +reported by Michal Zalewski, feedback & ok deraadt@ + +Upstream-ID: 5d9c8f2fa8511d4ecf95322994ffe73e9283899b +--- + sftp-server.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sftp-server.c b/sftp-server.c +index 3619cdfc0..df0fb5068 100644 +--- a/sftp-server.c ++++ b/sftp-server.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: sftp-server.c,v 1.110 2016/09/12 01:22:38 deraadt Exp $ */ ++/* $OpenBSD: sftp-server.c,v 1.111 2017/04/04 00:24:56 djm Exp $ */ + /* + * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. + * +@@ -691,8 +691,8 @@ process_open(u_int32_t id) + logit("open \"%s\" flags %s mode 0%o", + name, string_from_portable(pflags), mode); + if (readonly && +- ((flags & O_ACCMODE) == O_WRONLY || +- (flags & O_ACCMODE) == O_RDWR)) { ++ ((flags & O_ACCMODE) != O_RDONLY || ++ (flags & (O_CREAT|O_TRUNC)) != 0)) { + verbose("Refusing open request in read-only mode"); + status = SSH2_FX_PERMISSION_DENIED; + } else { + 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..36bd6c4 --- /dev/null +++ b/openssh-8.7p1-upstream-cve-2021-41617.patch @@ -0,0 +1,25 @@ +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index b8d1040d..0134d694 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -56,6 +56,7 @@ + # include + #endif + #include ++#include + #include + #include + #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); ++ } + /* Don't use permanently_set_uid() here to avoid fatal() */ + if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { + error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, 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..6211473 --- /dev/null +++ b/openssh-9.3p1-upstream-cve-2023-38408.patch @@ -0,0 +1,17 @@ +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_id, 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; diff --git a/sources b/sources index a583b69..01c94ef 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -a62b88b884df0b09b8a8c5789ac9e51b openssh-6.4p1.tar.gz +SHA512 (openssh-7.4p1.tar.gz) = 4f3256f461f01366c5d5e0e45285eec65016e2643b3284b407f48f53d81087bf2c1caf7d5f7530d307a15c91c64de91446e1cba948e8fc68f82098290fe3b292