Compare commits
21 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adf6749248 | ||
|
|
658736fecc | ||
|
|
d9b07779a6 | ||
|
|
d9643d4abf | ||
|
|
ba7503ed34 | ||
|
|
0155cda587 | ||
|
|
897e3b92a6 | ||
|
|
c4d973523c | ||
|
|
a67ad5bbcf | ||
|
|
9575bd55d5 | ||
|
|
06a633eb7a | ||
|
|
68d8f4ac90 | ||
|
|
53bc8ae15d | ||
|
|
9c88d73924 | ||
|
|
149f61dfaa | ||
|
|
146f9b28f3 | ||
|
|
4f44809b0b | ||
|
|
8e86bdb410 | ||
|
|
775e7f8a14 | ||
|
|
c2bba13c4a | ||
|
|
b17edf9dcf |
77 changed files with 16273 additions and 15763 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,4 +1,4 @@
|
|||
/*.tar.bz2
|
||||
/*.tar.gz
|
||||
/*.tar.gz.asc
|
||||
/DJM-GPG-KEY.gpg
|
||||
/*.gpg
|
||||
|
|
|
|||
283
gsi-openssh.spec
283
gsi-openssh.spec
|
|
@ -30,8 +30,8 @@
|
|||
# Do we want LDAP support
|
||||
%global ldap 1
|
||||
|
||||
%global openssh_ver 7.8p1
|
||||
%global openssh_rel 1
|
||||
%global openssh_ver 8.0p1
|
||||
%global openssh_rel 16
|
||||
|
||||
Summary: An implementation of the SSH protocol with GSI authentication
|
||||
Name: gsi-openssh
|
||||
|
|
@ -56,11 +56,6 @@ Source99: README.sshd-and-gsisshd
|
|||
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=2581
|
||||
Patch100: openssh-6.7p1-coverity.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1894
|
||||
#https://bugzilla.redhat.com/show_bug.cgi?id=735889
|
||||
#Patch102: openssh-5.8p1-getaddrinfo.patch
|
||||
# OpenSSL 1.1.0 compatibility
|
||||
Patch104: openssh-7.3p1-openssl-1.1.0.patch
|
||||
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1171248
|
||||
|
|
@ -98,8 +93,6 @@ Patch702: openssh-5.1p1-askpass-progress.patch
|
|||
Patch703: openssh-4.3p2-askpass-grab-info.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
|
||||
Patch707: openssh-7.7p1-redhat.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX)
|
||||
Patch709: openssh-6.2p1-vendor.patch
|
||||
# warn users for unsupported UsePAM=no (#757545)
|
||||
Patch711: openssh-7.8p1-UsePAM-warning.patch
|
||||
# make aes-ctr ciphers use EVP engines such as AES-NI from OpenSSL
|
||||
|
|
@ -109,26 +102,20 @@ Patch713: openssh-6.6p1-ctr-cavstest.patch
|
|||
# add SSH KDF CAVS test driver
|
||||
Patch714: openssh-6.7p1-kdf-cavs.patch
|
||||
|
||||
#http://www.sxw.org.uk/computing/patches/openssh.html
|
||||
#changed cache storage type - #848228
|
||||
Patch800: openssh-7.8p1-gsskex.patch
|
||||
# GSSAPI Key Exchange (RFC 4462 + draft-ietf-curdle-gss-keyex-sha2-08)
|
||||
# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
|
||||
Patch800: openssh-8.0p1-gssapi-keyex.patch
|
||||
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
|
||||
Patch801: openssh-6.6p1-force_krb.patch
|
||||
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
|
||||
# CVE-2014-9278
|
||||
Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch
|
||||
# Documentation about GSSAPI
|
||||
# from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765655
|
||||
Patch803: openssh-7.1p1-gssapi-documentation.patch
|
||||
# Improve ccache handling in openssh (#991186, #1199363, #1566494)
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=2775
|
||||
Patch804: openssh-7.7p1-gssapi-new-unique.patch
|
||||
# Respect k5login_directory option in krk5.conf (#1328243)
|
||||
Patch805: openssh-7.2p2-k5login_directory.patch
|
||||
# Support SHA2 in GSS key exchanges from draft-ssorce-gss-keyex-sha2-02
|
||||
Patch807: openssh-7.5p1-gssapi-kex-with-ec.patch
|
||||
|
||||
Patch900: openssh-6.1p1-gssapi-canohost.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
|
||||
Patch901: openssh-6.6p1-kuserok.patch
|
||||
# Use tty allocation for a remote scp (#985650)
|
||||
|
|
@ -139,16 +126,12 @@ Patch916: openssh-6.6.1p1-selinux-contexts.patch
|
|||
Patch918: openssh-6.6.1p1-log-in-chroot.patch
|
||||
# scp file into non-existing directory (#1142223)
|
||||
Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch
|
||||
# Config parser shouldn't accept ip/port syntax (#1130733)
|
||||
Patch920: openssh-7.8p1-ip-port-config-parser.patch
|
||||
# apply upstream patch and make sshd -T more consistent (#1187521)
|
||||
Patch922: openssh-6.8p1-sshdT-output.patch
|
||||
# Add sftp option to force mode of created files (#1191055)
|
||||
Patch926: openssh-6.7p1-sftp-force-permission.patch
|
||||
# Restore compatible default (#89216)
|
||||
Patch929: openssh-6.9p1-permit-root-login.patch
|
||||
# Add GSSAPIKexAlgorithms option for server and client application
|
||||
Patch932: openssh-7.0p1-gssKexAlgorithms.patch
|
||||
# make s390 use /dev/ crypto devices -- ignore closefrom
|
||||
Patch939: openssh-7.2p2-s390-closefrom.patch
|
||||
# Move MAX_DISPLAYS to a configuration option (#1341302)
|
||||
|
|
@ -160,15 +143,110 @@ Patch949: openssh-7.6p1-cleanup-selinux.patch
|
|||
# Sandbox adjustments for s390 and audit
|
||||
Patch950: openssh-7.5p1-sandbox.patch
|
||||
# PKCS#11 URIs (upstream #2817, 2nd iteration)
|
||||
Patch951: openssh-7.6p1-pkcs11-uri.patch
|
||||
# PKCS#11 ECDSA keys (upstream #2474, 8th iteration)
|
||||
Patch952: openssh-7.6p1-pkcs11-ecdsa.patch
|
||||
Patch951: openssh-8.0p1-pkcs11-uri.patch
|
||||
# Unbreak scp between two IPv6 hosts (#1620333)
|
||||
Patch953: openssh-7.8p1-scp-ipv6.patch
|
||||
# ssh-copy-id is unmaintained: Aggreagete patches
|
||||
# - do not return 0 if the write fails (full disk)
|
||||
# - shellcheck reports (upstream #2902)
|
||||
Patch958: openssh-7.9p1-ssh-copy-id.patch
|
||||
# Verify the SCP vulnerabilities are fixed in the package testsuite
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=3007
|
||||
Patch961: openssh-8.0p1-scp-tests.patch
|
||||
# Mention crypto-policies in manual pages (#1668325)
|
||||
Patch962: openssh-8.0p1-crypto-policies.patch
|
||||
# Use OpenSSL high-level API to produce and verify signatures (#1707485)
|
||||
Patch963: openssh-8.0p1-openssl-evp.patch
|
||||
# Use OpenSSL KDF (#1631761)
|
||||
Patch964: openssh-8.0p1-openssl-kdf.patch
|
||||
# Use new OpenSSL for PEM export to avoid MD5 dependency (#1712436)
|
||||
Patch965: openssh-8.0p1-openssl-pem.patch
|
||||
# Seed from dev/random if requested (#1785655)
|
||||
Patch966: openssh-8.0p1-entropy.patch
|
||||
# Unbreak ssh-keyscan RSA keys without SHA1 (#1744108)
|
||||
Patch967: openssh-8.0p1-keyscan-rsa-sha2.patch
|
||||
# Detect proxyJump loops in configuration files (#1804099)
|
||||
Patch968: openssh-8.0p1-proxyjump-loops.patch
|
||||
# ssh-keygen should default to SHA2-based signature algorithm (#1790610)
|
||||
Patch969: openssh-8.0p1-keygen-sha2.patch
|
||||
# RDomain is not suported on non-OpenBSD (#1807686)
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=3126
|
||||
Patch970: openssh-8.0p1-rdomain.patch
|
||||
# Do not fail X11 forwarding if IPv6 is disabled (#1662189)
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=2143
|
||||
Patch971: openssh-8.0p1-x11-without-ipv6.patch
|
||||
# Client window fix (#1913041)
|
||||
Patch972: openssh-8.0p1-channel-limits.patch
|
||||
# SFTP sort upon the modification time (#1909988)
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=3248
|
||||
Patch973: openssh-8.0p1-sftp-timespeccmp.patch
|
||||
# ssh-keygen printing fingerprint issue with Windows keys (#1901518)
|
||||
Patch974: openssh-8.0p1-keygen-strip-doseol.patch
|
||||
# sshd provides PAM an incorrect error code (#1879503)
|
||||
Patch975: openssh-8.0p1-preserve-pam-errors.patch
|
||||
# ssh incorrectly restores the blocking mode on standard output (#1942901)
|
||||
Patch976: openssh-8.0p1-restore-nonblock.patch
|
||||
# CVE 2020-14145
|
||||
Patch977: openssh-8.0p1-cve-2020-14145.patch
|
||||
# sshd -T requires -C when "Match" is used in sshd_config (#1836277)
|
||||
Patch978: openssh-8.0p1-sshd_config.patch
|
||||
# CVE-2021-41617
|
||||
Patch980: openssh-8.7p1-upstream-cve-2021-41617.patch
|
||||
# support sshd Include directive
|
||||
# upstream commits:
|
||||
# c2bd7f74b0e0f3a3ee9d19ac549e6ba89013abaf~1..677d0ece67634262b3b96c3cd6410b19f3a603b7
|
||||
# 8bdc3bb7cf4c82c3344cfcb82495a43406e87e83
|
||||
# 47adfdc07f4f8ea0064a1495500244de08d311ed~1..7af1e92cd289b7eaa9a683e9a6f2fddd98f37a01
|
||||
# supplementary commit 612b1dd1ec91ffb1e01f58cca0c6eb1d47bf4423
|
||||
Patch981: openssh-8.0p1-sshd_include.patch
|
||||
# Port upstream ClientAliveCountMax behaviour
|
||||
# upstream commit:
|
||||
# 69334996ae203c51c70bf01d414c918a44618f8e
|
||||
Patch982: openssh-8.0p1-client_alive_count_max.patch
|
||||
# add a local implementation of BSD realpath() for sftp-server
|
||||
# use ahead of OpenBSD's realpath changing to match POSIX
|
||||
# upstream commits:
|
||||
# 569b650f93b561c09c655f83f128e1dfffe74101
|
||||
# 53a6ebf1445a857f5e487b18ee5e5830a9575149
|
||||
# 5428b0d239f6b516c81d1dd15aa9fe9e60af75d4
|
||||
Patch983: openssh-8.0p1-sftp-realpath.patch
|
||||
# include caveat for crypto-policy in sshd manpage (#2044354)
|
||||
Patch984: openssh-8.0p1-crypto-policy-doc.patch
|
||||
# minimize the use of SHA1 as a proof of possession for RSA key (#2093897)
|
||||
# upstream commits:
|
||||
# 291721bc7c840d113a49518f3fca70e86248b8e8
|
||||
# 0fa33683223c76289470a954404047bc762be84c
|
||||
# f8df0413f0a057b6a3d3dd7bd8bc7c5d80911d3a
|
||||
Patch985: openssh-8.7p1-minimize-sha1-use.patch
|
||||
# Upstream ff89b1bed80721295555bd083b173247a9c0484e
|
||||
Patch986: openssh-9.1p1-sshbanner.patch
|
||||
# Upstream 25e3bccbaa63d27b9d5e09c123f1eb28594d2bd6
|
||||
Patch987: openssh-8.0p1-ipv6-process.patch
|
||||
# Upstream 4332b4fe49360679647a8705bc08f4e81323f6b4
|
||||
Patch988: openssh-8.0p1-avoidkillall.patch
|
||||
# Upstream 89b54900ac61986760452f132bbe3fb7249cfdac
|
||||
Patch989: openssh-8.0p1-bigsshdconfig.patch
|
||||
# upsream commit
|
||||
# b23fe83f06ee7e721033769cfa03ae840476d280
|
||||
Patch1015: openssh-9.3p1-upstream-cve-2023-38408.patch
|
||||
#upstream commit 01dbf3d46651b7d6ddf5e45d233839bbfffaeaec
|
||||
Patch1017: openssh-9.4p2-limit-delay.patch
|
||||
#upstream commit 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5
|
||||
Patch1018: openssh-9.6p1-CVE-2023-48795.patch
|
||||
#upstream commit 7ef3787c84b6b524501211b11a26c742f829af1a
|
||||
Patch1019: openssh-9.6p1-CVE-2023-51385.patch
|
||||
# SCP kill switch
|
||||
Patch1020: openssh-8.7p1-scp-kill-switch.patch
|
||||
#upstream commit 96faa0de6c673a2ce84736eba37fc9fb723d9e5c
|
||||
Patch1021: openssh-8.0p1-upstream-ignore-SIGPIPE.patch
|
||||
|
||||
# This is the patch that adds GSI support
|
||||
# Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream
|
||||
Patch98: openssh-7.8p1-gsissh.patch
|
||||
Patch98: openssh-8.0p1-gsissh.patch
|
||||
|
||||
# This is the HPN patch
|
||||
# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-8_0_P1 (hpn14v19)
|
||||
Patch99: openssh-8.0p1-hpn-14.19.patch
|
||||
|
||||
License: BSD
|
||||
Group: Applications/Internet
|
||||
|
|
@ -182,7 +260,6 @@ BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel
|
|||
BuildRequires: audit-libs-devel >= 2.0.5
|
||||
BuildRequires: util-linux, groff
|
||||
BuildRequires: pam-devel
|
||||
BuildRequires: fipscheck-devel >= 1.3.0
|
||||
BuildRequires: openssl-devel >= 0.9.8j
|
||||
BuildRequires: systemd-devel
|
||||
BuildRequires: gcc
|
||||
|
|
@ -197,7 +274,6 @@ BuildRequires: krb5-devel
|
|||
BuildRequires: globus-gss-assist-devel >= 8
|
||||
BuildRequires: globus-gssapi-gsi-devel >= 12.12
|
||||
BuildRequires: globus-common-devel >= 14
|
||||
BuildRequires: globus-usage-devel >= 3
|
||||
%endif
|
||||
|
||||
%if %{libedit}
|
||||
|
|
@ -221,7 +297,6 @@ Provides: gsissh-clients = %{version}-%{release}
|
|||
Obsoletes: gsissh-clients < 5.8p2-2
|
||||
Group: Applications/Internet
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
Requires: fipscheck-lib%{_isa} >= 1.3.0
|
||||
Requires: crypto-policies >= 20180306-1
|
||||
|
||||
%package server
|
||||
|
|
@ -232,7 +307,6 @@ Group: System Environment/Daemons
|
|||
Requires: %{name} = %{version}-%{release}
|
||||
Requires(pre): /usr/sbin/useradd
|
||||
Requires: pam >= 1.0.1-3
|
||||
Requires: fipscheck-lib%{_isa} >= 1.3.0
|
||||
Requires: crypto-policies >= 20180306-1
|
||||
%{?systemd_requires}
|
||||
|
||||
|
|
@ -271,8 +345,6 @@ This version of OpenSSH has been modified to support GSI authentication.
|
|||
gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
|
||||
%setup -q -n openssh-%{version}
|
||||
|
||||
# investigate %%patch102 -p1 -b .getaddrinfo
|
||||
|
||||
%patch400 -p1 -b .role-mls
|
||||
%patch404 -p1 -b .privsep-selinux
|
||||
|
||||
|
|
@ -290,7 +362,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
|
|||
%patch702 -p1 -b .progress
|
||||
%patch703 -p1 -b .grab-info
|
||||
%patch707 -p1 -b .redhat
|
||||
%patch709 -p1 -b .vendor
|
||||
%patch711 -p1 -b .log-usepam-no
|
||||
%patch712 -p1 -b .evp-ctr
|
||||
%patch713 -p1 -b .ctr-cavs
|
||||
|
|
@ -298,44 +369,74 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
|
|||
|
||||
%patch800 -p1 -b .gsskex
|
||||
%patch801 -p1 -b .force_krb
|
||||
%patch803 -p1 -b .gss-docs
|
||||
%patch804 -p1 -b .ccache_name
|
||||
%patch805 -p1 -b .k5login
|
||||
|
||||
%patch900 -p1 -b .canohost
|
||||
%patch901 -p1 -b .kuserok
|
||||
%patch906 -p1 -b .fromto-remote
|
||||
%patch916 -p1 -b .contexts
|
||||
%patch918 -p1 -b .log-in-chroot
|
||||
%patch919 -p1 -b .scp
|
||||
%patch920 -p1 -b .config
|
||||
%patch802 -p1 -b .GSSAPIEnablek5users
|
||||
%patch922 -p1 -b .sshdt
|
||||
%patch926 -p1 -b .sftp-force-mode
|
||||
%patch929 -p1 -b .root-login
|
||||
%patch932 -p1 -b .gsskexalg
|
||||
%patch939 -p1 -b .s390-dev
|
||||
%patch944 -p1 -b .x11max
|
||||
%patch948 -p1 -b .systemd
|
||||
%patch807 -p1 -b .gsskex-ec
|
||||
%patch949 -p1 -b .refactor
|
||||
%patch950 -p1 -b .sandbox
|
||||
%patch951 -p1 -b .pkcs11-uri
|
||||
%patch952 -p1 -b .pkcs11-ecdsa
|
||||
%patch953 -p1 -b .scp-ipv6
|
||||
%patch958 -p1 -b .ssh-copy-id
|
||||
%patch961 -p1 -b .scp-tests
|
||||
%patch962 -p1 -b .crypto-policies
|
||||
%patch963 -p1 -b .openssl-evp
|
||||
%patch964 -p1 -b .openssl-kdf
|
||||
%patch965 -p1 -b .openssl-pem
|
||||
%patch966 -p1 -b .entropy
|
||||
%patch967 -p1 -b .keyscan
|
||||
%patch968 -p1 -b .proxyjump-loops
|
||||
%patch969 -p1 -b .keygen-sha2
|
||||
%patch970 -p1 -b .rdomain
|
||||
%patch971 -p1 -b .x11-ipv6
|
||||
%patch972 -p1 -b .channel-limits
|
||||
%patch973 -p1 -b .sftp-timespeccmp
|
||||
%patch974 -p1 -b .keygen-strip-doseol
|
||||
%patch975 -p1 -b .preserve-pam-errors
|
||||
%patch976 -p1 -b .restore-nonblock
|
||||
%patch977 -p1 -b .cve-2020-14145
|
||||
%patch978 -p1 -b .sshd_config
|
||||
%patch980 -p1 -b .cve-2021-41617
|
||||
%patch981 -p1 -b .sshdinclude
|
||||
%patch982 -p1 -b .client_alive_count_max
|
||||
%patch983 -p1 -b .sftp-realpath
|
||||
%patch984 -p1 -b .crypto-policy-doc
|
||||
%patch985 -p1 -b .minimize-sha1-use
|
||||
%patch986 -p1 -b .banner
|
||||
%patch987 -p1 -b .sftp_ipv6
|
||||
%patch988 -p1 -b .killall
|
||||
%patch989 -p1 -b .bigsshdconfig
|
||||
|
||||
%patch200 -p1 -b .audit
|
||||
%patch201 -p1 -b .audit-race
|
||||
%patch700 -p1 -b .fips
|
||||
|
||||
%patch100 -p1 -b .coverity
|
||||
%patch104 -p1 -b .openssl
|
||||
|
||||
%patch1015 -p1 -b .cve-2023-38408
|
||||
%patch1017 -p1 -b .limitdelay
|
||||
%patch1018 -p1 -b .cve-2023-48795
|
||||
%patch1019 -p1 -b .cve-2023-51385
|
||||
%patch1020 -p1 -b .scp-kill-switch
|
||||
%patch1021 -p1 -b .ignore-SIGPIPE
|
||||
|
||||
%patch98 -p1 -b .gsi
|
||||
%patch99 -p1 -b .hpn
|
||||
|
||||
sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h
|
||||
sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in
|
||||
sed 's!/etc/sysconfig/sshd!/etc/sysconfig/gsisshd!' -i sshd_config
|
||||
sed 's!/etc/pam.d/ssh!/etc/pam.d/gsisshd!' -i sshd_config
|
||||
|
||||
cp -p %{SOURCE99} .
|
||||
|
||||
|
|
@ -375,10 +476,9 @@ fi
|
|||
--sysconfdir=%{_sysconfdir}/gsissh \
|
||||
--libexecdir=%{_libexecdir}/gsissh \
|
||||
--datadir=%{_datadir}/gsissh \
|
||||
--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-%{openssh_ver}-%{openssh_rel}" \
|
||||
--with-default-path=%{_libexecdir}/gsissh/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \
|
||||
--with-superuser-path=%{_libexecdir}/gsissh/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \
|
||||
--with-privsep-path=%{_var}/empty/sshd \
|
||||
--disable-strip \
|
||||
--without-zlib-version-check \
|
||||
--with-ssl-engine \
|
||||
|
|
@ -391,6 +491,7 @@ fi
|
|||
--with-ldap \
|
||||
%endif
|
||||
--with-pam \
|
||||
--with-pam-service=gsisshd \
|
||||
%if %{WITH_SELINUX}
|
||||
--with-selinux --with-audit=linux \
|
||||
--with-sandbox=seccomp_filter \
|
||||
|
|
@ -414,27 +515,18 @@ fi
|
|||
make SSH_PROGRAM=%{_bindir}/gsissh \
|
||||
ASKPASS_PROGRAM=%{_libexecdir}/openssh/ssh-askpass
|
||||
|
||||
# Add generation of HMAC checksums of the final stripped binaries
|
||||
%global __spec_install_post \
|
||||
%%{?__debug_package:%%{__debug_install_post}} \
|
||||
%%{__arch_install_post} \
|
||||
%%{__os_install_post} \
|
||||
fipshmac -d $RPM_BUILD_ROOT%{_libdir}/fipscheck $RPM_BUILD_ROOT%{_bindir}/gsissh $RPM_BUILD_ROOT%{_sbindir}/gsisshd \
|
||||
%{nil}
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/gsissh
|
||||
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/ssh_config.d
|
||||
mkdir -p -m755 $RPM_BUILD_ROOT%{_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
|
||||
|
||||
install -d $RPM_BUILD_ROOT/etc/pam.d/
|
||||
install -d $RPM_BUILD_ROOT/etc/sysconfig/
|
||||
install -d $RPM_BUILD_ROOT%{_libexecdir}/gsissh
|
||||
install -d $RPM_BUILD_ROOT%{_libdir}/fipscheck
|
||||
install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/gsisshd
|
||||
install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/sysconfig/gsisshd
|
||||
install -m644 ssh_config_redhat $RPM_BUILD_ROOT/etc/gsissh/ssh_config.d/05-redhat.conf
|
||||
|
|
@ -470,6 +562,11 @@ for f in $RPM_BUILD_ROOT%{_bindir}/* \
|
|||
mv $f `dirname $f`/gsi`basename $f`
|
||||
done
|
||||
|
||||
# Add scp symlink in gsisshd's path
|
||||
mkdir $RPM_BUILD_ROOT%{_libexecdir}/gsissh/bin
|
||||
ln -nrs $RPM_BUILD_ROOT%{_bindir}/gsiscp \
|
||||
$RPM_BUILD_ROOT%{_libexecdir}/gsissh/bin/scp
|
||||
|
||||
perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/*
|
||||
|
||||
%pre
|
||||
|
|
@ -491,19 +588,18 @@ getent passwd sshd >/dev/null || \
|
|||
%systemd_postun_with_restart gsisshd.service
|
||||
|
||||
%files
|
||||
%license LICENCE LICENSE.globus_usage
|
||||
%doc CREDITS ChangeLog INSTALL OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO
|
||||
%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(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli
|
||||
%attr(0755,root,root) %{_bindir}/gsissh-keygen
|
||||
%attr(0644,root,root) %{_mandir}/man1/gsissh-keygen.1*
|
||||
%attr(0755,root,root) %dir %{_libexecdir}/gsissh
|
||||
%attr(2755,root,ssh_keys) %{_libexecdir}/gsissh/ssh-keysign
|
||||
%attr(2555,root,ssh_keys) %{_libexecdir}/gsissh/ssh-keysign
|
||||
%attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8*
|
||||
|
||||
%files clients
|
||||
%attr(0755,root,root) %{_bindir}/gsissh
|
||||
%attr(0644,root,root) %{_libdir}/fipscheck/gsissh.hmac
|
||||
%attr(0644,root,root) %{_mandir}/man1/gsissh.1*
|
||||
%attr(0755,root,root) %{_bindir}/gsiscp
|
||||
%attr(0644,root,root) %{_mandir}/man1/gsiscp.1*
|
||||
|
|
@ -513,11 +609,12 @@ getent passwd sshd >/dev/null || \
|
|||
%attr(0644,root,root) %{_mandir}/man5/gsissh_config.5*
|
||||
%attr(0755,root,root) %{_bindir}/gsisftp
|
||||
%attr(0644,root,root) %{_mandir}/man1/gsisftp.1*
|
||||
%attr(0755,root,root) %dir %{_libexecdir}/gsissh/bin
|
||||
%{_libexecdir}/gsissh/bin/scp
|
||||
|
||||
%files server
|
||||
%dir %attr(0711,root,root) %{_var}/empty/gsisshd
|
||||
%dir %attr(0711,root,root) %{_var}/empty/sshd
|
||||
%attr(0755,root,root) %{_sbindir}/gsisshd
|
||||
%attr(0644,root,root) %{_libdir}/fipscheck/gsisshd.hmac
|
||||
%attr(0755,root,root) %{_libexecdir}/gsissh/sftp-server
|
||||
%attr(0755,root,root) %{_libexecdir}/gsissh/sshd-keygen
|
||||
%attr(0644,root,root) %{_mandir}/man5/gsisshd_config.5*
|
||||
|
|
@ -535,6 +632,70 @@ getent passwd sshd >/dev/null || \
|
|||
%attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf
|
||||
|
||||
%changelog
|
||||
* Wed Oct 02 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-16
|
||||
- Based on openssh-8.0p1-25.el8_10
|
||||
|
||||
* Fri Jul 12 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-15
|
||||
- Add scp symlink in gsisshd's path
|
||||
|
||||
* Tue Jul 09 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-14
|
||||
- Based on openssh-8.0p1-24.el8
|
||||
- Drop patch openssh-8.0p1-sshbuf-readonly.patch (now included in
|
||||
openssh-8.0p1-gssapi-keyex.patch)
|
||||
|
||||
* Fri Aug 11 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-13
|
||||
- Based on openssh-8.0p1-19.el8_8
|
||||
|
||||
* Sat Mar 11 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-12
|
||||
- Based on openssh-8.0p1-17.el8_7
|
||||
|
||||
* Wed Oct 05 2022 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-11
|
||||
- Based on openssh-8.0p1-16.el8
|
||||
|
||||
* Tue Aug 09 2022 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-10
|
||||
- Based on openssh-8.0p1-13.el8
|
||||
|
||||
* Wed Nov 24 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-9
|
||||
- Based on openssh-8.0p1-10.el8
|
||||
|
||||
* Sat May 22 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-8
|
||||
- Based on openssh-8.0p1-6.el8_4.2
|
||||
|
||||
* Tue Mar 16 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-7
|
||||
- Fix issue with read-only ssh buffer during gssapi key exchange
|
||||
- Clean up HPN patch
|
||||
|
||||
* Mon Nov 30 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-6
|
||||
- Based on openssh-8.0p1-5.el8
|
||||
|
||||
* Fri Oct 23 2020 Frank Scheiner <scheiner@hlrs.de> - 8.0p1-5
|
||||
- Update HPN patch with additional documentation and configuration and a
|
||||
version number fix
|
||||
|
||||
* Fri Sep 25 2020 Frank Scheiner <scheiner@hlrs.de> - 8.0p1-4
|
||||
- Add HPN patch
|
||||
|
||||
* Mon May 04 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-3
|
||||
- Add missing buffer initialization in gsissh patch
|
||||
|
||||
* Tue Apr 14 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-2
|
||||
- Based on openssh-8.0p1-4.el8
|
||||
|
||||
* Wed Jan 08 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.0p1-1
|
||||
- Based on openssh-8.0p1-3.el8
|
||||
|
||||
* Mon Aug 19 2019 Mattias Ellert <mattias.ellert@physics.uu.se> - 7.8p1-5
|
||||
- Based on openssh-7.8p1-4.el8
|
||||
|
||||
* Wed Feb 27 2019 Mattias Ellert <mattias.ellert@physics.uu.se> - 7.8p1-4
|
||||
- Remove usage statistics collection support
|
||||
|
||||
* Fri Feb 08 2019 Mattias Ellert <mattias.ellert@physics.uu.se> - 7.8p1-3
|
||||
- CVE-2019-7639
|
||||
|
||||
* Tue Jan 15 2019 Mattias Ellert <mattias.ellert@physics.uu.se> - 7.8p1-2
|
||||
- Based on openssh-7.8p1-4.fc28
|
||||
|
||||
* Tue Oct 23 2018 Mattias Ellert <mattias.ellert@physics.uu.se> - 7.8p1-1
|
||||
- Based on openssh-7.8p1-3.fc28
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@
|
|||
# of DSA key or systemctl mask gsisshd-keygen@rsa.service to disable RSA key
|
||||
# creation.
|
||||
|
||||
# Do not change this option unless you have hardware random
|
||||
# generator and you REALLY know what you are doing
|
||||
|
||||
SSH_USE_STRONG_RNG=0
|
||||
# SSH_USE_STRONG_RNG=1
|
||||
|
||||
# System-wide crypto policy:
|
||||
# To opt-out, uncomment the following line
|
||||
# CRYPTO_POLICY=
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c
|
||||
--- openssh-6.1p1/sshconnect2.c.canohost 2012-10-30 10:52:59.593301692 +0100
|
||||
+++ openssh-6.1p1/sshconnect2.c 2012-10-30 11:01:12.870301632 +0100
|
||||
@@ -699,12 +699,15 @@ userauth_gssapi(Authctxt *authctxt)
|
||||
static u_int mech = 0;
|
||||
OM_uint32 min;
|
||||
int r, ok = 0;
|
||||
- const char *gss_host;
|
||||
+ const char *gss_host = NULL;
|
||||
|
||||
if (options.gss_server_identity)
|
||||
gss_host = options.gss_server_identity;
|
||||
- else if (options.gss_trust_dns)
|
||||
+ else if (options.gss_trust_dns) {
|
||||
gss_host = get_canonical_hostname(active_state, 1);
|
||||
+ if (strcmp(gss_host, "UNKNOWN") == 0)
|
||||
+ gss_host = authctxt->host;
|
||||
+ }
|
||||
else
|
||||
gss_host = authctxt->host;
|
||||
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
diff -up openssh-7.4p1/configure.ac.vendor openssh-7.4p1/configure.ac
|
||||
--- openssh-7.4p1/configure.ac.vendor 2016-12-23 13:34:51.681253844 +0100
|
||||
+++ openssh-7.4p1/configure.ac 2016-12-23 13:34:51.694253847 +0100
|
||||
@@ -4930,6 +4930,12 @@ AC_ARG_WITH([lastlog],
|
||||
fi
|
||||
]
|
||||
)
|
||||
+AC_ARG_ENABLE(vendor-patchlevel,
|
||||
+ [ --enable-vendor-patchlevel=TAG specify a vendor patch level],
|
||||
+ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.])
|
||||
+ SSH_VENDOR_PATCHLEVEL="$enableval"],
|
||||
+ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.])
|
||||
+ SSH_VENDOR_PATCHLEVEL=none])
|
||||
|
||||
dnl lastlog, [uw]tmpx? detection
|
||||
dnl NOTE: set the paths in the platform section to avoid the
|
||||
@@ -5194,6 +5200,7 @@ echo " Translate v4 in v6 hack
|
||||
echo " BSD Auth support: $BSD_AUTH_MSG"
|
||||
echo " Random number source: $RAND_MSG"
|
||||
echo " Privsep sandbox style: $SANDBOX_STYLE"
|
||||
+echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL"
|
||||
|
||||
echo ""
|
||||
|
||||
diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c
|
||||
--- openssh-7.4p1/servconf.c.vendor 2016-12-19 05:59:41.000000000 +0100
|
||||
+++ openssh-7.4p1/servconf.c 2016-12-23 13:36:07.555268628 +0100
|
||||
@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions
|
||||
options->max_authtries = -1;
|
||||
options->max_sessions = -1;
|
||||
options->banner = NULL;
|
||||
+ options->show_patchlevel = -1;
|
||||
options->use_dns = -1;
|
||||
options->client_alive_interval = -1;
|
||||
options->client_alive_count_max = -1;
|
||||
@@ -325,6 +326,8 @@ fill_default_server_options(ServerOption
|
||||
options->ip_qos_bulk = IPTOS_DSCP_CS1;
|
||||
if (options->version_addendum == NULL)
|
||||
options->version_addendum = xstrdup("");
|
||||
+ if (options->show_patchlevel == -1)
|
||||
+ options->show_patchlevel = 0;
|
||||
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
|
||||
options->fwd_opts.streamlocal_bind_mask = 0177;
|
||||
if (options->fwd_opts.streamlocal_bind_unlink == -1)
|
||||
@@ -402,7 +405,7 @@ typedef enum {
|
||||
sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
|
||||
sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
|
||||
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
|
||||
- sBanner, sUseDNS, sHostbasedAuthentication,
|
||||
+ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
|
||||
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
|
||||
sHostKeyAlgorithms,
|
||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
@@ -528,6 +531,7 @@ static struct {
|
||||
{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
|
||||
{ "maxsessions", sMaxSessions, SSHCFG_ALL },
|
||||
{ "banner", sBanner, SSHCFG_ALL },
|
||||
+ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL },
|
||||
{ "usedns", sUseDNS, SSHCFG_GLOBAL },
|
||||
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
|
||||
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
|
||||
@@ -1369,6 +1373,10 @@ process_server_config_line(ServerOptions
|
||||
intptr = &options->disable_forwarding;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sShowPatchLevel:
|
||||
+ intptr = &options->show_patchlevel;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sAllowUsers:
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (match_user(NULL, NULL, NULL, arg) == -1)
|
||||
@@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
|
||||
dump_cfg_fmtint(sCompression, o->compression);
|
||||
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
|
||||
+ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel);
|
||||
dump_cfg_fmtint(sUseDNS, o->use_dns);
|
||||
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
|
||||
dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
|
||||
diff -up openssh-7.4p1/servconf.h.vendor openssh-7.4p1/servconf.h
|
||||
--- openssh-7.4p1/servconf.h.vendor 2016-12-19 05:59:41.000000000 +0100
|
||||
+++ openssh-7.4p1/servconf.h 2016-12-23 13:34:51.694253847 +0100
|
||||
@@ -149,6 +149,7 @@ typedef struct {
|
||||
int max_authtries;
|
||||
int max_sessions;
|
||||
char *banner; /* SSH-2 banner message */
|
||||
+ int show_patchlevel; /* Show vendor patch level to clients */
|
||||
int use_dns;
|
||||
int client_alive_interval; /*
|
||||
* poke the client this often to
|
||||
diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5
|
||||
--- openssh-7.4p1/sshd_config.5.vendor 2016-12-23 13:34:51.695253847 +0100
|
||||
+++ openssh-7.4p1/sshd_config.5 2016-12-23 13:37:17.482282253 +0100
|
||||
@@ -1334,6 +1334,13 @@ an OpenSSH Key Revocation List (KRL) as
|
||||
.Cm AcceptEnv
|
||||
or
|
||||
.Cm PermitUserEnvironment .
|
||||
+.It Cm ShowPatchLevel
|
||||
+Specifies whether
|
||||
+.Nm sshd
|
||||
+will display the patch level of the binary in the identification string.
|
||||
+The patch level is set at compile-time.
|
||||
+The default is
|
||||
+.Dq no .
|
||||
.It Cm StreamLocalBindMask
|
||||
Sets the octal file creation mode mask
|
||||
.Pq umask
|
||||
diff -up openssh-7.4p1/sshd_config.vendor openssh-7.4p1/sshd_config
|
||||
--- openssh-7.4p1/sshd_config.vendor 2016-12-23 13:34:51.690253846 +0100
|
||||
+++ openssh-7.4p1/sshd_config 2016-12-23 13:34:51.695253847 +0100
|
||||
@@ -105,6 +105,7 @@ X11Forwarding yes
|
||||
#Compression delayed
|
||||
#ClientAliveInterval 0
|
||||
#ClientAliveCountMax 3
|
||||
+#ShowPatchLevel no
|
||||
#UseDNS no
|
||||
#PidFile /var/run/sshd.pid
|
||||
#MaxStartups 10:30:100
|
||||
diff -up openssh-7.4p1/sshd.c.vendor openssh-7.4p1/sshd.c
|
||||
--- openssh-7.4p1/sshd.c.vendor 2016-12-23 13:34:51.682253844 +0100
|
||||
+++ openssh-7.4p1/sshd.c 2016-12-23 13:38:32.434296856 +0100
|
||||
@@ -367,7 +367,8 @@ sshd_exchange_identification(struct ssh
|
||||
char remote_version[256]; /* Must be at least as big as buf. */
|
||||
|
||||
xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n",
|
||||
- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
|
||||
+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
|
||||
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
|
||||
*options.version_addendum == '\0' ? "" : " ",
|
||||
options.version_addendum);
|
||||
|
||||
@@ -1650,7 +1651,8 @@ main(int ac, char **av)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- debug("sshd version %s, %s", SSH_VERSION,
|
||||
+ debug("sshd version %s, %s",
|
||||
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
|
||||
#ifdef WITH_OPENSSL
|
||||
SSLeay_version(SSLEAY_VERSION)
|
||||
#else
|
||||
|
|
@ -46,7 +46,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c
|
|||
|
||||
+ pmonitor->m_state = "preauth";
|
||||
+
|
||||
authctxt = _authctxt;
|
||||
authctxt = (Authctxt *)ssh->authctxt;
|
||||
memset(authctxt, 0, sizeof(*authctxt));
|
||||
ssh->authctxt = authctxt;
|
||||
@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p
|
||||
|
|
@ -113,7 +113,7 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h
|
|||
+void monitor_reinit(struct monitor *, const char *);
|
||||
|
||||
struct Authctxt;
|
||||
void monitor_child_preauth(struct Authctxt *, struct monitor *);
|
||||
void monitor_child_preauth(struct ssh *, struct monitor *);
|
||||
diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c
|
||||
--- openssh-7.4p1/session.c.log-in-chroot 2016-12-23 15:14:33.319168086 +0100
|
||||
+++ openssh-7.4p1/session.c 2016-12-23 15:18:18.742211853 +0100
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ index 8f32464..18a2ca4 100644
|
|||
|
||||
if (!sshd_selinux_enabled())
|
||||
return;
|
||||
@@ -461,6 +462,58 @@ sshd_selinux_copy_context(void)
|
||||
@@ -461,6 +462,72 @@ sshd_selinux_copy_context(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -30,46 +30,60 @@ index 8f32464..18a2ca4 100644
|
|||
+ char line[1024], *preauth_context = NULL, *cp, *arg;
|
||||
+ const char *contexts_path;
|
||||
+ FILE *contexts_file;
|
||||
+ struct stat sb;
|
||||
+
|
||||
+ contexts_path = selinux_openssh_contexts_path();
|
||||
+ if (contexts_path != NULL) {
|
||||
+ if ((contexts_file = fopen(contexts_path, "r")) != NULL) {
|
||||
+ struct stat sb;
|
||||
+
|
||||
+ if (fstat(fileno(contexts_file), &sb) == 0 && ((sb.st_uid == 0) && ((sb.st_mode & 022) == 0))) {
|
||||
+ while (fgets(line, sizeof(line), contexts_file)) {
|
||||
+ /* Strip trailing whitespace */
|
||||
+ for (len = strlen(line) - 1; len > 0; len--) {
|
||||
+ if (strchr(" \t\r\n", line[len]) == NULL)
|
||||
+ break;
|
||||
+ line[len] = '\0';
|
||||
+ }
|
||||
+
|
||||
+ if (line[0] == '\0')
|
||||
+ continue;
|
||||
+
|
||||
+ cp = line;
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (arg && *arg == '\0')
|
||||
+ arg = strdelim(&cp);
|
||||
+
|
||||
+ if (arg && strcmp(arg, "privsep_preauth") == 0) {
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (!arg || *arg == '\0') {
|
||||
+ debug("%s: privsep_preauth is empty", __func__);
|
||||
+ fclose(contexts_file);
|
||||
+ return;
|
||||
+ }
|
||||
+ preauth_context = xstrdup(arg);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(contexts_file);
|
||||
+ }
|
||||
+ if (contexts_path == NULL) {
|
||||
+ debug3("%s: Failed to get the path to SELinux context", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (preauth_context == NULL)
|
||||
+ preauth_context = xstrdup("sshd_net_t");
|
||||
+ if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
|
||||
+ debug("%s: Failed to open SELinux context file", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (fstat(fileno(contexts_file), &sb) != 0 ||
|
||||
+ sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
|
||||
+ logit("%s: SELinux context file needs to be owned by root"
|
||||
+ " and not writable by anyone else", __func__);
|
||||
+ fclose(contexts_file);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), contexts_file)) {
|
||||
+ /* Strip trailing whitespace */
|
||||
+ for (len = strlen(line) - 1; len > 0; len--) {
|
||||
+ if (strchr(" \t\r\n", line[len]) == NULL)
|
||||
+ break;
|
||||
+ line[len] = '\0';
|
||||
+ }
|
||||
+
|
||||
+ if (line[0] == '\0')
|
||||
+ continue;
|
||||
+
|
||||
+ cp = line;
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (arg && *arg == '\0')
|
||||
+ arg = strdelim(&cp);
|
||||
+
|
||||
+ if (arg && strcmp(arg, "privsep_preauth") == 0) {
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (!arg || *arg == '\0') {
|
||||
+ debug("%s: privsep_preauth is empty", __func__);
|
||||
+ fclose(contexts_file);
|
||||
+ return;
|
||||
+ }
|
||||
+ preauth_context = xstrdup(arg);
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(contexts_file);
|
||||
+
|
||||
+ if (preauth_context == NULL) {
|
||||
+ debug("%s: Unable to find 'privsep_preauth' option in"
|
||||
+ " SELinux context file", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ssh_selinux_change_context(preauth_context);
|
||||
+ free(preauth_context);
|
||||
|
|
@ -82,14 +96,6 @@ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
|
|||
index 22ea8ef..1fc963d 100644
|
||||
--- a/openbsd-compat/port-linux.c
|
||||
+++ b/openbsd-compat/port-linux.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "xmalloc.h"
|
||||
@@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname)
|
||||
strlcpy(newctx + len, newname, newlen - len);
|
||||
if ((cx = index(cx + 1, ':')))
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
|
|||
--- openssh-7.4p1/servconf.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100
|
||||
+++ openssh-7.4p1/servconf.c 2016-12-23 15:35:36.354401156 +0100
|
||||
@@ -168,6 +168,7 @@ initialize_server_options(ServerOptions
|
||||
options->gss_strict_acceptor = -1;
|
||||
options->gss_store_rekey = -1;
|
||||
options->gss_kex_algorithms = NULL;
|
||||
options->use_kuserok = -1;
|
||||
+ options->enable_k5users = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->challenge_response_authentication = -1;
|
||||
@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
|
||||
options->gss_store_rekey = 0;
|
||||
#endif
|
||||
if (options->use_kuserok == -1)
|
||||
options->use_kuserok = 1;
|
||||
+ if (options->enable_k5users == -1)
|
||||
|
|
@ -44,20 +44,22 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
|
|||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
|
||||
+ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
|
||||
sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel,
|
||||
sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
|
||||
sAcceptEnv, sSetEnv, sPermitTunnel,
|
||||
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
@@ -497,12 +500,14 @@ static struct {
|
||||
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
|
||||
@@ -497,14 +500,16 @@ static struct {
|
||||
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
|
||||
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
|
||||
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
|
||||
#else
|
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablek5users", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
|
|
@ -83,7 +85,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
|
|||
M_CP_INTOPT(log_level);
|
||||
@@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o)
|
||||
# endif
|
||||
dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket);
|
||||
dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
|
||||
dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
|
||||
+ dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users);
|
||||
#endif
|
||||
|
|
@ -93,7 +95,7 @@ diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h
|
|||
--- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100
|
||||
+++ openssh-7.4p1/servconf.h 2016-12-23 15:18:40.629216102 +0100
|
||||
@@ -174,6 +174,7 @@ typedef struct {
|
||||
int kerberos_unique_ticket; /* If true, the aquired ticket will
|
||||
int kerberos_unique_ccache; /* If true, the acquired ticket will
|
||||
* be stored in per-session ccache */
|
||||
int use_kuserok;
|
||||
+ int enable_k5users;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in
|
|||
ssh-xmss.o \
|
||||
@@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l
|
||||
ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
|
||||
$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS)
|
||||
$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
|
||||
|
||||
+ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o
|
||||
+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS)
|
||||
+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
+
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
|
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
|
@ -187,7 +187,7 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c
|
|||
+ usage();
|
||||
+ }
|
||||
+
|
||||
+ SSLeay_add_all_algorithms();
|
||||
+ OpenSSL_add_all_algorithms();
|
||||
+
|
||||
+ c = cipher_by_name(algo);
|
||||
+ if (c == NULL) {
|
||||
|
|
|
|||
|
|
@ -235,9 +235,9 @@ index 28659ec..9c94d8e 100644
|
|||
+#endif
|
||||
+#endif
|
||||
+
|
||||
s->forced = 0;
|
||||
if (forced != NULL) {
|
||||
if (IS_INTERNAL_SFTP(command)) {
|
||||
s->is_subsystem = s->is_subsystem ?
|
||||
s->forced = 1;
|
||||
diff --git a/ssh-gss.h b/ssh-gss.h
|
||||
index 0374c88..509109a 100644
|
||||
--- a/ssh-gss.h
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in
|
|||
ssh-xmss.o \
|
||||
@@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
|
||||
ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o
|
||||
$(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS)
|
||||
$(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LDAPLIBS)
|
||||
|
||||
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
|
||||
+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS)
|
||||
+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
|
||||
+
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
|
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
|
|
|||
|
|
@ -176,17 +176,17 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
|
|||
--- openssh-7.4p1/servconf.c.kuserok 2016-12-23 14:36:07.630465944 +0100
|
||||
+++ openssh-7.4p1/servconf.c 2016-12-23 15:11:52.278133344 +0100
|
||||
@@ -116,6 +116,7 @@ initialize_server_options(ServerOptions
|
||||
options->gss_cleanup_creds = -1;
|
||||
options->gss_strict_acceptor = -1;
|
||||
options->gss_store_rekey = -1;
|
||||
options->gss_kex_algorithms = NULL;
|
||||
+ options->use_kuserok = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->challenge_response_authentication = -1;
|
||||
@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
|
||||
options->gss_strict_acceptor = 1;
|
||||
if (options->gss_store_rekey == -1)
|
||||
options->gss_store_rekey = 0;
|
||||
if (options->gss_kex_algorithms == NULL)
|
||||
options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
|
||||
#endif
|
||||
+ if (options->use_kuserok == -1)
|
||||
+ options->use_kuserok = 1;
|
||||
if (options->password_authentication == -1)
|
||||
|
|
@ -196,22 +196,22 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
|
|||
sPermitRootLogin, sLogFacility, sLogLevel,
|
||||
sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
- sKerberosGetAFSToken, sKerberosUniqueTicket,
|
||||
+ sKerberosGetAFSToken, sKerberosUniqueTicket, sKerberosUseKuserok,
|
||||
- sKerberosGetAFSToken, sKerberosUniqueCCache,
|
||||
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok,
|
||||
sChallengeResponseAuthentication,
|
||||
sPasswordAuthentication, sKbdInteractiveAuthentication,
|
||||
sListenAddress, sAddressFamily,
|
||||
@@ -478,12 +481,14 @@ static struct {
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL },
|
||||
{ "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
|
||||
+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL },
|
||||
#else
|
||||
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
|
|
@ -238,7 +238,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
|
|||
@@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
|
||||
# endif
|
||||
dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket);
|
||||
dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
|
||||
+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
|
|
@ -248,7 +248,7 @@ diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h
|
|||
+++ openssh-7.4p1/servconf.h 2016-12-23 14:36:07.645465936 +0100
|
||||
@@ -118,6 +118,7 @@ typedef struct {
|
||||
* authenticated with Kerberos. */
|
||||
int kerberos_unique_ticket; /* If true, the aquired ticket will
|
||||
int kerberos_unique_ccache; /* If true, the acquired ticket will
|
||||
* be stored in per-session ccache */
|
||||
+ int use_kuserok;
|
||||
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||
|
|
@ -258,9 +258,9 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5
|
|||
--- openssh-7.4p1/sshd_config.5.kuserok 2016-12-23 14:36:07.637465940 +0100
|
||||
+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:14:03.117162222 +0100
|
||||
@@ -850,6 +850,10 @@ Specifies whether to automatically destr
|
||||
tickets aquired in different sessions of the same user.
|
||||
The default is
|
||||
.Cm no .
|
||||
.Cm no
|
||||
can lead to overwriting previous tickets by subseqent connections to the same
|
||||
user account.
|
||||
+.It Cm KerberosUseKuserok
|
||||
+Specifies whether to look at .k5login file for user's aliases.
|
||||
+The default is
|
||||
|
|
|
|||
|
|
@ -25,15 +25,15 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh-
|
|||
+ return;
|
||||
+
|
||||
+ if (getexeccon((security_context_t *)&ctx) != 0) {
|
||||
+ logit("%s: getcon failed with %s", __func__, strerror (errno));
|
||||
+ logit("%s: getexeccon failed with %s", __func__, strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+ if (ctx != NULL) {
|
||||
+ /* unset exec context before we will lose this capabililty */
|
||||
+ if (setexeccon(NULL) != 0)
|
||||
+ fatal("%s: setexeccon failed with %s", __func__, strerror (errno));
|
||||
+ fatal("%s: setexeccon failed with %s", __func__, strerror(errno));
|
||||
+ if (setcon(ctx) != 0)
|
||||
+ fatal("%s: setcon failed with %s", __func__, strerror (errno));
|
||||
+ fatal("%s: setcon failed with %s", __func__, strerror(errno));
|
||||
+ freecon(ctx);
|
||||
+ }
|
||||
+}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c
|
||||
--- openssh-7.4p1/channels.c.coverity 2016-12-23 16:40:26.881788686 +0100
|
||||
+++ openssh-7.4p1/channels.c 2016-12-23 16:42:36.244818763 +0100
|
||||
@@ -288,11 +288,11 @@ channel_register_fds(Channel *c, int rfd
|
||||
|
||||
/* enable nonblocking mode */
|
||||
if (nonblock) {
|
||||
- if (rfd != -1)
|
||||
+ if (rfd >= 0)
|
||||
diff -up openssh-8.0p1/channels.c.coverity openssh-8.0p1/channels.c
|
||||
--- openssh-8.0p1/channels.c.coverity 2021-06-21 10:59:17.297473319 +0200
|
||||
+++ openssh-8.0p1/channels.c 2021-06-21 11:11:32.467290400 +0200
|
||||
@@ -341,15 +341,15 @@ channel_register_fds(struct ssh *ssh, Ch
|
||||
* restore their blocking state on exit to avoid interfering
|
||||
* with other programs that follow.
|
||||
*/
|
||||
- if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) {
|
||||
+ if (rfd >= 0 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) {
|
||||
c->restore_block |= CHANNEL_RESTORE_RFD;
|
||||
set_nonblock(rfd);
|
||||
- if (wfd != -1)
|
||||
+ if (wfd >= 0)
|
||||
}
|
||||
- if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) {
|
||||
+ if (wfd >= 0 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) {
|
||||
c->restore_block |= CHANNEL_RESTORE_WFD;
|
||||
set_nonblock(wfd);
|
||||
- if (efd != -1)
|
||||
+ if (efd >= 0)
|
||||
}
|
||||
- if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) {
|
||||
+ if (efd >= 0 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) {
|
||||
c->restore_block |= CHANNEL_RESTORE_EFD;
|
||||
set_nonblock(efd);
|
||||
}
|
||||
}
|
||||
diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c
|
||||
--- openssh-7.4p1/monitor.c.coverity 2016-12-23 16:40:26.888788688 +0100
|
||||
+++ openssh-7.4p1/monitor.c 2016-12-23 16:40:26.900788691 +0100
|
||||
@@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx
|
||||
mm_get_keystate(pmonitor);
|
||||
}
|
||||
diff -up openssh-8.0p1/monitor.c.coverity openssh-8.0p1/monitor.c
|
||||
--- openssh-8.0p1/monitor.c.coverity 2021-06-21 10:59:17.282473202 +0200
|
||||
+++ openssh-8.0p1/monitor.c 2021-06-21 10:59:17.297473319 +0200
|
||||
@@ -401,7 +401,7 @@ monitor_child_preauth(struct ssh *ssh, s
|
||||
mm_get_keystate(ssh, pmonitor);
|
||||
|
||||
/* Drain any buffered messages from the child */
|
||||
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
|
||||
|
|
@ -124,26 +128,14 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c
|
|||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ server_request_tun(void)
|
||||
debug("%s: invalid tun", __func__);
|
||||
goto done;
|
||||
}
|
||||
|
||||
tun = packet_get_int();
|
||||
- if (auth_opts->force_tun_device != -1) {
|
||||
+ if (auth_opts->force_tun_device >= 0) {
|
||||
if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun)
|
||||
if (tun != SSH_TUNID_ANY &&
|
||||
auth_opts->force_tun_device != (int)tun)
|
||||
goto done;
|
||||
tun = auth_opts->force_tun_device;
|
||||
diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
|
||||
--- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100
|
||||
+++ openssh-7.4p1/sftp.c 2016-12-23 16:40:26.903788691 +0100
|
||||
@@ -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/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c
|
||||
--- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100
|
||||
+++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100
|
||||
|
|
@ -163,7 +155,7 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
|
|||
+++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100
|
||||
@@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt)
|
||||
|
||||
privsep_preauth_child();
|
||||
privsep_preauth_child(ssh);
|
||||
setproctitle("%s", "[net]");
|
||||
- if (box != NULL)
|
||||
+ if (box != NULL) {
|
||||
|
|
@ -174,8 +166,8 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
|
|||
return 0;
|
||||
}
|
||||
@@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so
|
||||
if (num_listen_socks < 0)
|
||||
break;
|
||||
explicit_bzero(rnd, sizeof(rnd));
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (fdset != NULL)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in
|
|||
ssh-xmss.o \
|
||||
@@ -198,6 +199,9 @@ ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHD
|
||||
ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o
|
||||
$(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS)
|
||||
$(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
||||
+ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o
|
||||
+ $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
|
@ -40,7 +40,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in
|
|||
diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
|
||||
--- openssh-6.8p1/ssh-cavs.c.kdf-cavs 2015-03-18 11:23:46.348049354 +0100
|
||||
+++ openssh-6.8p1/ssh-cavs.c 2015-03-18 11:23:46.348049354 +0100
|
||||
@@ -0,0 +1,377 @@
|
||||
@@ -0,0 +1,387 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
|
||||
+ *
|
||||
|
|
@ -208,6 +208,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
|
|||
+{
|
||||
+ int ret = 0;
|
||||
+ struct kex kex;
|
||||
+ struct sshbuf *Kb = NULL;
|
||||
+ BIGNUM *Kbn = NULL;
|
||||
+ int mode = 0;
|
||||
+ struct newkeys *ctoskeys;
|
||||
|
|
@ -222,10 +223,17 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
|
|||
+ Kbn = BN_new();
|
||||
+ BN_bin2bn(test->K, test->Klen, Kbn);
|
||||
+ if (!Kbn) {
|
||||
+ printf("cannot convert K into BIGNUM\n");
|
||||
+ printf("cannot convert K into bignum\n");
|
||||
+ ret = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ Kb = sshbuf_new();
|
||||
+ if (!Kb) {
|
||||
+ printf("cannot convert K into sshbuf\n");
|
||||
+ ret = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ sshbuf_put_bignum2(Kb, Kbn);
|
||||
+
|
||||
+ kex.session_id = test->session_id;
|
||||
+ kex.session_id_len = test->session_id_len;
|
||||
|
|
@ -285,7 +293,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
|
|||
+ goto out;
|
||||
+ }
|
||||
+ ssh->kex = &kex;
|
||||
+ kex_derive_keys_bn(ssh, test->H, test->Hlen, Kbn);
|
||||
+ kex_derive_keys(ssh, test->H, test->Hlen, Kb);
|
||||
+
|
||||
+ ctoskeys = kex.newkeys[0];
|
||||
+ stockeys = kex.newkeys[1];
|
||||
|
|
@ -321,6 +329,8 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
|
|||
+out:
|
||||
+ if (Kbn)
|
||||
+ BN_free(Kbn);
|
||||
+ if (Kb)
|
||||
+ sshbuf_free(Kb);
|
||||
+ if (ssh)
|
||||
+ ssh_packet_close(ssh);
|
||||
+ return ret;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in
|
|||
$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o
|
||||
+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS)
|
||||
+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LDAPLIBS)
|
||||
+
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
|
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
|
@ -331,7 +331,7 @@ diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac
|
|||
+ [ac_cv_ldap_set_rebind_proc=3],
|
||||
+ [ac_cv_ldap_set_rebind_proc=2])
|
||||
+ AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc)
|
||||
+ AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
|
||||
+ AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
|
||||
+ )
|
||||
+ LIBS="$saved_LIBS"
|
||||
+ fi
|
||||
|
|
@ -646,7 +646,7 @@ diff -up openssh-6.8p1/ldap.conf.ldap openssh-6.8p1/ldap.conf
|
|||
diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c
|
||||
--- openssh-6.8p1/ldapbody.c.ldap 2015-03-18 11:11:29.031801462 +0100
|
||||
+++ openssh-6.8p1/ldapbody.c 2015-03-18 11:11:29.031801462 +0100
|
||||
@@ -0,0 +1,494 @@
|
||||
@@ -0,0 +1,499 @@
|
||||
+/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
|
||||
+/*
|
||||
+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved.
|
||||
|
|
@ -708,7 +708,11 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c
|
|||
+
|
||||
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
|
||||
+static int
|
||||
+#if LDAP_API_VERSION > 3000
|
||||
+_rebind_proc (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params)
|
||||
+#else
|
||||
+_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid)
|
||||
+#endif
|
||||
+{
|
||||
+ struct timeval timeout;
|
||||
+ int rc;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8
|
||||
--- openssh-7.2p2/sftp-server.8.sftp-force-mode 2016-03-09 19:04:48.000000000 +0100
|
||||
+++ openssh-7.2p2/sftp-server.8 2016-06-23 16:18:20.463854117 +0200
|
||||
diff --color -ru a/sftp-server.8 b/sftp-server.8
|
||||
--- a/sftp-server.8 2019-04-18 00:52:57.000000000 +0200
|
||||
+++ b/sftp-server.8 2022-06-20 16:03:47.892540068 +0200
|
||||
@@ -38,6 +38,7 @@
|
||||
.Op Fl P Ar blacklisted_requests
|
||||
.Op Fl p Ar whitelisted_requests
|
||||
|
|
@ -9,21 +9,23 @@ diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8
|
|||
.Ek
|
||||
.Nm
|
||||
.Fl Q Ar protocol_feature
|
||||
@@ -138,6 +139,10 @@ Sets an explicit
|
||||
@@ -138,6 +139,12 @@
|
||||
.Xr umask 2
|
||||
to be applied to newly-created files and directories, instead of the
|
||||
user's default mask.
|
||||
+.It Fl m Ar force_file_perms
|
||||
+Sets explicit file permissions to be applied to newly-created files instead
|
||||
+of the default or client requested mode. Numeric values include:
|
||||
+777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set.
|
||||
+777, 755, 750, 666, 644, 640, etc. Using both -m and -u switches makes the
|
||||
+umask (-u) effective only for newly created directories and explicit mode (-m)
|
||||
+for newly created files.
|
||||
.El
|
||||
.Pp
|
||||
On some systems,
|
||||
diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
|
||||
--- openssh-7.2p2/sftp-server.c.sftp-force-mode 2016-06-23 16:18:20.446854128 +0200
|
||||
+++ openssh-7.2p2/sftp-server.c 2016-06-23 16:20:37.950766082 +0200
|
||||
@@ -69,6 +69,10 @@ struct sshbuf *oqueue;
|
||||
diff --color -ru a/sftp-server.c b/sftp-server.c
|
||||
--- a/sftp-server.c 2022-06-20 16:01:26.183793633 +0200
|
||||
+++ b/sftp-server.c 2022-06-20 16:02:12.442690608 +0200
|
||||
@@ -65,6 +65,10 @@
|
||||
/* Version of client */
|
||||
static u_int version;
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
|
|||
/* SSH2_FXP_INIT received */
|
||||
static int init_done;
|
||||
|
||||
@@ -683,6 +687,7 @@ process_open(u_int32_t id)
|
||||
@@ -683,6 +687,7 @@
|
||||
Attrib a;
|
||||
char *name;
|
||||
int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE;
|
||||
|
|
@ -42,7 +44,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
|
|||
|
||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
|
||||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
|
||||
@@ -692,6 +697,10 @@ process_open(u_int32_t id)
|
||||
@@ -692,6 +697,10 @@
|
||||
debug3("request %u: open flags %d", id, pflags);
|
||||
flags = flags_from_portable(pflags);
|
||||
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
|
||||
|
|
@ -53,7 +55,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
|
|||
logit("open \"%s\" flags %s mode 0%o",
|
||||
name, string_from_portable(pflags), mode);
|
||||
if (readonly &&
|
||||
@@ -713,6 +722,8 @@ process_open(u_int32_t id)
|
||||
@@ -713,6 +722,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -62,7 +64,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
|
|||
if (status != SSH2_FX_OK)
|
||||
send_status(id, status);
|
||||
free(name);
|
||||
@@ -1494,7 +1505,7 @@ sftp_server_usage(void)
|
||||
@@ -1555,7 +1566,7 @@
|
||||
fprintf(stderr,
|
||||
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
|
||||
"[-l log_level]\n\t[-P blacklisted_requests] "
|
||||
|
|
@ -71,7 +73,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
|
|||
" %s -Q protocol_feature\n",
|
||||
__progname, __progname);
|
||||
exit(1);
|
||||
@@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv,
|
||||
@@ -1581,7 +1592,7 @@
|
||||
pw = pwcopy(user_pw);
|
||||
|
||||
while (!skipargs && (ch = getopt(argc, argv,
|
||||
|
|
@ -80,7 +82,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
|
|||
switch (ch) {
|
||||
case 'Q':
|
||||
if (strcasecmp(optarg, "requests") != 0) {
|
||||
@@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv,
|
||||
@@ -1643,6 +1654,15 @@
|
||||
fatal("Invalid umask \"%s\"", optarg);
|
||||
(void)umask((mode_t)mask);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -10,18 +10,3 @@ diff -up openssh/servconf.c.sshdt openssh/servconf.c
|
|||
dump_cfg_string(sForceCommand, o->adm_forced_command);
|
||||
dump_cfg_string(sChrootDirectory, o->chroot_directory);
|
||||
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
|
||||
diff -up openssh/ssh.1.sshdt openssh/ssh.1
|
||||
--- openssh/ssh.1.sshdt 2015-06-24 11:42:19.565102807 +0200
|
||||
+++ openssh/ssh.1 2015-06-24 11:42:29.042078701 +0200
|
||||
@@ -441,7 +441,11 @@ For full details of the options listed b
|
||||
.It GatewayPorts
|
||||
.It GlobalKnownHostsFile
|
||||
.It GSSAPIAuthentication
|
||||
+.It GSSAPIKeyExchange
|
||||
+.It GSSAPIClientIdentity
|
||||
.It GSSAPIDelegateCredentials
|
||||
+.It GSSAPIRenewalForcesRekey
|
||||
+.It GSSAPITrustDNS
|
||||
.It HashKnownHosts
|
||||
.It Host
|
||||
.It HostbasedAuthentication
|
||||
|
|
|
|||
|
|
@ -1,422 +0,0 @@
|
|||
diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c
|
||||
--- openssh-7.0p1/gss-genr.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200
|
||||
+++ openssh-7.0p1/gss-genr.c 2015-08-19 12:28:38.078518839 +0200
|
||||
@@ -78,7 +78,8 @@ ssh_gssapi_oid_table_ok() {
|
||||
*/
|
||||
|
||||
char *
|
||||
-ssh_gssapi_client_mechanisms(const char *host, const char *client) {
|
||||
+ssh_gssapi_client_mechanisms(const char *host, const char *client,
|
||||
+ const char *kex) {
|
||||
gss_OID_set gss_supported;
|
||||
OM_uint32 min_status;
|
||||
|
||||
@@ -86,12 +87,12 @@ ssh_gssapi_client_mechanisms(const char
|
||||
return NULL;
|
||||
|
||||
return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
|
||||
- host, client));
|
||||
+ host, client, kex));
|
||||
}
|
||||
|
||||
char *
|
||||
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
|
||||
- const char *host, const char *client) {
|
||||
+ const char *host, const char *client, const char *kex) {
|
||||
struct sshbuf *buf;
|
||||
size_t i;
|
||||
int oidpos, enclen, r;
|
||||
@@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
|
||||
char deroid[2];
|
||||
const EVP_MD *evp_md = EVP_md5();
|
||||
EVP_MD_CTX md;
|
||||
+ char *s, *cp, *p;
|
||||
|
||||
if (gss_enc2oid != NULL) {
|
||||
for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
|
||||
@@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
|
||||
oidpos = 0;
|
||||
+ s = cp = xstrdup(kex);
|
||||
for (i = 0; i < gss_supported->count; i++) {
|
||||
if (gss_supported->elements[i].length < 128 &&
|
||||
(*check)(NULL, &(gss_supported->elements[i]), host, client)) {
|
||||
@@ -131,28 +134,25 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
|
||||
enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
|
||||
encoded, EVP_MD_size(evp_md) * 2);
|
||||
|
||||
- if (oidpos != 0)
|
||||
- if ((r = sshbuf_put_u8(buf, ',')) != 0)
|
||||
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
-
|
||||
- if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID,
|
||||
- sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 ||
|
||||
- (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
|
||||
- (r = sshbuf_put_u8(buf, ',')) != 0 ||
|
||||
- (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID,
|
||||
- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 ||
|
||||
- (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
|
||||
- (r = sshbuf_put_u8(buf, ',')) != 0 ||
|
||||
- (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID,
|
||||
- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 ||
|
||||
- (r = sshbuf_put(buf, encoded, enclen)) != 0)
|
||||
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
+ cp = strncpy(s, kex, strlen(kex));
|
||||
+ for ((p = strsep(&cp, ",")); p && *p != '\0';
|
||||
+ (p = strsep(&cp, ","))) {
|
||||
+ if (sshbuf_len(buf) != 0)
|
||||
+ if ((r = sshbuf_put_u8(buf, ',')) != 0)
|
||||
+ fatal("%s: buffer error: %s",
|
||||
+ __func__, ssh_err(r));
|
||||
+ if ((r = sshbuf_put(buf, p, strlen(p))) != 0 ||
|
||||
+ (r = sshbuf_put(buf, encoded, enclen)) != 0)
|
||||
+ fatal("%s: buffer error: %s",
|
||||
+ __func__, ssh_err(r));
|
||||
+ }
|
||||
|
||||
gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
|
||||
gss_enc2oid[oidpos].encoded = encoded;
|
||||
oidpos++;
|
||||
}
|
||||
}
|
||||
+ free(s);
|
||||
gss_enc2oid[oidpos].oid = NULL;
|
||||
gss_enc2oid[oidpos].encoded = NULL;
|
||||
|
||||
diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c
|
||||
--- openssh-7.0p1/gss-serv.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200
|
||||
+++ openssh-7.0p1/gss-serv.c 2015-08-19 12:28:38.078518839 +0200
|
||||
@@ -149,7 +149,8 @@ ssh_gssapi_server_mechanisms() {
|
||||
if (supported_oids == NULL)
|
||||
ssh_gssapi_prepare_supported_oids();
|
||||
return (ssh_gssapi_kex_mechs(supported_oids,
|
||||
- &ssh_gssapi_server_check_mech, NULL, NULL));
|
||||
+ &ssh_gssapi_server_check_mech, NULL, NULL,
|
||||
+ options.gss_kex_algorithms));
|
||||
}
|
||||
|
||||
/* Unprivileged */
|
||||
diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c
|
||||
--- openssh-7.0p1/kex.c.gsskexalg 2015-08-19 12:28:38.078518839 +0200
|
||||
+++ openssh-7.0p1/kex.c 2015-08-19 12:30:13.249306371 +0200
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "misc.h"
|
||||
#include "dispatch.h"
|
||||
#include "monitor.h"
|
||||
+#include "xmalloc.h"
|
||||
|
||||
#include "ssherr.h"
|
||||
#include "sshbuf.h"
|
||||
@@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char
|
||||
return r;
|
||||
}
|
||||
|
||||
+/* Validate GSS KEX method name list */
|
||||
+int
|
||||
+gss_kex_names_valid(const char *names)
|
||||
+{
|
||||
+ char *s, *cp, *p;
|
||||
+
|
||||
+ if (names == NULL || *names == '\0')
|
||||
+ return 0;
|
||||
+ s = cp = xstrdup(names);
|
||||
+ for ((p = strsep(&cp, ",")); p && *p != '\0';
|
||||
+ (p = strsep(&cp, ","))) {
|
||||
+ if (strncmp(p, "gss-", 4) != 0
|
||||
+ || kex_alg_by_name(p) == NULL) {
|
||||
+ error("Unsupported KEX algorithm \"%.100s\"", p);
|
||||
+ free(s);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ debug3("gss kex names ok: [%s]", names);
|
||||
+ free(s);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/* put algorithm proposal into buffer */
|
||||
int
|
||||
kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
|
||||
diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h
|
||||
--- openssh-7.0p1/kex.h.gsskexalg 2015-08-19 12:28:38.078518839 +0200
|
||||
+++ openssh-7.0p1/kex.h 2015-08-19 12:30:52.404218958 +0200
|
||||
@@ -173,6 +173,7 @@ int kex_names_valid(const char *);
|
||||
char *kex_alg_list(char);
|
||||
char *kex_names_cat(const char *, const char *);
|
||||
int kex_assemble_names(char **, const char *, const char *);
|
||||
+int gss_kex_names_valid(const char *);
|
||||
|
||||
int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **);
|
||||
int kex_setup(struct ssh *, char *[PROPOSAL_MAX]);
|
||||
diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c
|
||||
--- openssh-7.0p1/readconf.c.gsskexalg 2015-08-19 12:28:38.026518955 +0200
|
||||
+++ openssh-7.0p1/readconf.c 2015-08-19 12:31:28.333138747 +0200
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "uidswap.h"
|
||||
#include "myproposal.h"
|
||||
#include "digest.h"
|
||||
+#include "ssh-gss.h"
|
||||
|
||||
/* Format of the configuration file:
|
||||
|
||||
@@ -148,7 +149,7 @@ typedef enum {
|
||||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
|
||||
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
|
||||
oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
|
||||
- oGssServerIdentity,
|
||||
+ oGssServerIdentity, oGssKexAlgorithms,
|
||||
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
|
||||
oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
|
||||
oHashKnownHosts,
|
||||
@@ -200,6 +201,7 @@ static struct {
|
||||
{ "gssapiclientidentity", oGssClientIdentity },
|
||||
{ "gssapiserveridentity", oGssServerIdentity },
|
||||
{ "gssapirenewalforcesrekey", oGssRenewalRekey },
|
||||
+ { "gssapikexalgorithms", oGssKexAlgorithms },
|
||||
# else
|
||||
{ "gssapiauthentication", oUnsupported },
|
||||
{ "gssapikeyexchange", oUnsupported },
|
||||
@@ -207,6 +209,7 @@ static struct {
|
||||
{ "gssapitrustdns", oUnsupported },
|
||||
{ "gssapiclientidentity", oUnsupported },
|
||||
{ "gssapirenewalforcesrekey", oUnsupported },
|
||||
+ { "gssapikexalgorithms", oUnsupported },
|
||||
#endif
|
||||
#ifdef ENABLE_PKCS11
|
||||
{ "smartcarddevice", oPKCS11Provider },
|
||||
@@ -929,6 +932,18 @@ parse_time:
|
||||
intptr = &options->gss_renewal_rekey;
|
||||
goto parse_flag;
|
||||
|
||||
+ case oGssKexAlgorithms:
|
||||
+ arg = strdelim(&s);
|
||||
+ if (!arg || *arg == '\0')
|
||||
+ fatal("%.200s line %d: Missing argument.",
|
||||
+ filename, linenum);
|
||||
+ if (!gss_kex_names_valid(arg))
|
||||
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
|
||||
+ filename, linenum, arg ? arg : "<NONE>");
|
||||
+ if (*activep && options->gss_kex_algorithms == NULL)
|
||||
+ options->gss_kex_algorithms = xstrdup(arg);
|
||||
+ break;
|
||||
+
|
||||
case oBatchMode:
|
||||
intptr = &options->batch_mode;
|
||||
goto parse_flag;
|
||||
@@ -1638,6 +1653,7 @@ initialize_options(Options * options)
|
||||
options->gss_renewal_rekey = -1;
|
||||
options->gss_client_identity = NULL;
|
||||
options->gss_server_identity = NULL;
|
||||
+ options->gss_kex_algorithms = NULL;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->kbd_interactive_devices = NULL;
|
||||
@@ -1773,6 +1789,10 @@ fill_default_options(Options * options)
|
||||
options->gss_trust_dns = 0;
|
||||
if (options->gss_renewal_rekey == -1)
|
||||
options->gss_renewal_rekey = 0;
|
||||
+#ifdef GSSAPI
|
||||
+ if (options->gss_kex_algorithms == NULL)
|
||||
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
|
||||
+#endif
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
diff -up openssh-7.0p1/readconf.h.gsskexalg openssh-7.0p1/readconf.h
|
||||
--- openssh-7.0p1/readconf.h.gsskexalg 2015-08-19 12:28:38.026518955 +0200
|
||||
+++ openssh-7.0p1/readconf.h 2015-08-19 12:28:38.079518836 +0200
|
||||
@@ -51,6 +51,7 @@ typedef struct {
|
||||
int gss_renewal_rekey; /* Credential renewal forces rekey */
|
||||
char *gss_client_identity; /* Principal to initiate GSSAPI with */
|
||||
char *gss_server_identity; /* GSSAPI target principal */
|
||||
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */
|
||||
int password_authentication; /* Try password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
||||
diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c
|
||||
--- openssh-7.0p1/servconf.c.gsskexalg 2015-08-19 12:28:38.074518847 +0200
|
||||
+++ openssh-7.0p1/servconf.c 2015-08-19 12:33:13.599902732 +0200
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "auth.h"
|
||||
#include "myproposal.h"
|
||||
#include "digest.h"
|
||||
+#include "ssh-gss.h"
|
||||
|
||||
static void add_listen_addr(ServerOptions *, const char *,
|
||||
const char *, int);
|
||||
@@ -121,6 +122,7 @@ initialize_server_options(ServerOptions
|
||||
options->gss_cleanup_creds = -1;
|
||||
options->gss_strict_acceptor = -1;
|
||||
options->gss_store_rekey = -1;
|
||||
+ options->gss_kex_algorithms = NULL;
|
||||
options->use_kuserok = -1;
|
||||
options->enable_k5users = -1;
|
||||
options->password_authentication = -1;
|
||||
@@ -288,6 +290,10 @@ fill_default_server_options(ServerOption
|
||||
options->gss_strict_acceptor = 1;
|
||||
if (options->gss_store_rekey == -1)
|
||||
options->gss_store_rekey = 0;
|
||||
+#ifdef GSSAPI
|
||||
+ if (options->gss_kex_algorithms == NULL)
|
||||
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
|
||||
+#endif
|
||||
if (options->use_kuserok == -1)
|
||||
options->use_kuserok = 1;
|
||||
if (options->enable_k5users == -1)
|
||||
@@ -427,7 +431,7 @@ typedef enum {
|
||||
sHostKeyAlgorithms,
|
||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
|
||||
- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel,
|
||||
+ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel,
|
||||
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
sHostCertificate,
|
||||
@@ -506,6 +510,7 @@ static struct {
|
||||
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
|
||||
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
|
||||
{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
|
||||
+ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
|
||||
#else
|
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -513,6 +518,7 @@ static struct {
|
||||
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
|
||||
+ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -1273,6 +1279,18 @@ process_server_config_line(ServerOptions
|
||||
intptr = &options->gss_store_rekey;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sGssKexAlgorithms:
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (!arg || *arg == '\0')
|
||||
+ fatal("%.200s line %d: Missing argument.",
|
||||
+ filename, linenum);
|
||||
+ if (!gss_kex_names_valid(arg))
|
||||
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
|
||||
+ filename, linenum, arg ? arg : "<NONE>");
|
||||
+ if (*activep && options->gss_kex_algorithms == NULL)
|
||||
+ options->gss_kex_algorithms = xstrdup(arg);
|
||||
+ break;
|
||||
+
|
||||
case sPasswordAuthentication:
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
@@ -2304,6 +2322,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
|
||||
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
|
||||
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
|
||||
+ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
|
||||
#endif
|
||||
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
|
||||
dump_cfg_fmtint(sKbdInteractiveAuthentication,
|
||||
diff -up openssh-7.0p1/servconf.h.gsskexalg openssh-7.0p1/servconf.h
|
||||
--- openssh-7.0p1/servconf.h.gsskexalg 2015-08-19 12:28:38.080518834 +0200
|
||||
+++ openssh-7.0p1/servconf.h 2015-08-19 12:34:46.328693944 +0200
|
||||
@@ -122,6 +122,7 @@ typedef struct {
|
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
|
||||
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */
|
||||
int gss_store_rekey;
|
||||
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */
|
||||
int password_authentication; /* If true, permit password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* If true, permit */
|
||||
diff -up openssh-7.0p1/ssh.1.gsskexalg openssh-7.0p1/ssh.1
|
||||
--- openssh-7.0p1/ssh.1.gsskexalg 2015-08-19 12:28:38.081518832 +0200
|
||||
+++ openssh-7.0p1/ssh.1 2015-08-19 12:35:31.741591692 +0200
|
||||
@@ -496,6 +496,7 @@ For full details of the options listed b
|
||||
.It GSSAPIDelegateCredentials
|
||||
.It GSSAPIRenewalForcesRekey
|
||||
.It GSSAPITrustDNS
|
||||
+.It GSSAPIKexAlgorithms
|
||||
.It HashKnownHosts
|
||||
.It Host
|
||||
.It HostbasedAuthentication
|
||||
diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5
|
||||
--- openssh-7.0p1/ssh_config.5.gsskexalg 2015-08-19 12:28:38.028518950 +0200
|
||||
+++ openssh-7.0p1/ssh_config.5 2015-08-19 12:28:38.082518830 +0200
|
||||
@@ -786,6 +786,18 @@ command line will be passed untouched to
|
||||
command line will be passed untouched to the GSSAPI library.
|
||||
The default is
|
||||
.Dq no .
|
||||
+.It Cm GSSAPIKexAlgorithms
|
||||
+The list of key exchange algorithms that are offered for GSSAPI
|
||||
+key exchange. Possible values are
|
||||
+.Bd -literal -offset 3n
|
||||
+gss-gex-sha1-,
|
||||
+gss-group1-sha1-,
|
||||
+gss-group14-sha1-
|
||||
+.Ed
|
||||
+.Pp
|
||||
+The default is
|
||||
+.Dq gss-gex-sha1-,gss-group14-sha1- .
|
||||
+This option only applies to protocol version 2 connections using GSSAPI.
|
||||
.It Cm HashKnownHosts
|
||||
Indicates that
|
||||
.Xr ssh 1
|
||||
diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c
|
||||
--- openssh-7.0p1/sshconnect2.c.gsskexalg 2015-08-19 12:28:38.045518912 +0200
|
||||
+++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:28:38.081518832 +0200
|
||||
@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho
|
||||
else
|
||||
gss_host = host;
|
||||
|
||||
- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
|
||||
+ gss = ssh_gssapi_client_mechanisms(gss_host,
|
||||
+ options.gss_client_identity, options.gss_kex_algorithms);
|
||||
if (gss) {
|
||||
debug("Offering GSSAPI proposal: %s", gss);
|
||||
xasprintf(&options.kex_algorithms,
|
||||
--- openssh-7.1p1/sshd_config.5.gsskexalg 2015-12-10 15:32:48.105418092 +0100
|
||||
+++ openssh-7.1p1/sshd_config.5 2015-12-10 15:33:47.771279548 +0100
|
||||
@@ -663,6 +663,18 @@ or updated credentials from a compatible
|
||||
For this to work
|
||||
.Cm GSSAPIKeyExchange
|
||||
needs to be enabled in the server and also used by the client.
|
||||
+.It Cm GSSAPIKexAlgorithms
|
||||
+The list of key exchange algorithms that are accepted by GSSAPI
|
||||
+key exchange. Possible values are
|
||||
+.Bd -literal -offset 3n
|
||||
+gss-gex-sha1-,
|
||||
+gss-group1-sha1-,
|
||||
+gss-group14-sha1-
|
||||
+.Ed
|
||||
+.Pp
|
||||
+The default is
|
||||
+.Dq gss-gex-sha1-,gss-group14-sha1- .
|
||||
+This option only applies to protocol version 2 connections using GSSAPI.
|
||||
.It Cm HostbasedAcceptedKeyTypes
|
||||
Specifies the key types that will be accepted for hostbased authentication
|
||||
as a list of comma-separated patterns.
|
||||
diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h
|
||||
--- openssh-7.0p1/ssh-gss.h.gsskexalg 2015-08-19 12:28:38.031518944 +0200
|
||||
+++ openssh-7.0p1/ssh-gss.h 2015-08-19 12:28:38.081518832 +0200
|
||||
@@ -76,6 +76,10 @@ extern char **k5users_allowed_cmds;
|
||||
#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-"
|
||||
#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-"
|
||||
|
||||
+#define GSS_KEX_DEFAULT_KEX \
|
||||
+ KEX_GSS_GEX_SHA1_ID "," \
|
||||
+ KEX_GSS_GRP14_SHA1_ID
|
||||
+
|
||||
typedef struct {
|
||||
char *envvar;
|
||||
char *envval;
|
||||
@@ -147,9 +151,9 @@ int ssh_gssapi_credentials_updated(Gssct
|
||||
/* In the server */
|
||||
typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *,
|
||||
const char *);
|
||||
-char *ssh_gssapi_client_mechanisms(const char *, const char *);
|
||||
+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *);
|
||||
char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
|
||||
- const char *);
|
||||
+ const char *, const char *);
|
||||
gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
|
||||
int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *,
|
||||
const char *);
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
diff -up openssh-7.4p1/ssh_config.5.gss-docs openssh-7.4p1/ssh_config.5
|
||||
--- openssh-7.4p1/ssh_config.5.gss-docs 2016-12-23 14:28:34.051714486 +0100
|
||||
+++ openssh-7.4p1/ssh_config.5 2016-12-23 14:34:24.568522417 +0100
|
||||
@@ -765,10 +765,19 @@ The default is
|
||||
If set to
|
||||
.Dq yes
|
||||
then renewal of the client's GSSAPI credentials will force the rekeying of the
|
||||
-ssh connection. With a compatible server, this can delegate the renewed
|
||||
+ssh connection. With a compatible server, this will delegate the renewed
|
||||
credentials to a session on the server.
|
||||
+.Pp
|
||||
+Checks are made to ensure that credentials are only propagated when the new
|
||||
+credentials match the old ones on the originating client and where the
|
||||
+receiving server still has the old set in its cache.
|
||||
+.Pp
|
||||
The default is
|
||||
.Dq no .
|
||||
+.Pp
|
||||
+For this to work
|
||||
+.Cm GSSAPIKeyExchange
|
||||
+needs to be enabled in the server and also used by the client.
|
||||
.It Cm GSSAPIServerIdentity
|
||||
If set, specifies the GSSAPI server identity that ssh should expect when
|
||||
connecting to the server. The default is unset, which means that the
|
||||
@@ -776,9 +785,11 @@ expected GSSAPI server identity will be
|
||||
hostname.
|
||||
.It Cm GSSAPITrustDns
|
||||
Set to
|
||||
-.Dq yes to indicate that the DNS is trusted to securely canonicalize
|
||||
+.Dq yes
|
||||
+to indicate that the DNS is trusted to securely canonicalize
|
||||
the name of the host being connected to. If
|
||||
-.Dq no, the hostname entered on the
|
||||
+.Dq no ,
|
||||
+the hostname entered on the
|
||||
command line will be passed untouched to the GSSAPI library.
|
||||
The default is
|
||||
.Dq no .
|
||||
diff -up openssh-7.4p1/sshd_config.5.gss-docs openssh-7.4p1/sshd_config.5
|
||||
--- openssh-7.4p1/sshd_config.5.gss-docs 2016-12-23 14:28:34.043714490 +0100
|
||||
+++ openssh-7.4p1/sshd_config.5 2016-12-23 14:28:34.051714486 +0100
|
||||
@@ -652,6 +652,10 @@ Controls whether the user's GSSAPI crede
|
||||
successful connection rekeying. This option can be used to accepted renewed
|
||||
or updated credentials from a compatible client. The default is
|
||||
.Dq no .
|
||||
+.Pp
|
||||
+For this to work
|
||||
+.Cm GSSAPIKeyExchange
|
||||
+needs to be enabled in the server and also used by the client.
|
||||
.It Cm HostbasedAcceptedKeyTypes
|
||||
Specifies the key types that will be accepted for hostbased authentication
|
||||
as a list of comma-separated patterns.
|
||||
|
|
@ -56,9 +56,9 @@ diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h
|
|||
--- openssh-7.4p1/monitor_wrap.h.audit-race 2016-12-23 16:35:52.694685771 +0100
|
||||
+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 16:35:52.698685772 +0100
|
||||
@@ -83,6 +83,8 @@ void mm_audit_unsupported_body(int);
|
||||
void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
|
||||
void mm_audit_session_key_free_body(int, pid_t, uid_t);
|
||||
void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t);
|
||||
void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t);
|
||||
void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t);
|
||||
void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t);
|
||||
+int mm_forward_audit_messages(int);
|
||||
+void mm_set_monitor_pipe(int);
|
||||
#endif
|
||||
|
|
@ -82,7 +82,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
|
|||
return 1;
|
||||
}
|
||||
|
||||
+void child_destory_sensitive_data();
|
||||
+void child_destory_sensitive_data(struct ssh *ssh);
|
||||
+
|
||||
#define USE_PIPES 1
|
||||
/*
|
||||
|
|
@ -91,7 +91,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
|
|||
close(err[0]);
|
||||
#endif
|
||||
|
||||
+ child_destory_sensitive_data();
|
||||
+ child_destory_sensitive_data(ssh);
|
||||
+
|
||||
/* Do processing for the child (exec command etc). */
|
||||
do_child(ssh, s, command);
|
||||
|
|
@ -101,7 +101,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
|
|||
close(ttyfd);
|
||||
|
||||
+ /* Do this early, so we will not block large MOTDs */
|
||||
+ child_destory_sensitive_data();
|
||||
+ child_destory_sensitive_data(ssh);
|
||||
+
|
||||
/* record login, etc. similar to login(1) */
|
||||
#ifndef HAVE_OSF_SIA
|
||||
|
|
@ -109,7 +109,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
|
|||
@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command)
|
||||
}
|
||||
if (s->command != NULL && s->ptyfd == -1)
|
||||
s->command_handle = PRIVSEP(audit_run_command(s->command));
|
||||
s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
|
||||
+ if (pipe(paudit) < 0)
|
||||
+ fatal("pipe: %s", strerror(errno));
|
||||
#endif
|
||||
|
|
@ -141,7 +141,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
|
|||
}
|
||||
|
||||
+void
|
||||
+child_destory_sensitive_data()
|
||||
+child_destory_sensitive_data(struct ssh *ssh)
|
||||
+{
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ int pparent = paudit[1];
|
||||
|
|
@ -152,15 +152,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
|
|||
+#endif
|
||||
+
|
||||
+ /* remove hostkey from the child's memory */
|
||||
+ destroy_sensitive_data(use_privsep);
|
||||
+ destroy_sensitive_data(ssh, use_privsep);
|
||||
+ /*
|
||||
+ * We can audit this, because we hacked the pipe to direct the
|
||||
+ * messages over postauth child. But this message requires answer
|
||||
+ * which we can't do using one-way pipe.
|
||||
+ */
|
||||
+ packet_destroy_all(0, 1);
|
||||
+ packet_destroy_all(ssh, 0, 1);
|
||||
+ /* XXX this will clean the rest but should not audit anymore */
|
||||
+ /* packet_clear_keys(); */
|
||||
+ /* packet_clear_keys(ssh); */
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ /* Notify parent that we are done */
|
||||
|
|
@ -172,15 +172,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
|
|||
* Performs common processing for the child, such as setting up the
|
||||
* environment, closing extra file descriptors, setting the user and group
|
||||
@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command
|
||||
struct passwd *pw = s->pw;
|
||||
int r = 0;
|
||||
|
||||
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
|
||||
|
||||
- /* remove hostkey from the child's memory */
|
||||
- destroy_sensitive_data(1);
|
||||
- packet_clear_keys();
|
||||
- destroy_sensitive_data(ssh, 1);
|
||||
- ssh_packet_clear_keys(ssh);
|
||||
- /* Don't audit this - both us and the parent would be talking to the
|
||||
- monitor over a single socket, with no synchronization. */
|
||||
- packet_destroy_all(0, 1);
|
||||
- packet_destroy_all(ssh, 0, 1);
|
||||
-
|
||||
/* Force a password change */
|
||||
if (s->authctxt->force_pwchange) {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ diff --git a/auth-krb5.c b/auth-krb5.c
|
|||
index 2b02a04..19b9364 100644
|
||||
--- a/auth-krb5.c
|
||||
+++ b/auth-krb5.c
|
||||
@@ -375,6 +375,22 @@ cleanup:
|
||||
return -1;
|
||||
@@ -375,5 +375,21 @@ cleanup:
|
||||
return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
}
|
||||
}
|
||||
|
||||
+
|
||||
+/*
|
||||
+ * Reads k5login_directory option from the krb5.conf
|
||||
+ */
|
||||
|
|
@ -21,10 +22,8 @@ index 2b02a04..19b9364 100644
|
|||
+ return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL,
|
||||
+ k5login_directory);
|
||||
+}
|
||||
+
|
||||
krb5_error_code
|
||||
ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
|
||||
profile_t p;
|
||||
#endif /* !HEIMDAL */
|
||||
#endif /* KRB5 */
|
||||
diff --git a/auth.h b/auth.h
|
||||
index f9d191c..c432d2f 100644
|
||||
--- a/auth.h
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -20,8 +20,8 @@ index ca75cc7..6e7de31 100644
|
|||
+#if defined(__NR_flock) && defined(__s390__)
|
||||
+ SC_ALLOW(__NR_flock),
|
||||
+#endif
|
||||
#ifdef __NR_geteuid
|
||||
SC_ALLOW(__NR_geteuid),
|
||||
#ifdef __NR_futex
|
||||
SC_ALLOW(__NR_futex),
|
||||
#endif
|
||||
@@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = {
|
||||
#ifdef __NR_gettimeofday
|
||||
|
|
@ -106,3 +106,41 @@ diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-se
|
|||
#ifdef __NR_getrandom
|
||||
SC_ALLOW(__NR_getrandom),
|
||||
#endif
|
||||
|
||||
|
||||
From ef34ea4521b042dd8a9c4c7455f5d1a8f8ee5bb2 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Freudenberger <freude@linux.ibm.com>
|
||||
Date: Fri, 24 May 2019 10:11:15 +0200
|
||||
Subject: [PATCH] allow s390 specific ioctl for ecc hardware support
|
||||
|
||||
Adding another s390 specific ioctl to be able to support ECC hardware acceleration
|
||||
to the sandbox seccomp filter rules.
|
||||
|
||||
Now the ibmca openssl engine provides elliptic curve cryptography support with the
|
||||
help of libica and CCA crypto cards. This is done via jet another ioctl call to the zcrypt
|
||||
device driver and so there is a need to enable this on the openssl sandbox.
|
||||
|
||||
Code is s390 specific and has been tested, verified and reviewed.
|
||||
|
||||
Please note that I am also the originator of the previous changes in that area.
|
||||
I posted these changes to Eduardo and he forwarded the patches to the openssl
|
||||
community.
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
|
||||
Reviewed-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
|
||||
---
|
||||
sandbox-seccomp-filter.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
|
||||
index 5edbc6946..56eb9317f 100644
|
||||
--- a/sandbox-seccomp-filter.c
|
||||
+++ b/sandbox-seccomp-filter.c
|
||||
@@ -252,6 +252,7 @@ static const struct sock_filter preauth_insns[] = {
|
||||
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT),
|
||||
/* Allow ioctls for EP11 crypto card on s390 */
|
||||
SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB),
|
||||
+ SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB),
|
||||
#endif
|
||||
#if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT)
|
||||
/*
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
|
||||
--- openssh/auth2-pubkey.c.refactor 2017-09-27 13:10:19.556830609 +0200
|
||||
+++ openssh/auth2-pubkey.c 2017-09-27 13:10:19.677831274 +0200
|
||||
--- openssh/auth2-pubkey.c.refactor 2019-04-04 13:19:12.188821236 +0200
|
||||
+++ openssh/auth2-pubkey.c 2019-04-04 13:19:12.276822078 +0200
|
||||
@@ -72,6 +72,9 @@
|
||||
extern ServerOptions options;
|
||||
extern u_char *session_id2;
|
||||
|
|
@ -11,7 +11,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
|
|||
|
||||
static char *
|
||||
format_key(const struct sshkey *key)
|
||||
@@ -432,7 +435,8 @@ match_principals_command(struct passwd *
|
||||
@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
|
||||
|
||||
if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command,
|
||||
ac, av, &f,
|
||||
|
|
@ -21,7 +21,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
|
|||
goto out;
|
||||
|
||||
uid_swapped = 1;
|
||||
@@ -762,7 +766,8 @@ user_key_command_allowed2(struct passwd
|
||||
@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
|
||||
|
||||
if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command,
|
||||
ac, av, &f,
|
||||
|
|
@ -32,9 +32,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
|
|||
|
||||
uid_swapped = 1;
|
||||
diff -up openssh/auth.c.refactor openssh/auth.c
|
||||
--- openssh/auth.c.refactor 2017-09-27 13:10:19.640831071 +0200
|
||||
+++ openssh/auth.c 2017-09-27 13:10:19.678831279 +0200
|
||||
@@ -1435,7 +1435,8 @@ argv_assemble(int argc, char **argv)
|
||||
--- openssh/auth.c.refactor 2019-04-04 13:19:12.235821686 +0200
|
||||
+++ openssh/auth.c 2019-04-04 13:19:12.276822078 +0200
|
||||
@@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh *
|
||||
*/
|
||||
pid_t
|
||||
subprocess(const char *tag, struct passwd *pw, const char *command,
|
||||
|
|
@ -44,7 +44,7 @@ diff -up openssh/auth.c.refactor openssh/auth.c
|
|||
{
|
||||
FILE *f = NULL;
|
||||
struct stat st;
|
||||
@@ -1551,7 +1552,7 @@ subprocess(const char *tag, struct passw
|
||||
@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
|
||||
}
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
|
|
@ -54,9 +54,9 @@ diff -up openssh/auth.c.refactor openssh/auth.c
|
|||
strerror(errno));
|
||||
_exit(127);
|
||||
diff -up openssh/auth.h.refactor openssh/auth.h
|
||||
--- openssh/auth.h.refactor 2017-09-25 01:48:10.000000000 +0200
|
||||
+++ openssh/auth.h 2017-09-27 13:10:19.678831279 +0200
|
||||
@@ -144,7 +144,7 @@ int exited_cleanly(pid_t, const char *,
|
||||
--- openssh/auth.h.refactor 2019-04-04 13:19:12.251821839 +0200
|
||||
+++ openssh/auth.h 2019-04-04 13:19:12.276822078 +0200
|
||||
@@ -235,7 +235,7 @@ struct passwd *fakepw(void);
|
||||
#define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */
|
||||
#define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */
|
||||
pid_t subprocess(const char *, struct passwd *,
|
||||
|
|
@ -66,8 +66,8 @@ diff -up openssh/auth.h.refactor openssh/auth.h
|
|||
int sys_auth_passwd(struct ssh *, const char *);
|
||||
|
||||
diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h
|
||||
--- openssh/openbsd-compat/port-linux.h.refactor 2017-09-27 13:10:19.634831038 +0200
|
||||
+++ openssh/openbsd-compat/port-linux.h 2017-09-27 13:10:54.954025248 +0200
|
||||
--- openssh/openbsd-compat/port-linux.h.refactor 2019-04-04 13:19:12.256821887 +0200
|
||||
+++ openssh/openbsd-compat/port-linux.h 2019-04-04 13:19:12.276822078 +0200
|
||||
@@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch
|
||||
|
||||
int sshd_selinux_enabled(void);
|
||||
|
|
@ -80,9 +80,9 @@ diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/por
|
|||
#endif
|
||||
|
||||
diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c
|
||||
--- openssh/openbsd-compat/port-linux-sshd.c.refactor 2017-09-27 13:10:19.634831038 +0200
|
||||
+++ openssh/openbsd-compat/port-linux-sshd.c 2017-09-27 13:12:06.811420371 +0200
|
||||
@@ -48,11 +48,6 @@
|
||||
--- openssh/openbsd-compat/port-linux-sshd.c.refactor 2019-04-04 13:19:12.256821887 +0200
|
||||
+++ openssh/openbsd-compat/port-linux-sshd.c 2019-04-04 13:19:12.276822078 +0200
|
||||
@@ -49,11 +49,6 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
/* Wrapper around is_selinux_enabled() to log its return value once only */
|
||||
int
|
||||
sshd_selinux_enabled(void)
|
||||
@@ -222,7 +217,8 @@ get_user_context(const char *sename, con
|
||||
@@ -223,7 +218,8 @@ get_user_context(const char *sename, con
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -104,7 +104,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
{
|
||||
*role = NULL;
|
||||
*level = NULL;
|
||||
@@ -240,8 +236,8 @@ ssh_selinux_get_role_level(char **role,
|
||||
@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
|
||||
|
||||
/* Return the default security context for the given username */
|
||||
static int
|
||||
|
|
@ -115,7 +115,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
{
|
||||
char *sename, *lvl;
|
||||
char *role;
|
||||
@@ -249,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
int r = 0;
|
||||
context_t con = NULL;
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
|
||||
#ifdef HAVE_GETSEUSERBYNAME
|
||||
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
|
||||
@@ -271,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
|
||||
if (r == 0) {
|
||||
/* If launched from xinetd, we must use current level */
|
||||
|
|
@ -133,7 +133,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
security_context_t sshdsc=NULL;
|
||||
|
||||
if (getcon_raw(&sshdsc) < 0)
|
||||
@@ -332,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
|
||||
/* Setup environment variables for pam_selinux */
|
||||
static int
|
||||
|
|
@ -143,7 +143,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
{
|
||||
const char *reqlvl;
|
||||
char *role;
|
||||
@@ -341,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it
|
||||
@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
|
||||
|
||||
debug3("%s: setting execution context", __func__);
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
use_current = "1";
|
||||
} else {
|
||||
use_current = "";
|
||||
@@ -361,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it
|
||||
@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -170,7 +170,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
}
|
||||
|
||||
static int
|
||||
@@ -373,25 +371,28 @@ do_setenv(char *name, const char *value)
|
||||
@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -204,7 +204,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
switch (security_getenforce()) {
|
||||
case -1:
|
||||
fatal("%s: security_getenforce() failed", __func__);
|
||||
@@ -409,7 +410,7 @@ sshd_selinux_setup_exec_context(char *pw
|
||||
@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
|
||||
|
||||
debug3("%s: setting execution context", __func__);
|
||||
|
||||
|
|
@ -214,9 +214,9 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
|
|||
r = setexeccon(user_ctx);
|
||||
if (r < 0) {
|
||||
diff -up openssh/platform.c.refactor openssh/platform.c
|
||||
--- openssh/platform.c.refactor 2017-09-27 13:10:19.574830708 +0200
|
||||
+++ openssh/platform.c 2017-09-27 13:11:45.475303050 +0200
|
||||
@@ -33,6 +33,9 @@
|
||||
--- openssh/platform.c.refactor 2019-04-04 13:19:12.204821389 +0200
|
||||
+++ openssh/platform.c 2019-04-04 13:19:12.277822088 +0200
|
||||
@@ -32,6 +32,9 @@
|
||||
|
||||
extern int use_privsep;
|
||||
extern ServerOptions options;
|
||||
|
|
@ -226,7 +226,7 @@ diff -up openssh/platform.c.refactor openssh/platform.c
|
|||
|
||||
void
|
||||
platform_pre_listen(void)
|
||||
@@ -184,7 +187,9 @@ platform_setusercontext_post_groups(stru
|
||||
@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru
|
||||
}
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef WITH_SELINUX
|
||||
|
|
@ -238,9 +238,27 @@ diff -up openssh/platform.c.refactor openssh/platform.c
|
|||
}
|
||||
|
||||
diff -up openssh/sshd.c.refactor openssh/sshd.c
|
||||
--- openssh/sshd.c.refactor 2017-09-27 13:10:19.674831257 +0200
|
||||
+++ openssh/sshd.c 2017-09-27 13:12:01.635391909 +0200
|
||||
@@ -2135,7 +2135,9 @@ main(int ac, char **av)
|
||||
--- openssh/sshd.c.refactor 2019-04-04 13:19:12.275822068 +0200
|
||||
+++ openssh/sshd.c 2019-04-04 13:19:51.270195262 +0200
|
||||
@@ -158,7 +158,7 @@ int debug_flag = 0;
|
||||
static int test_flag = 0;
|
||||
|
||||
/* Flag indicating that the daemon is being started from inetd. */
|
||||
-static int inetd_flag = 0;
|
||||
+int inetd_flag = 0;
|
||||
|
||||
/* Flag indicating that sshd should not detach and become a daemon. */
|
||||
static int no_daemon_flag = 0;
|
||||
@@ -171,7 +171,7 @@ static char **saved_argv;
|
||||
static int saved_argc;
|
||||
|
||||
/* re-exec */
|
||||
-static int rexeced_flag = 0;
|
||||
+int rexeced_flag = 0;
|
||||
static int rexec_flag = 1;
|
||||
static int rexec_argc = 0;
|
||||
static char **rexec_argv;
|
||||
@@ -2192,7 +2192,9 @@ main(int ac, char **av)
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_SELINUX
|
||||
|
|
|
|||
|
|
@ -1,801 +0,0 @@
|
|||
diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-client.c
|
||||
--- openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa 2018-02-16 13:25:59.426469253 +0100
|
||||
+++ openssh-7.6p1/ssh-pkcs11-client.c 2018-02-16 13:25:59.428469265 +0100
|
||||
@@ -31,6 +31,15 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+#include <openssl/ecdsa.h>
|
||||
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
|
||||
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
|
||||
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+#define ENABLE_PKCS11_ECDSA 1
|
||||
+#endif
|
||||
+#endif
|
||||
|
||||
#include "pathnames.h"
|
||||
#include "xmalloc.h"
|
||||
@@ -139,9 +147,9 @@ pkcs11_rsa_private_encrypt(int flen, con
|
||||
return (ret);
|
||||
}
|
||||
|
||||
-/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
|
||||
+/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */
|
||||
static int
|
||||
-wrap_key(RSA *rsa)
|
||||
+wrap_rsa_key(RSA *rsa)
|
||||
{
|
||||
static RSA_METHOD helper_rsa;
|
||||
|
||||
@@ -152,6 +160,88 @@ wrap_key(RSA *rsa)
|
||||
return (0);
|
||||
}
|
||||
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static ECDSA_SIG *
|
||||
+pkcs11_ecdsa_private_sign(const unsigned char *from, int flen,
|
||||
+ const BIGNUM *inv, const BIGNUM *rp, EC_KEY * ecdsa)
|
||||
+{
|
||||
+ struct sshkey *key = NULL;
|
||||
+ u_char *blob, *signature = NULL;
|
||||
+ size_t blen, slen = 0;
|
||||
+ struct sshbuf *msg = NULL;
|
||||
+ ECDSA_SIG *ret = NULL;
|
||||
+ BIGNUM *r = NULL, *s = NULL;
|
||||
+ int rv;
|
||||
+
|
||||
+ if ((key = sshkey_new(KEY_ECDSA)) == NULL)
|
||||
+ fatal("%s: sshkey_new failed", __func__);
|
||||
+ key->ecdsa = ecdsa;
|
||||
+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
|
||||
+ if (sshkey_to_blob(key, &blob, &blen) == 0)
|
||||
+ goto out;
|
||||
+ if ((msg = sshbuf_new()) == NULL)
|
||||
+ fatal("%s: sshbuf_new failed", __func__);
|
||||
+ if ((rv = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
|
||||
+ (rv = sshbuf_put_string(msg, blob, blen)) != 0 ||
|
||||
+ (rv = sshbuf_put_string(msg, from, flen)) != 0 ||
|
||||
+ (rv = sshbuf_put_u32(msg, 0)) != 0)
|
||||
+ fatal("%s: buffer error: %s", __func__, ssh_err(rv));
|
||||
+ free(blob);
|
||||
+ send_msg(msg);
|
||||
+ sshbuf_reset(msg);
|
||||
+
|
||||
+ if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
|
||||
+ if ((rv = sshbuf_get_string(msg, &signature, &slen)) != 0)
|
||||
+ fatal("%s: buffer error: %s", __func__, ssh_err(rv));
|
||||
+ if (slen <= (size_t)ECDSA_size(ecdsa)) {
|
||||
+ int nlen = slen / 2;
|
||||
+ ret = ECDSA_SIG_new();
|
||||
+ r = BN_new();
|
||||
+ s = BN_new();
|
||||
+ BN_bin2bn(&signature[0], nlen, r);
|
||||
+ BN_bin2bn(&signature[nlen], nlen, s);
|
||||
+ ECDSA_SIG_set0(ret, r, s);
|
||||
+ }
|
||||
+ free(signature);
|
||||
+ }
|
||||
+out:
|
||||
+ sshkey_free(key);
|
||||
+ sshbuf_free(msg);
|
||||
+ return (ret);
|
||||
+}
|
||||
+
|
||||
+/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */
|
||||
+static int
|
||||
+wrap_ecdsa_key(EC_KEY *ecdsa) {
|
||||
+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ static EC_KEY_METHOD *helper_ecdsa = NULL;
|
||||
+ if (helper_ecdsa == NULL) {
|
||||
+ const EC_KEY_METHOD *def = EC_KEY_get_default_method();
|
||||
+ helper_ecdsa = EC_KEY_METHOD_new(def);
|
||||
+ EC_KEY_METHOD_set_sign(helper_ecdsa, NULL, NULL, pkcs11_ecdsa_private_sign);
|
||||
+ }
|
||||
+ EC_KEY_set_method(ecdsa, helper_ecdsa);
|
||||
+#else
|
||||
+ static ECDSA_METHOD *helper_ecdsa = NULL;
|
||||
+ if(helper_ecdsa == NULL) {
|
||||
+ const ECDSA_METHOD *def = ECDSA_get_default_method();
|
||||
+# ifdef ECDSA_F_ECDSA_METHOD_NEW
|
||||
+ helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def);
|
||||
+ ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa");
|
||||
+ ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign);
|
||||
+# else
|
||||
+ helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa));
|
||||
+ memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa));
|
||||
+ helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa";
|
||||
+ helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign;
|
||||
+# endif
|
||||
+ }
|
||||
+ ECDSA_set_method(ecdsa, helper_ecdsa);
|
||||
+#endif
|
||||
+ return (0);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int
|
||||
pkcs11_start_helper(void)
|
||||
{
|
||||
@@ -212,7 +281,15 @@ pkcs11_add_provider(char *name, char *pi
|
||||
__func__, ssh_err(r));
|
||||
if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
|
||||
fatal("%s: bad key: %s", __func__, ssh_err(r));
|
||||
- wrap_key(k->rsa);
|
||||
+ if(k->type == KEY_RSA) {
|
||||
+ wrap_rsa_key(k->rsa);
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if(k->type == KEY_ECDSA) {
|
||||
+ wrap_ecdsa_key(k->ecdsa);
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ } else {
|
||||
+ /* Unsupported type */
|
||||
+ }
|
||||
(*keysp)[i] = k;
|
||||
free(blob);
|
||||
}
|
||||
diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c
|
||||
--- openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa 2018-02-16 13:25:59.427469259 +0100
|
||||
+++ openssh-7.6p1/ssh-pkcs11.c 2018-02-16 13:44:51.270554797 +0100
|
||||
@@ -32,6 +32,16 @@
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include <openssl/x509.h>
|
||||
+#include <openssl/rsa.h>
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+#include <openssl/ecdsa.h>
|
||||
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
|
||||
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
|
||||
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+#define ENABLE_PKCS11_ECDSA 1
|
||||
+#endif
|
||||
+#endif
|
||||
|
||||
#define CRYPTOKI_COMPAT
|
||||
#include "pkcs11.h"
|
||||
@@ -67,6 +76,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro
|
||||
struct pkcs11_key {
|
||||
struct pkcs11_provider *provider;
|
||||
CK_ULONG slotidx;
|
||||
+ CK_ULONG key_type;
|
||||
int (*orig_finish)(RSA *rsa);
|
||||
RSA_METHOD rsa_method;
|
||||
char *keyid;
|
||||
@@ -75,6 +85,9 @@ struct pkcs11_key {
|
||||
};
|
||||
|
||||
int pkcs11_interactive = 0;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static int pkcs11_key_idx = -1;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
|
||||
/*
|
||||
* This can't be in the ssh-pkcs11-uri, becase we can not depend on
|
||||
@@ -289,6 +302,40 @@ pkcs11_find(struct pkcs11_provider *p, C
|
||||
return (ret);
|
||||
}
|
||||
|
||||
+int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) {
|
||||
+ char *pin = NULL, prompt[1024];
|
||||
+ CK_RV rv;
|
||||
+ if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
|
||||
+ if (!pkcs11_interactive) {
|
||||
+ error("need pin entry%s", (si->token.flags &
|
||||
+ CKF_PROTECTED_AUTHENTICATION_PATH) ?
|
||||
+ " on reader keypad" : "");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||
+ verbose("Deferring PIN entry to reader keypad.");
|
||||
+ else {
|
||||
+ snprintf(prompt, sizeof(prompt),
|
||||
+ "Enter PIN for '%s': ", si->token.label);
|
||||
+ pin = read_passphrase(prompt, RP_ALLOW_EOF);
|
||||
+ if (pin == NULL)
|
||||
+ return (-1); /* bail out */
|
||||
+ }
|
||||
+ rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
|
||||
+ (pin != NULL) ? strlen(pin) : 0);
|
||||
+ if (pin != NULL) {
|
||||
+ explicit_bzero(pin, strlen(pin));
|
||||
+ free(pin);
|
||||
+ }
|
||||
+ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
|
||||
+ error("C_Login failed: %lu", rv);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ si->logged_in = 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* openssl callback doing the actual signing operation */
|
||||
static int
|
||||
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
|
||||
@@ -310,7 +357,6 @@ pkcs11_rsa_private_encrypt(int flen, con
|
||||
{CKA_ID, NULL, 0},
|
||||
{CKA_SIGN, NULL, sizeof(true_val) }
|
||||
};
|
||||
- char *pin = NULL, prompt[1024];
|
||||
int rval = -1;
|
||||
|
||||
key_filter[0].pValue = &private_key_class;
|
||||
@@ -326,33 +372,8 @@ pkcs11_rsa_private_encrypt(int flen, con
|
||||
}
|
||||
f = k11->provider->module->function_list;
|
||||
si = &k11->provider->module->slotinfo[k11->slotidx];
|
||||
- if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
|
||||
- if (!pkcs11_interactive) {
|
||||
- error("need pin entry%s", (si->token.flags &
|
||||
- CKF_PROTECTED_AUTHENTICATION_PATH) ?
|
||||
- " on reader keypad" : "");
|
||||
- return (-1);
|
||||
- }
|
||||
- if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||
- verbose("Deferring PIN entry to reader keypad.");
|
||||
- else {
|
||||
- snprintf(prompt, sizeof(prompt),
|
||||
- "Enter PIN for '%s': ", si->token.label);
|
||||
- pin = read_passphrase(prompt, RP_ALLOW_EOF);
|
||||
- if (pin == NULL)
|
||||
- return (-1); /* bail out */
|
||||
- }
|
||||
- rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
|
||||
- (pin != NULL) ? strlen(pin) : 0);
|
||||
- if (pin != NULL) {
|
||||
- explicit_bzero(pin, strlen(pin));
|
||||
- free(pin);
|
||||
- }
|
||||
- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
|
||||
- error("C_Login failed: %lu", rv);
|
||||
- return (-1);
|
||||
- }
|
||||
- si->logged_in = 1;
|
||||
+ if(pkcs11_login(k11, f, si)) {
|
||||
+ return (-1);
|
||||
}
|
||||
key_filter[1].pValue = k11->keyid;
|
||||
key_filter[1].ulValueLen = k11->keyid_len;
|
||||
@@ -390,6 +411,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
|
||||
const RSA_METHOD *def = RSA_get_default_method();
|
||||
|
||||
k11 = xcalloc(1, sizeof(*k11));
|
||||
+ k11->key_type = CKK_RSA;
|
||||
k11->provider = provider;
|
||||
provider->refcount++; /* provider referenced by RSA key */
|
||||
k11->slotidx = slotidx;
|
||||
@@ -415,6 +437,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
|
||||
return (0);
|
||||
}
|
||||
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len,
|
||||
+ const BIGNUM *inv, const BIGNUM *rp,
|
||||
+ EC_KEY *ecdsa) {
|
||||
+ struct pkcs11_key *k11;
|
||||
+ struct pkcs11_slotinfo *si;
|
||||
+ CK_FUNCTION_LIST *f;
|
||||
+ CK_OBJECT_HANDLE obj;
|
||||
+ CK_ULONG tlen = 0;
|
||||
+ CK_RV rv;
|
||||
+ CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY;
|
||||
+ CK_BBOOL true_val = CK_TRUE;
|
||||
+ CK_MECHANISM mech = {
|
||||
+ CKM_ECDSA, NULL_PTR, 0
|
||||
+ };
|
||||
+ CK_ATTRIBUTE key_filter[] = {
|
||||
+ {CKA_CLASS, NULL, sizeof(private_key_class) },
|
||||
+ {CKA_ID, NULL, 0},
|
||||
+ {CKA_SIGN, NULL, sizeof(true_val) }
|
||||
+ };
|
||||
+ ECDSA_SIG *rval = NULL;
|
||||
+ key_filter[0].pValue = &private_key_class;
|
||||
+ key_filter[2].pValue = &true_val;
|
||||
+
|
||||
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ if ((k11 = (struct pkcs11_key *)EC_KEY_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
|
||||
+ error("EC_KEY_get_ex_data failed for ecdsa %p", ecdsa);
|
||||
+ #else
|
||||
+ if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
|
||||
+ error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa);
|
||||
+ #endif
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (!k11->provider || !k11->provider->valid) {
|
||||
+ error("no pkcs11 (valid) provider for ecdsa %p", ecdsa);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ f = k11->provider->module->function_list;
|
||||
+ si = &k11->provider->module->slotinfo[k11->slotidx];
|
||||
+ if(pkcs11_login(k11, f, si)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ key_filter[1].pValue = k11->keyid;
|
||||
+ key_filter[1].ulValueLen = k11->keyid_len;
|
||||
+ /* try to find object w/CKA_SIGN first, retry w/o */
|
||||
+ if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
|
||||
+ pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
|
||||
+ error("cannot find private key");
|
||||
+ } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
|
||||
+ error("C_SignInit failed: %lu", rv);
|
||||
+ } else {
|
||||
+ CK_BYTE_PTR buf = NULL;
|
||||
+ BIGNUM *r = NULL, *s = NULL;
|
||||
+ int nlen;
|
||||
+ /* Make a call to C_Sign to find out the size of the signature */
|
||||
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ error("C_Sign failed: %lu", rv);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if ((buf = xmalloc(tlen)) == NULL) {
|
||||
+ error("failure to allocate signature buffer");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ error("C_Sign failed: %lu", rv);
|
||||
+ }
|
||||
+
|
||||
+ if ((rval = ECDSA_SIG_new()) == NULL ||
|
||||
+ (r = BN_new()) == NULL ||
|
||||
+ (s = BN_new()) == NULL) {
|
||||
+ error("failure to allocate ECDSA signature");
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * ECDSA signature is 2 large integers of same size returned
|
||||
+ * concatenated by PKCS#11, we separate them to create an
|
||||
+ * ECDSA_SIG for OpenSSL.
|
||||
+ */
|
||||
+ nlen = tlen / 2;
|
||||
+ BN_bin2bn(&buf[0], nlen, r);
|
||||
+ BN_bin2bn(&buf[nlen], nlen, s);
|
||||
+ ECDSA_SIG_set0(rval, r, s);
|
||||
+ }
|
||||
+ free(buf);
|
||||
+ }
|
||||
+ return (rval);
|
||||
+}
|
||||
+
|
||||
+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+static EC_KEY_METHOD *get_pkcs11_ecdsa_method(void) {
|
||||
+ static EC_KEY_METHOD *pkcs11_ecdsa_method = NULL;
|
||||
+ if(pkcs11_key_idx == -1) {
|
||||
+ pkcs11_key_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0);
|
||||
+ }
|
||||
+ if (pkcs11_ecdsa_method == NULL) {
|
||||
+ const EC_KEY_METHOD *def = EC_KEY_get_default_method();
|
||||
+ pkcs11_ecdsa_method = EC_KEY_METHOD_new(def);
|
||||
+ EC_KEY_METHOD_set_sign(pkcs11_ecdsa_method, NULL, NULL, pkcs11_ecdsa_sign);
|
||||
+ }
|
||||
+#else
|
||||
+static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) {
|
||||
+ static ECDSA_METHOD *pkcs11_ecdsa_method = NULL;
|
||||
+ if(pkcs11_key_idx == -1) {
|
||||
+ pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
|
||||
+ }
|
||||
+ if(pkcs11_ecdsa_method == NULL) {
|
||||
+ const ECDSA_METHOD *def = ECDSA_get_default_method();
|
||||
+ #ifdef ECDSA_F_ECDSA_METHOD_NEW
|
||||
+ pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def);
|
||||
+ ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11");
|
||||
+ ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign);
|
||||
+ #else
|
||||
+ pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method));
|
||||
+ memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method));
|
||||
+ pkcs11_ecdsa_method->name = "pkcs11";
|
||||
+ pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign;
|
||||
+ #endif
|
||||
+ }
|
||||
+#endif
|
||||
+ return pkcs11_ecdsa_method;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
|
||||
+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ecdsa)
|
||||
+{
|
||||
+ struct pkcs11_key *k11;
|
||||
+ k11 = xcalloc(1, sizeof(*k11));
|
||||
+ k11->key_type = CKK_EC;
|
||||
+ k11->provider = provider;
|
||||
+ provider->refcount++; /* provider referenced by ECDSA key */
|
||||
+ k11->slotidx = slotidx;
|
||||
+ /* identify key object on smartcard */
|
||||
+ k11->keyid_len = keyid_attrib->ulValueLen;
|
||||
+ if (k11->keyid_len > 0) {
|
||||
+ k11->keyid = xmalloc(k11->keyid_len);
|
||||
+ memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
|
||||
+ }
|
||||
+ if (label_attrib->ulValueLen > 0 ) {
|
||||
+ k11->label = xmalloc(label_attrib->ulValueLen+1);
|
||||
+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen);
|
||||
+ k11->label[label_attrib->ulValueLen] = 0;
|
||||
+ }
|
||||
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ EC_KEY_set_method(ecdsa, get_pkcs11_ecdsa_method());
|
||||
+ EC_KEY_set_ex_data(ecdsa, pkcs11_key_idx, k11);
|
||||
+ #else
|
||||
+ ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method());
|
||||
+ ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11);
|
||||
+ #endif
|
||||
+ return (0);
|
||||
+}
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+
|
||||
+int pkcs11_del_key(struct sshkey *key) {
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ if(key->type == KEY_ECDSA) {
|
||||
+ struct pkcs11_key *k11 = (struct pkcs11_key *)
|
||||
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+ EC_KEY_get_ex_data(key->ecdsa, pkcs11_key_idx);
|
||||
+ #else
|
||||
+ ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx);
|
||||
+ #endif
|
||||
+ if (k11 == NULL) {
|
||||
+ error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa);
|
||||
+ } else {
|
||||
+ if (k11->provider)
|
||||
+ pkcs11_provider_unref(k11->provider);
|
||||
+ free(k11->keyid);
|
||||
+ free(k11);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ sshkey_free(key);
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
/* remove trailing spaces */
|
||||
static void
|
||||
rmspace(u_char *buf, size_t len)
|
||||
@@ -482,11 +646,13 @@ static int
|
||||
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri)
|
||||
{
|
||||
- size_t filter_size = 1;
|
||||
+ size_t filter_size = 2;
|
||||
+ CK_KEY_TYPE pubkey_type = CKK_RSA;
|
||||
CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
|
||||
CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
|
||||
CK_ATTRIBUTE pubkey_filter[] = {
|
||||
{ CKA_CLASS, NULL, sizeof(pubkey_class) },
|
||||
+ { CKA_KEY_TYPE, NULL, sizeof(pubkey_type) },
|
||||
{ CKA_ID, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
@@ -507,29 +673,60 @@ pkcs11_fetch_keys(struct pkcs11_provider
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 }
|
||||
};
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ CK_KEY_TYPE ecdsa_type = CKK_EC;
|
||||
+ CK_ATTRIBUTE ecdsa_filter[] = {
|
||||
+ { CKA_CLASS, NULL, sizeof(pubkey_class) },
|
||||
+ { CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) },
|
||||
+ { CKA_ID, NULL, 0 },
|
||||
+ { CKA_LABEL, NULL, 0 }
|
||||
+ };
|
||||
+ CK_ATTRIBUTE ecdsa_attribs[] = {
|
||||
+ { CKA_ID, NULL, 0 },
|
||||
+ { CKA_LABEL, NULL, 0 },
|
||||
+ { CKA_EC_PARAMS, NULL, 0 },
|
||||
+ { CKA_EC_POINT, NULL, 0 }
|
||||
+ };
|
||||
+ ecdsa_filter[0].pValue = &pubkey_class;
|
||||
+ ecdsa_filter[1].pValue = &ecdsa_type;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
pubkey_filter[0].pValue = &pubkey_class;
|
||||
+ pubkey_filter[1].pValue = &pubkey_type;
|
||||
cert_filter[0].pValue = &cert_class;
|
||||
|
||||
if (uri->id != NULL) {
|
||||
pubkey_filter[filter_size].pValue = uri->id;
|
||||
pubkey_filter[filter_size].ulValueLen = uri->id_len;
|
||||
- cert_filter[filter_size].pValue = uri->id;
|
||||
- cert_filter[filter_size].ulValueLen = uri->id_len;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ ecdsa_filter[filter_size].pValue = uri->id;
|
||||
+ ecdsa_filter[filter_size].ulValueLen = uri->id_len;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ cert_filter[filter_size-1].pValue = uri->id;
|
||||
+ cert_filter[filter_size-1].ulValueLen = uri->id_len;
|
||||
filter_size++;
|
||||
}
|
||||
if (uri->object != NULL) {
|
||||
pubkey_filter[filter_size].pValue = uri->object;
|
||||
pubkey_filter[filter_size].ulValueLen = strlen(uri->object);
|
||||
pubkey_filter[filter_size].type = CKA_LABEL;
|
||||
- cert_filter[filter_size].pValue = uri->object;
|
||||
- cert_filter[filter_size].ulValueLen = strlen(uri->object);
|
||||
- cert_filter[filter_size].type = CKA_LABEL;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ ecdsa_filter[filter_size].pValue = uri->object;
|
||||
+ ecdsa_filter[filter_size].ulValueLen = strlen(uri->object);
|
||||
+ ecdsa_filter[filter_size].type = CKA_LABEL;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ cert_filter[filter_size-1].pValue = uri->object;
|
||||
+ cert_filter[filter_size-1].ulValueLen = strlen(uri->object);
|
||||
+ cert_filter[filter_size-1].type = CKA_LABEL;
|
||||
filter_size++;
|
||||
}
|
||||
|
||||
if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size,
|
||||
pubkey_attribs, keysp, nkeys) < 0 ||
|
||||
- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size,
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size,
|
||||
+ ecdsa_attribs, keysp, nkeys) < 0||
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1,
|
||||
cert_attribs, keysp, nkeys) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
@@ -553,6 +746,11 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
{
|
||||
struct sshkey *key;
|
||||
RSA *rsa;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ EC_KEY *ecdsa;
|
||||
+#else
|
||||
+ void *ecdsa;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
X509 *x509;
|
||||
EVP_PKEY *evp = NULL;
|
||||
int i;
|
||||
@@ -608,6 +806,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
* or ID, label, subject and value for certificates.
|
||||
*/
|
||||
rsa = NULL;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ ecdsa = NULL;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs))
|
||||
!= CKR_OK) {
|
||||
error("C_GetAttributeValue failed: %lu", rv);
|
||||
@@ -620,6 +821,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
rsa->e = BN_bin2bn(attribs[3].pValue,
|
||||
attribs[3].ulValueLen, NULL);
|
||||
}
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if (attribs[2].type == CKA_EC_PARAMS ) {
|
||||
+ if ((ecdsa = EC_KEY_new()) == NULL) {
|
||||
+ error("EC_KEY_new failed");
|
||||
+ } else {
|
||||
+ const unsigned char *ptr1 = attribs[2].pValue;
|
||||
+ const unsigned char *ptr2 = attribs[3].pValue;
|
||||
+ CK_ULONG len1 = attribs[2].ulValueLen;
|
||||
+ CK_ULONG len2 = attribs[3].ulValueLen;
|
||||
+ ASN1_OCTET_STRING *point = NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * CKA_EC_PARAMS contains the curve parameters of the key
|
||||
+ * either referenced as an OID or directly with all values.
|
||||
+ * CKA_EC_POINT contains the point (public key) on the curve.
|
||||
+ * The point is should be returned inside a DER-encoded
|
||||
+ * ASN.1 OCTET STRING value (but some implementation).
|
||||
+ */
|
||||
+ if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) {
|
||||
+ /* Pointing to OCTET STRING content */
|
||||
+ ptr2 = point->data;
|
||||
+ len2 = point->length;
|
||||
+ } else {
|
||||
+ /* No OCTET STRING */
|
||||
+ ptr2 = attribs[3].pValue;
|
||||
+ }
|
||||
+
|
||||
+ if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) ||
|
||||
+ (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) {
|
||||
+ EC_KEY_free(ecdsa);
|
||||
+ ecdsa = NULL;
|
||||
+ error("EC public key parsing failed");
|
||||
+ }
|
||||
+
|
||||
+ if(point) {
|
||||
+ ASN1_OCTET_STRING_free(point);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
} else {
|
||||
cp = attribs[3].pValue;
|
||||
if ((x509 = X509_new()) == NULL) {
|
||||
@@ -639,13 +879,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(evp);
|
||||
}
|
||||
- if (rsa && rsa->n && rsa->e &&
|
||||
- pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) {
|
||||
- if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
|
||||
- fatal("sshkey_new failed");
|
||||
- key->rsa = rsa;
|
||||
- key->type = KEY_RSA;
|
||||
- key->flags |= SSHKEY_FLAG_EXT;
|
||||
+ key = NULL;
|
||||
+ if (rsa || ecdsa) {
|
||||
+ if (rsa && rsa->n && rsa->e &&
|
||||
+ pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) {
|
||||
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
|
||||
+ fatal("sshkey_new failed");
|
||||
+ key->rsa = rsa;
|
||||
+ key->type = KEY_RSA;
|
||||
+ key->flags |= SSHKEY_FLAG_EXT;
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) {
|
||||
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
|
||||
+ fatal("sshkey_new failed");
|
||||
+ key->ecdsa = ecdsa;
|
||||
+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
|
||||
+ key->type = KEY_ECDSA;
|
||||
+ key->flags |= SSHKEY_FLAG_EXT;
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(key) {
|
||||
if (pkcs11_key_included(keysp, nkeys, key)) {
|
||||
sshkey_free(key);
|
||||
} else {
|
||||
@@ -658,6 +913,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
}
|
||||
} else if (rsa) {
|
||||
RSA_free(rsa);
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if (ecdsa) {
|
||||
+ EC_KEY_free(ecdsa);
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
}
|
||||
for (i = 0; i < nattribs; i++)
|
||||
free(attribs[i].pValue);
|
||||
diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-helper.c
|
||||
--- openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa 2017-10-02 21:34:26.000000000 +0200
|
||||
+++ openssh-7.6p1/ssh-pkcs11-helper.c 2018-02-16 13:25:59.428469265 +0100
|
||||
@@ -24,6 +24,17 @@
|
||||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
+#include <openssl/rsa.h>
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+#include <openssl/ecdsa.h>
|
||||
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
|
||||
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
|
||||
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
|
||||
+#define ENABLE_PKCS11_ECDSA 1
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@@ -80,7 +90,7 @@ del_keys_by_name(char *name)
|
||||
if (!strcmp(ki->providername, name)) {
|
||||
TAILQ_REMOVE(&pkcs11_keylist, ki, next);
|
||||
free(ki->providername);
|
||||
- sshkey_free(ki->key);
|
||||
+ pkcs11_del_key(ki->key);
|
||||
free(ki);
|
||||
}
|
||||
}
|
||||
@@ -164,6 +174,20 @@ process_del(void)
|
||||
sshbuf_free(msg);
|
||||
}
|
||||
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+static u_int EC_KEY_order_size(EC_KEY *key)
|
||||
+{
|
||||
+ const EC_GROUP *group = EC_KEY_get0_group(key);
|
||||
+ BIGNUM *order = BN_new();
|
||||
+ u_int nbytes = 0;
|
||||
+ if ((group != NULL) && (order != NULL) && EC_GROUP_get_order(group, order, NULL)) {
|
||||
+ nbytes = BN_num_bytes(order);
|
||||
+ }
|
||||
+ BN_clear_free(order);
|
||||
+ return nbytes;
|
||||
+}
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+
|
||||
static void
|
||||
process_sign(void)
|
||||
{
|
||||
@@ -180,14 +204,38 @@ process_sign(void)
|
||||
else {
|
||||
if ((found = lookup_key(key)) != NULL) {
|
||||
#ifdef WITH_OPENSSL
|
||||
- int ret;
|
||||
-
|
||||
- slen = RSA_size(key->rsa);
|
||||
- signature = xmalloc(slen);
|
||||
- if ((ret = RSA_private_encrypt(dlen, data, signature,
|
||||
- found->rsa, RSA_PKCS1_PADDING)) != -1) {
|
||||
- slen = ret;
|
||||
- ok = 0;
|
||||
+ if(found->type == KEY_RSA) {
|
||||
+ int ret;
|
||||
+ slen = RSA_size(key->rsa);
|
||||
+ signature = xmalloc(slen);
|
||||
+ if ((ret = RSA_private_encrypt(dlen, data, signature,
|
||||
+ found->rsa, RSA_PKCS1_PADDING)) != -1) {
|
||||
+ slen = ret;
|
||||
+ ok = 0;
|
||||
+ }
|
||||
+#ifdef ENABLE_PKCS11_ECDSA
|
||||
+ } else if(found->type == KEY_ECDSA) {
|
||||
+ ECDSA_SIG *sig;
|
||||
+ const BIGNUM *r = NULL, *s = NULL;
|
||||
+ if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) {
|
||||
+ /* PKCS11 2.3.1 recommends both r and s to have the order size for
|
||||
+ backward compatiblity */
|
||||
+ ECDSA_SIG_get0(sig, &r, &s);
|
||||
+ u_int o_len = EC_KEY_order_size(found->ecdsa);
|
||||
+ u_int r_len = BN_num_bytes(r);
|
||||
+ u_int s_len = BN_num_bytes(s);
|
||||
+ if (o_len > 0 && r_len <= o_len && s_len <= o_len) {
|
||||
+ signature = xcalloc(2, o_len);
|
||||
+ BN_bn2bin(r, signature + o_len - r_len);
|
||||
+ BN_bn2bin(s, signature + (2 * o_len) - s_len);
|
||||
+ slen = 2 * o_len;
|
||||
+ ok = 0;
|
||||
+ }
|
||||
+ ECDSA_SIG_free(sig);
|
||||
+ }
|
||||
+#endif /* ENABLE_PKCS11_ECDSA */
|
||||
+ } else {
|
||||
+ /* Unsupported type */
|
||||
}
|
||||
#endif /* WITH_OPENSSL */
|
||||
}
|
||||
diff -up openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.h
|
||||
--- openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa 2018-02-16 13:25:59.429469272 +0100
|
||||
+++ openssh-7.6p1/ssh-pkcs11.h 2018-02-16 13:45:29.623800048 +0100
|
||||
@@ -20,6 +20,7 @@
|
||||
int pkcs11_init(int);
|
||||
void pkcs11_terminate(void);
|
||||
int pkcs11_add_provider(char *, char *, struct sshkey ***);
|
||||
+int pkcs11_del_key(struct sshkey *);
|
||||
int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***);
|
||||
int pkcs11_del_provider(char *);
|
||||
int pkcs11_uri_write(const struct sshkey *, FILE *);
|
||||
|
||||
|
||||
|
||||
diff -up openssh-7.6p1/ssh-pkcs11.c.old openssh-7.6p1/ssh-pkcs11.c
|
||||
--- openssh-7.6p1/ssh-pkcs11.c.old 2018-02-16 16:43:08.861520255 +0100
|
||||
+++ openssh-7.6p1/ssh-pkcs11.c 2018-02-16 16:56:35.312601451 +0100
|
||||
@@ -917,13 +917,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
|
||||
} else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen)
|
||||
== NULL) {
|
||||
error("d2i_X509 failed");
|
||||
- } else if ((evp = X509_get_pubkey(x509)) == NULL ||
|
||||
- evp->type != EVP_PKEY_RSA ||
|
||||
- evp->pkey.rsa == NULL) {
|
||||
- debug("X509_get_pubkey failed or no rsa");
|
||||
- } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa))
|
||||
- == NULL) {
|
||||
- error("RSAPublicKey_dup");
|
||||
+ } else if ((evp = X509_get_pubkey(x509)) == NULL) {
|
||||
+ debug("X509_get_pubkey failed");
|
||||
+ } else {
|
||||
+ switch (evp->type) {
|
||||
+ case EVP_PKEY_RSA:
|
||||
+ if (evp->pkey.rsa == NULL)
|
||||
+ debug("Missing RSA key");
|
||||
+ else if ((rsa = RSAPublicKey_dup(
|
||||
+ evp->pkey.rsa)) == NULL)
|
||||
+ error("RSAPublicKey_dup failed");
|
||||
+ break;
|
||||
+ case EVP_PKEY_EC:
|
||||
+ if (evp->pkey.ecdsa == NULL)
|
||||
+ debug("Missing ECDSA key");
|
||||
+ else if ((ecdsa = EC_KEY_dup(
|
||||
+ evp->pkey.ecdsa)) == NULL)
|
||||
+ error("EC_KEY_dup failed");
|
||||
+ break;
|
||||
+ default:
|
||||
+ debug("not a RSA or ECDSA key");
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(evp);
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,70 +1,6 @@
|
|||
diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c
|
||||
--- openssh-7.7p1/cipher.c.fips 2018-08-08 10:08:40.814719906 +0200
|
||||
+++ openssh-7.7p1/cipher.c 2018-08-08 10:08:40.821719965 +0200
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
+#include <openssl/fips.h>
|
||||
+
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@@ -90,6 +92,33 @@ static const struct sshcipher ciphers[]
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
+static const struct sshcipher fips_ciphers[] = {
|
||||
+#ifdef WITH_OPENSSL
|
||||
+ { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc },
|
||||
+ { "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc },
|
||||
+ { "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc },
|
||||
+ { "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
|
||||
+ { "rijndael-cbc@lysator.liu.se",
|
||||
+ 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
|
||||
+ { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr },
|
||||
+ { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr },
|
||||
+ { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr },
|
||||
+# ifdef OPENSSL_HAVE_EVPGCM
|
||||
+ { "aes128-gcm@openssh.com",
|
||||
+ 16, 16, 12, 16, 0, EVP_aes_128_gcm },
|
||||
+ { "aes256-gcm@openssh.com",
|
||||
+ 16, 32, 12, 16, 0, EVP_aes_256_gcm },
|
||||
+# endif /* OPENSSL_HAVE_EVPGCM */
|
||||
+#else
|
||||
+ { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL },
|
||||
+ { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL },
|
||||
+ { "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL },
|
||||
+#endif
|
||||
+ { "none", 8, 0, 0, 0, CFLAG_NONE, NULL },
|
||||
+
|
||||
+ { NULL, 0, 0, 0, 0, 0, NULL }
|
||||
+};
|
||||
+
|
||||
/*--*/
|
||||
|
||||
/* Returns a comma-separated list of supported ciphers. */
|
||||
@@ -100,7 +129,7 @@ cipher_alg_list(char sep, int auth_only)
|
||||
size_t nlen, rlen = 0;
|
||||
const struct sshcipher *c;
|
||||
|
||||
- for (c = ciphers; c->name != NULL; c++) {
|
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) {
|
||||
if ((c->flags & CFLAG_INTERNAL) != 0)
|
||||
continue;
|
||||
if (auth_only && c->auth_len == 0)
|
||||
@@ -172,7 +201,7 @@ const struct sshcipher *
|
||||
cipher_by_name(const char *name)
|
||||
{
|
||||
const struct sshcipher *c;
|
||||
- for (c = ciphers; c->name != NULL; c++)
|
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++)
|
||||
if (strcmp(c->name, name) == 0)
|
||||
return c;
|
||||
return NULL;
|
||||
diff -up openssh-7.7p1/cipher-ctr.c.fips openssh-7.7p1/cipher-ctr.c
|
||||
--- openssh-7.7p1/cipher-ctr.c.fips 2018-08-08 10:08:40.709719021 +0200
|
||||
+++ openssh-7.7p1/cipher-ctr.c 2018-08-08 10:08:40.821719965 +0200
|
||||
diff -up openssh-7.9p1/cipher-ctr.c.fips openssh-7.9p1/cipher-ctr.c
|
||||
--- openssh-7.9p1/cipher-ctr.c.fips 2019-03-11 17:06:37.519877082 +0100
|
||||
+++ openssh-7.9p1/cipher-ctr.c 2019-03-11 17:06:37.620878031 +0100
|
||||
@@ -179,7 +179,8 @@ evp_aes_128_ctr(void)
|
||||
aes_ctr.do_cipher = ssh_aes_ctr;
|
||||
#ifndef SSH_OLD_EVP
|
||||
|
|
@ -75,10 +11,10 @@ diff -up openssh-7.7p1/cipher-ctr.c.fips openssh-7.7p1/cipher-ctr.c
|
|||
#endif
|
||||
return (&aes_ctr);
|
||||
}
|
||||
diff -up openssh-7.7p1/clientloop.c.fips openssh-7.7p1/clientloop.c
|
||||
--- openssh-7.7p1/clientloop.c.fips 2018-08-08 10:08:40.769719527 +0200
|
||||
+++ openssh-7.7p1/clientloop.c 2018-08-08 10:08:40.822719973 +0200
|
||||
@@ -1978,7 +1978,8 @@ key_accepted_by_hostkeyalgs(const struct
|
||||
diff -up openssh-7.9p1/clientloop.c.fips openssh-7.9p1/clientloop.c
|
||||
--- openssh-7.9p1/clientloop.c.fips 2019-03-11 17:06:37.523877120 +0100
|
||||
+++ openssh-7.9p1/clientloop.c 2019-03-11 17:06:37.620878031 +0100
|
||||
@@ -2014,7 +2014,8 @@ key_accepted_by_hostkeyalgs(const struct
|
||||
{
|
||||
const char *ktype = sshkey_ssh_name(key);
|
||||
const char *hostkeyalgs = options.hostkeyalgorithms != NULL ?
|
||||
|
|
@ -88,86 +24,75 @@ diff -up openssh-7.7p1/clientloop.c.fips openssh-7.7p1/clientloop.c
|
|||
|
||||
if (key == NULL || key->type == KEY_UNSPEC)
|
||||
return 0;
|
||||
diff -up openssh-7.7p1/dh.h.fips openssh-7.7p1/dh.h
|
||||
--- openssh-7.7p1/dh.h.fips 2018-04-02 07:38:28.000000000 +0200
|
||||
+++ openssh-7.7p1/dh.h 2018-08-08 10:08:40.822719973 +0200
|
||||
@@ -51,6 +51,7 @@ u_int dh_estimate(int);
|
||||
* Miniumum increased in light of DH precomputation attacks.
|
||||
*/
|
||||
#define DH_GRP_MIN 2048
|
||||
+#define DH_GRP_MIN_FIPS 2048
|
||||
#define DH_GRP_MAX 8192
|
||||
diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c
|
||||
--- openssh-7.9p1/dh.c.fips 2018-10-17 02:01:20.000000000 +0200
|
||||
+++ openssh-7.9p1/dh.c 2019-03-11 17:08:11.769763057 +0100
|
||||
@@ -152,6 +152,12 @@ choose_dh(int min, int wantbits, int max
|
||||
int best, bestcount, which, linenum;
|
||||
struct dhgroup dhg;
|
||||
|
||||
/*
|
||||
diff -up openssh-7.7p1/entropy.c.fips openssh-7.7p1/entropy.c
|
||||
--- openssh-7.7p1/entropy.c.fips 2018-08-08 10:08:40.698718928 +0200
|
||||
+++ openssh-7.7p1/entropy.c 2018-08-08 10:08:40.822719973 +0200
|
||||
@@ -217,6 +217,9 @@ seed_rng(void)
|
||||
fatal("OpenSSL version mismatch. Built against %lx, you "
|
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
|
||||
+ /* clean the PRNG status when exiting the program */
|
||||
+ atexit(RAND_cleanup);
|
||||
+ if (FIPS_mode()) {
|
||||
+ verbose("Using arbitrary primes is not allowed in FIPS mode."
|
||||
+ " Falling back to known groups.");
|
||||
+ return (dh_new_group_fallback(max));
|
||||
+ }
|
||||
+
|
||||
#ifndef OPENSSL_PRNG_ONLY
|
||||
if (RAND_status() == 1) {
|
||||
debug3("RNG is ready, skipping seeding");
|
||||
diff -up openssh-7.7p1/kex.c.fips openssh-7.7p1/kex.c
|
||||
--- openssh-7.7p1/kex.c.fips 2018-08-08 10:08:40.815719915 +0200
|
||||
+++ openssh-7.7p1/kex.c 2018-08-08 10:11:24.109081924 +0200
|
||||
@@ -35,6 +35,7 @@
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/dh.h>
|
||||
+#include <openssl/fips.h>
|
||||
#endif
|
||||
if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
|
||||
logit("WARNING: could not open %s (%s), using fixed modulus",
|
||||
_PATH_DH_MODULI, strerror(errno));
|
||||
@@ -489,4 +495,38 @@ dh_estimate(int bits)
|
||||
return 8192;
|
||||
}
|
||||
|
||||
#include "ssh2.h"
|
||||
@@ -122,6 +123,26 @@ static const struct kexalg kexalgs[] = {
|
||||
{ NULL, -1, -1, -1},
|
||||
};
|
||||
|
||||
+static const struct kexalg kexalgs_fips[] = {
|
||||
+ { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
|
||||
+ { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
|
||||
+ { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
|
||||
+#ifdef HAVE_EVP_SHA256
|
||||
+ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
|
||||
+#endif
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
|
||||
+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
|
||||
+ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
|
||||
+ SSH_DIGEST_SHA384 },
|
||||
+# ifdef OPENSSL_HAS_NISTP521
|
||||
+ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
|
||||
+ SSH_DIGEST_SHA512 },
|
||||
+# endif
|
||||
+#endif
|
||||
+ { NULL, -1, -1, -1},
|
||||
+};
|
||||
+/*
|
||||
+ * Compares the received DH parameters with known-good groups,
|
||||
+ * which might be either from group14, group16 or group18.
|
||||
+ */
|
||||
+int
|
||||
+dh_is_known_group(const DH *dh)
|
||||
+{
|
||||
+ const BIGNUM *p, *g;
|
||||
+ const BIGNUM *known_p, *known_g;
|
||||
+ DH *known = NULL;
|
||||
+ int bits = 0, rv = 0;
|
||||
+
|
||||
char *
|
||||
kex_alg_list(char sep)
|
||||
{
|
||||
@@ -129,7 +150,7 @@ kex_alg_list(char sep)
|
||||
size_t nlen, rlen = 0;
|
||||
const struct kexalg *k;
|
||||
+ DH_get0_pqg(dh, &p, NULL, &g);
|
||||
+ bits = BN_num_bits(p);
|
||||
+
|
||||
+ if (bits <= 3072) {
|
||||
+ known = dh_new_group14();
|
||||
+ } else if (bits <= 6144) {
|
||||
+ known = dh_new_group16();
|
||||
+ } else {
|
||||
+ known = dh_new_group18();
|
||||
+ }
|
||||
+
|
||||
+ DH_get0_pqg(known, &known_p, NULL, &known_g);
|
||||
+
|
||||
+ if (BN_cmp(g, known_g) == 0 &&
|
||||
+ BN_cmp(p, known_p) == 0) {
|
||||
+ rv = 1;
|
||||
+ }
|
||||
+
|
||||
+ DH_free(known);
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
#endif /* WITH_OPENSSL */
|
||||
diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h
|
||||
--- openssh-7.9p1/dh.h.fips 2018-10-17 02:01:20.000000000 +0200
|
||||
+++ openssh-7.9p1/dh.h 2019-03-11 17:08:18.718828381 +0100
|
||||
@@ -43,6 +43,7 @@ DH *dh_new_group_fallback(int);
|
||||
|
||||
- for (k = kexalgs; k->name != NULL; k++) {
|
||||
+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) {
|
||||
if (ret != NULL)
|
||||
ret[rlen++] = sep;
|
||||
nlen = strlen(k->name);
|
||||
@@ -149,7 +170,7 @@ kex_alg_by_name(const char *name)
|
||||
{
|
||||
const struct kexalg *k;
|
||||
int dh_gen_key(DH *, int);
|
||||
int dh_pub_is_valid(const DH *, const BIGNUM *);
|
||||
+int dh_is_known_group(const DH *);
|
||||
|
||||
- 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
|
||||
u_int dh_estimate(int);
|
||||
|
||||
diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c
|
||||
--- openssh-7.9p1/kex.c.fips 2019-03-11 17:06:37.614877975 +0100
|
||||
+++ openssh-7.9p1/kex.c 2019-03-11 17:06:37.621878041 +0100
|
||||
@@ -175,7 +196,10 @@ kex_names_valid(const char *names)
|
||||
for ((p = strsep(&cp, ",")); p && *p != '\0';
|
||||
(p = strsep(&cp, ","))) {
|
||||
|
|
@ -180,158 +105,39 @@ diff -up openssh-7.7p1/kex.c.fips openssh-7.7p1/kex.c
|
|||
free(s);
|
||||
return 0;
|
||||
}
|
||||
diff -up openssh-7.7p1/kexgexc.c.fips openssh-7.7p1/kexgexc.c
|
||||
--- openssh-7.7p1/kexgexc.c.fips 2018-04-02 07:38:28.000000000 +0200
|
||||
+++ openssh-7.7p1/kexgexc.c 2018-08-08 10:08:40.822719973 +0200
|
||||
diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c
|
||||
--- openssh-7.9p1/kexgexc.c.fips 2018-10-17 02:01:20.000000000 +0200
|
||||
+++ openssh-7.9p1/kexgexc.c 2019-03-11 17:06:37.621878041 +0100
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
+#include <openssl/fips.h>
|
||||
+#include <openssl/crypto.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
@@ -63,7 +64,7 @@ kexgex_client(struct ssh *ssh)
|
||||
@@ -118,6 +119,10 @@ input_kex_dh_gex_group(int type, u_int32
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
+ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) {
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
p = g = NULL; /* belong to kex->dh now */
|
||||
|
||||
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.7p1/kexgexs.c.fips openssh-7.7p1/kexgexs.c
|
||||
--- openssh-7.7p1/kexgexs.c.fips 2018-04-02 07:38:28.000000000 +0200
|
||||
+++ openssh-7.7p1/kexgexs.c 2018-08-08 10:08:40.823719982 +0200
|
||||
@@ -82,9 +82,9 @@ input_kex_dh_gex_request(int type, u_int
|
||||
kex->nbits = nbits;
|
||||
kex->min = min;
|
||||
kex->max = max;
|
||||
- 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.7p1/mac.c.fips openssh-7.7p1/mac.c
|
||||
--- openssh-7.7p1/mac.c.fips 2018-08-08 10:08:40.815719915 +0200
|
||||
+++ openssh-7.7p1/mac.c 2018-08-08 10:11:56.915352642 +0200
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
+#include <openssl/fips.h>
|
||||
+
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -54,7 +56,7 @@ struct macalg {
|
||||
int etm; /* Encrypt-then-MAC */
|
||||
};
|
||||
|
||||
-static const struct macalg macs[] = {
|
||||
+static const struct macalg all_macs[] = {
|
||||
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */
|
||||
{ "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
|
||||
{ "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 },
|
||||
@@ -82,6 +84,24 @@ static const struct macalg macs[] = {
|
||||
{ NULL, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
+static const struct macalg fips_macs[] = {
|
||||
+ /* Encrypt-and-MAC (encrypt-and-authenticate) variants */
|
||||
+ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
|
||||
+#ifdef HAVE_EVP_SHA256
|
||||
+ { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },
|
||||
+ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },
|
||||
+#endif
|
||||
+
|
||||
+ /* Encrypt-then-MAC variants */
|
||||
+ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
|
||||
+#ifdef HAVE_EVP_SHA256
|
||||
+ { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },
|
||||
+ { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },
|
||||
+#endif
|
||||
+
|
||||
+ { NULL, 0, 0, 0, 0, 0, 0 }
|
||||
+};
|
||||
+
|
||||
/* Returns a list of supported MACs separated by the specified char. */
|
||||
char *
|
||||
mac_alg_list(char sep)
|
||||
@@ -90,7 +110,7 @@ mac_alg_list(char sep)
|
||||
size_t nlen, rlen = 0;
|
||||
const struct macalg *m;
|
||||
|
||||
- for (m = macs; m->name != NULL; m++) {
|
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) {
|
||||
if (ret != NULL)
|
||||
ret[rlen++] = sep;
|
||||
nlen = strlen(m->name);
|
||||
@@ -129,7 +149,7 @@ mac_setup(struct sshmac *mac, char *name
|
||||
{
|
||||
const struct macalg *m;
|
||||
|
||||
- for (m = macs; m->name != NULL; m++) {
|
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) {
|
||||
if (strcmp(name, m->name) != 0)
|
||||
continue;
|
||||
if (mac != NULL)
|
||||
diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in
|
||||
--- openssh-7.7p1/Makefile.in.fips 2018-08-08 10:08:40.815719915 +0200
|
||||
+++ openssh-7.7p1/Makefile.in 2018-08-08 10:08:40.823719982 +0200
|
||||
@@ -179,25 +179,25 @@ libssh.a: $(LIBSSH_OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
|
||||
- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS)
|
||||
+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS)
|
||||
|
||||
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
|
||||
- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
|
||||
+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
|
||||
|
||||
scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
|
||||
$(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
|
||||
- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o
|
||||
- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
|
||||
- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o
|
||||
- $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
|
||||
$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
|
||||
@@ -215,7 +215,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a
|
||||
$(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
|
||||
- $(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.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h
|
||||
--- openssh-7.7p1/myproposal.h.fips 2018-04-02 07:38:28.000000000 +0200
|
||||
+++ openssh-7.7p1/myproposal.h 2018-08-08 10:08:40.823719982 +0200
|
||||
@@ -114,6 +114,14 @@
|
||||
/* generate and send 'e', client DH public key */
|
||||
diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h
|
||||
--- openssh-7.9p1/myproposal.h.fips 2018-10-17 02:01:20.000000000 +0200
|
||||
+++ openssh-7.9p1/myproposal.h 2019-03-11 17:06:37.621878041 +0100
|
||||
@@ -116,6 +116,16 @@
|
||||
"rsa-sha2-256," \
|
||||
"ssh-rsa"
|
||||
|
||||
+#define KEX_FIPS_PK_ALG \
|
||||
+ HOSTKEY_ECDSA_CERT_METHODS \
|
||||
+ "rsa-sha2-512-cert-v01@openssh.com," \
|
||||
+ "rsa-sha2-256-cert-v01@openssh.com," \
|
||||
+ "ssh-rsa-cert-v01@openssh.com," \
|
||||
+ HOSTKEY_ECDSA_METHODS \
|
||||
+ "rsa-sha2-512," \
|
||||
|
|
@ -341,7 +147,7 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h
|
|||
/* the actual algorithms */
|
||||
|
||||
#define KEX_SERVER_ENCRYPT \
|
||||
@@ -137,6 +145,38 @@
|
||||
@@ -139,6 +147,38 @@
|
||||
|
||||
#define KEX_CLIENT_MAC KEX_SERVER_MAC
|
||||
|
||||
|
|
@ -377,16 +183,16 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h
|
|||
+ "hmac-sha1"
|
||||
+#endif
|
||||
+
|
||||
#else /* WITH_OPENSSL */
|
||||
|
||||
#define KEX_SERVER_KEX \
|
||||
diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c
|
||||
--- openssh-7.7p1/readconf.c.fips 2018-08-08 10:08:40.769719527 +0200
|
||||
+++ openssh-7.7p1/readconf.c 2018-08-08 10:08:40.824719990 +0200
|
||||
@@ -2081,17 +2081,18 @@ fill_default_options(Options * options)
|
||||
all_mac = mac_alg_list(',');
|
||||
/* Not a KEX value, but here so all the algorithm defaults are together */
|
||||
#define SSH_ALLOWED_CA_SIGALGS \
|
||||
"ecdsa-sha2-nistp256," \
|
||||
diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c
|
||||
--- openssh-7.9p1/readconf.c.fips 2019-03-11 17:06:37.601877853 +0100
|
||||
+++ openssh-7.9p1/readconf.c 2019-03-11 17:06:37.622878050 +0100
|
||||
@@ -2178,18 +2178,19 @@ fill_default_options(Options * options)
|
||||
all_kex = kex_alg_list(',');
|
||||
all_key = sshkey_alg_list(0, 0, 1, ',');
|
||||
all_sig = sshkey_alg_list(0, 1, 1, ',');
|
||||
-#define ASSEMBLE(what, defaults, all) \
|
||||
+#define ASSEMBLE(what, defaults, fips_defaults, all) \
|
||||
do { \
|
||||
|
|
@ -396,22 +202,24 @@ diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c
|
|||
+ all)) != 0) \
|
||||
fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
|
||||
} while (0)
|
||||
- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
|
||||
- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
|
||||
- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
|
||||
- ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, all_cipher);
|
||||
- ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac);
|
||||
- ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex);
|
||||
- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
|
||||
- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
|
||||
+ ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
|
||||
+ ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac);
|
||||
+ ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
|
||||
- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
|
||||
+ ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
|
||||
+ ASSEMBLE(macs, KEX_CLIENT_MAC, KEX_FIPS_MAC, all_mac);
|
||||
+ ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
|
||||
+ ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
|
||||
+ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
|
||||
+ ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig);
|
||||
#undef ASSEMBLE
|
||||
free(all_cipher);
|
||||
free(all_mac);
|
||||
diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-seccomp-filter.c
|
||||
--- openssh-7.7p1/sandbox-seccomp-filter.c.fips 2018-08-08 10:08:40.794719737 +0200
|
||||
+++ openssh-7.7p1/sandbox-seccomp-filter.c 2018-08-08 10:08:40.824719990 +0200
|
||||
diff -up openssh-7.9p1/sandbox-seccomp-filter.c.fips openssh-7.9p1/sandbox-seccomp-filter.c
|
||||
--- openssh-7.9p1/sandbox-seccomp-filter.c.fips 2019-03-11 17:06:37.586877712 +0100
|
||||
+++ openssh-7.9p1/sandbox-seccomp-filter.c 2019-03-11 17:06:37.622878050 +0100
|
||||
@@ -137,6 +137,9 @@ static const struct sock_filter preauth_
|
||||
#ifdef __NR_open
|
||||
SC_DENY(__NR_open, EACCES),
|
||||
|
|
@ -422,13 +230,13 @@ diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-secco
|
|||
#ifdef __NR_openat
|
||||
SC_DENY(__NR_openat, EACCES),
|
||||
#endif
|
||||
diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c
|
||||
--- openssh-7.7p1/servconf.c.fips 2018-08-08 10:08:40.778719603 +0200
|
||||
+++ openssh-7.7p1/servconf.c 2018-08-08 10:08:40.824719990 +0200
|
||||
@@ -196,17 +196,18 @@ option_clear_or_none(const char *o)
|
||||
all_mac = mac_alg_list(',');
|
||||
diff -up openssh-7.9p1/servconf.c.fips openssh-7.9p1/servconf.c
|
||||
--- openssh-7.9p1/servconf.c.fips 2019-03-11 17:06:37.568877543 +0100
|
||||
+++ openssh-7.9p1/servconf.c 2019-03-11 17:06:37.622878050 +0100
|
||||
@@ -209,18 +209,19 @@ assemble_algorithms(ServerOptions *o)
|
||||
all_kex = kex_alg_list(',');
|
||||
all_key = sshkey_alg_list(0, 0, 1, ',');
|
||||
all_sig = sshkey_alg_list(0, 1, 1, ',');
|
||||
-#define ASSEMBLE(what, defaults, all) \
|
||||
+#define ASSEMBLE(what, defaults, fips_defaults, all) \
|
||||
do { \
|
||||
|
|
@ -443,129 +251,65 @@ diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c
|
|||
- ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
|
||||
- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
|
||||
- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
|
||||
- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
|
||||
+ ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
|
||||
+ ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac);
|
||||
+ ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
|
||||
+ ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
|
||||
+ ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
|
||||
+ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
|
||||
+ ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig);
|
||||
#undef ASSEMBLE
|
||||
free(all_cipher);
|
||||
free(all_mac);
|
||||
diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c
|
||||
--- openssh-7.7p1/ssh.c.fips 2018-08-08 10:08:40.811719881 +0200
|
||||
+++ openssh-7.7p1/ssh.c 2018-08-08 10:08:40.825719999 +0200
|
||||
@@ -76,6 +76,8 @@
|
||||
diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c
|
||||
--- openssh-7.9p1/ssh.c.fips 2019-03-11 17:06:37.602877862 +0100
|
||||
+++ openssh-7.9p1/ssh.c 2019-03-11 17:06:37.623878060 +0100
|
||||
@@ -76,6 +76,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
+#include <openssl/fips.h>
|
||||
+#include <fipscheck.h>
|
||||
+#include <openssl/crypto.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
@@ -579,6 +581,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 */
|
||||
@@ -1045,7 +1055,6 @@ main(int ac, char **av)
|
||||
host_arg = xstrdup(host);
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
- OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
|
||||
@@ -1268,6 +1277,10 @@ main(int ac, char **av)
|
||||
|
||||
seed_rng();
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit("FIPS mode initialized");
|
||||
+ }
|
||||
@@ -1283,6 +1294,10 @@ main(int ac, char **av)
|
||||
dump_client_config(&options, host);
|
||||
exit(0);
|
||||
}
|
||||
+
|
||||
if (options.user == NULL)
|
||||
options.user = xstrdup(pw->pw_name);
|
||||
+ if (FIPS_mode()) {
|
||||
+ debug("FIPS mode initialized");
|
||||
+ }
|
||||
|
||||
diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c
|
||||
--- openssh-7.7p1/sshconnect2.c.fips 2018-08-08 10:08:40.786719670 +0200
|
||||
+++ openssh-7.7p1/sshconnect2.c 2018-08-08 10:08:40.825719999 +0200
|
||||
if (muxclient_command != 0 && options.control_path == NULL)
|
||||
fatal("No ControlPath specified for \"-O\" command");
|
||||
diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
|
||||
--- openssh-7.9p1/sshconnect2.c.fips 2019-03-11 17:06:37.580877655 +0100
|
||||
+++ openssh-7.9p1/sshconnect2.c 2019-03-11 17:06:37.623878060 +0100
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <vis.h>
|
||||
#endif
|
||||
|
||||
+#include <openssl/fips.h>
|
||||
+#include <openssl/crypto.h>
|
||||
+
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
@@ -235,7 +237,8 @@ order_hostkeyalgs(char *host, struct soc
|
||||
for (i = 0; i < options.num_system_hostfiles; i++)
|
||||
load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
|
||||
|
||||
@@ -148,7 +150,8 @@ order_hostkeyalgs(char *host, struct soc
|
||||
* Otherwise, prefer the host key algorithms that match known keys
|
||||
* while keeping the ordering of HostkeyAlgorithms as much as possible.
|
||||
*/
|
||||
- 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);
|
||||
@@ -290,21 +293,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
|
||||
@@ -322,14 +330,16 @@ ssh_kex2(char *host, struct sockaddr *ho
|
||||
@@ -229,14 +232,16 @@ ssh_kex2(struct ssh *ssh, char *host, st
|
||||
if (options.hostkeyalgorithms != NULL) {
|
||||
all_key = sshkey_alg_list(0, 0, 1, ',');
|
||||
if (kex_assemble_names(&options.hostkeyalgorithms,
|
||||
if (kex_assemble_names(&options.hostkeyalgorithms,
|
||||
- KEX_DEFAULT_PK_ALG, all_key) != 0)
|
||||
+ (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG),
|
||||
+ all_key) != 0)
|
||||
|
|
@ -581,9 +325,79 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c
|
|||
/* Prefer algorithms that we already have keys for */
|
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
|
||||
compat_pkalg_proposal(
|
||||
diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c
|
||||
--- openssh-7.7p1/sshd.c.fips 2018-08-08 10:08:40.818719940 +0200
|
||||
+++ openssh-7.7p1/sshd.c 2018-08-08 10:08:40.826720007 +0200
|
||||
@@ -201,35 +201,40 @@ ssh_kex2(char *host, struct sockaddr *ho
|
||||
|
||||
#if defined(GSSAPI) && defined(WITH_OPENSSL)
|
||||
if (options.gss_keyex) {
|
||||
- /* Add the GSSAPI mechanisms currently supported on this
|
||||
- * client to the key exchange algorithm proposal */
|
||||
- orig = myproposal[PROPOSAL_KEX_ALGS];
|
||||
-
|
||||
- if (options.gss_server_identity) {
|
||||
- gss_host = xstrdup(options.gss_server_identity);
|
||||
- } else if (options.gss_trust_dns) {
|
||||
- gss_host = remote_hostname(ssh);
|
||||
- /* Fall back to specified host if we are using proxy command
|
||||
- * and can not use DNS on that socket */
|
||||
- if (strcmp(gss_host, "UNKNOWN") == 0) {
|
||||
- gss_host = xstrdup(host);
|
||||
- }
|
||||
- } else {
|
||||
- gss_host = xstrdup(host);
|
||||
- }
|
||||
-
|
||||
- gss = ssh_gssapi_client_mechanisms(gss_host,
|
||||
- options.gss_client_identity, options.gss_kex_algorithms);
|
||||
- if (gss) {
|
||||
- debug("Offering GSSAPI proposal: %s", gss);
|
||||
- xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
|
||||
- "%s,%s", gss, orig);
|
||||
-
|
||||
- /* If we've got GSSAPI algorithms, then we also support the
|
||||
- * 'null' hostkey, as a last resort */
|
||||
- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
|
||||
- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
- "%s,null", orig);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
|
||||
+ options.gss_keyex = 0;
|
||||
+ } else {
|
||||
+ /* Add the GSSAPI mechanisms currently supported on this
|
||||
+ * client to the key exchange algorithm proposal */
|
||||
+ orig = myproposal[PROPOSAL_KEX_ALGS];
|
||||
+
|
||||
+ if (options.gss_server_identity) {
|
||||
+ gss_host = xstrdup(options.gss_server_identity);
|
||||
+ } else if (options.gss_trust_dns) {
|
||||
+ gss_host = remote_hostname(ssh);
|
||||
+ /* Fall back to specified host if we are using proxy command
|
||||
+ * and can not use DNS on that socket */
|
||||
+ if (strcmp(gss_host, "UNKNOWN") == 0) {
|
||||
+ gss_host = xstrdup(host);
|
||||
+ }
|
||||
+ } else {
|
||||
+ gss_host = xstrdup(host);
|
||||
+ }
|
||||
+
|
||||
+ gss = ssh_gssapi_client_mechanisms(gss_host,
|
||||
+ options.gss_client_identity, options.gss_kex_algorithms);
|
||||
+ if (gss) {
|
||||
+ debug("Offering GSSAPI proposal: %s", gss);
|
||||
+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
|
||||
+ "%s,%s", gss, orig);
|
||||
+
|
||||
+ /* If we've got GSSAPI algorithms, then we also support the
|
||||
+ * 'null' hostkey, as a last resort */
|
||||
+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
|
||||
+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
+ "%s,null", orig);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c
|
||||
--- openssh-7.9p1/sshd.c.fips 2019-03-11 17:06:37.617878003 +0100
|
||||
+++ openssh-7.9p1/sshd.c 2019-03-11 17:06:37.624878069 +0100
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
|
@ -592,55 +406,34 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -77,6 +78,8 @@
|
||||
@@ -77,6 +78,7 @@
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rand.h>
|
||||
+#include <openssl/fips.h>
|
||||
+#include <fipscheck.h>
|
||||
+#include <openssl/crypto.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#endif
|
||||
|
||||
@@ -1534,6 +1537,18 @@ main(int ac, char **av)
|
||||
@@ -1581,6 +1584,7 @@ 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();
|
||||
+ }
|
||||
+ OpenSSL_add_all_algorithms();
|
||||
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
|
||||
saved_argc = ac;
|
||||
rexec_argc = ac;
|
||||
@@ -1675,7 +1690,7 @@ main(int ac, char **av)
|
||||
else
|
||||
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
|
||||
|
||||
-#ifdef WITH_OPENSSL
|
||||
+#if 0 /* FIPS */
|
||||
OpenSSL_add_all_algorithms();
|
||||
#endif
|
||||
|
||||
@@ -1979,6 +1994,10 @@ main(int ac, char **av)
|
||||
@@ -2036,6 +2051,10 @@ main(int ac, char **av)
|
||||
/* Reinitialize the log (because of the fork above). */
|
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr);
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit("FIPS mode initialized");
|
||||
+ debug("FIPS mode initialized");
|
||||
+ }
|
||||
+
|
||||
/* Chdir to the root directory so that the current disk can be
|
||||
unmounted if desired. */
|
||||
if (chdir("/") == -1)
|
||||
@@ -2359,10 +2378,14 @@ do_ssh2_kex(void)
|
||||
@@ -2412,10 +2431,14 @@ do_ssh2_kex(void)
|
||||
if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
|
||||
orig = NULL;
|
||||
|
||||
|
|
@ -659,14 +452,14 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c
|
|||
|
||||
if (gss && orig)
|
||||
xasprintf(&newstr, "%s,%s", gss, orig);
|
||||
diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c
|
||||
--- openssh-7.7p1/sshkey.c.fips 2018-08-08 10:08:40.818719940 +0200
|
||||
+++ openssh-7.7p1/sshkey.c 2018-08-08 10:08:40.826720007 +0200
|
||||
diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c
|
||||
--- openssh-7.9p1/sshkey.c.fips 2019-03-11 17:06:37.617878003 +0100
|
||||
+++ openssh-7.9p1/sshkey.c 2019-03-11 17:06:37.624878069 +0100
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
+#include <openssl/fips.h>
|
||||
+#include <openssl/crypto.h>
|
||||
#endif
|
||||
|
||||
#include "crypto_api.h"
|
||||
|
|
@ -678,19 +471,60 @@ diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c
|
|||
|
||||
#include "xmss_fast.h"
|
||||
|
||||
@@ -1526,6 +1528,8 @@ rsa_generate_private_key(u_int bits, RSA
|
||||
@@ -392,7 +394,8 @@ sshkey_calculate_signature(EVP_PKEY *pkey
|
||||
{
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
u_char *sig = NULL;
|
||||
- int ret, slen, len;
|
||||
+ int ret, slen;
|
||||
+ size_t len;
|
||||
|
||||
if (sigp == NULL || lenp == NULL) {
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
@@ -411,9 +414,10 @@ sshkey_calculate_signature(EVP_PKEY *pkey
|
||||
ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto error;
|
||||
}
|
||||
- if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
|
||||
- EVP_SignUpdate(ctx, data, datalen) <= 0 ||
|
||||
- EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
|
||||
+ if (EVP_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg),
|
||||
+ NULL, pkey) != 1 ||
|
||||
+ EVP_DigestSignUpdate(ctx, data, datalen) != 1 ||
|
||||
+ EVP_DigestSignFinal(ctx, sig, &len) != 1) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto error;
|
||||
}
|
||||
@@ -440,12 +444,13 @@ sshkey_verify_signature(EVP_PKEY *pkey
|
||||
if ((ctx = EVP_MD_CTX_new()) == NULL) {
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
}
|
||||
- if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
|
||||
- EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
|
||||
+ if (EVP_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg),
|
||||
+ NULL, pkey) != 1 ||
|
||||
+ EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto done;
|
||||
}
|
||||
- ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
|
||||
+ ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen);
|
||||
switch (ret) {
|
||||
case 1:
|
||||
ret = 0;
|
||||
@@ -1514,6 +1516,8 @@ rsa_generate_private_key(u_int bits, RSA
|
||||
}
|
||||
if (!BN_set_word(f4, RSA_F4) ||
|
||||
!RSA_generate_key_ex(private, bits, f4, NULL)) {
|
||||
+ if (FIPS_mode())
|
||||
+ logit("%s: the key length might be unsupported by FIPS mode approved key generation method", __func__);
|
||||
+ if (FIPS_mode())
|
||||
+ logit("%s: the key length might be unsupported by FIPS mode approved key generation method", __func__);
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
diff -up openssh-7.7p1/ssh-keygen.c.fips openssh-7.7p1/ssh-keygen.c
|
||||
--- openssh-7.7p1/ssh-keygen.c.fips 2018-08-08 10:08:40.801719797 +0200
|
||||
+++ openssh-7.7p1/ssh-keygen.c 2018-08-08 10:08:40.827720016 +0200
|
||||
@@ -229,6 +229,12 @@ type_bits_valid(int type, const char *na
|
||||
diff -up openssh-7.9p1/ssh-keygen.c.fips openssh-7.9p1/ssh-keygen.c
|
||||
--- openssh-7.9p1/ssh-keygen.c.fips 2019-03-11 17:06:37.590877750 +0100
|
||||
+++ openssh-7.9p1/ssh-keygen.c 2019-03-11 17:06:37.625878079 +0100
|
||||
@@ -230,6 +230,12 @@ type_bits_valid(int type, const char *na
|
||||
OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
|
||||
if (*bitsp > maxbits)
|
||||
fatal("key bits exceeds maximum %d", maxbits);
|
||||
|
|
@ -703,3 +537,33 @@ diff -up openssh-7.7p1/ssh-keygen.c.fips openssh-7.7p1/ssh-keygen.c
|
|||
switch (type) {
|
||||
case KEY_DSA:
|
||||
if (*bitsp != 1024)
|
||||
@@ -1029,9 +1035,17 @@ do_gen_all_hostkeys(struct passwd *pw)
|
||||
first = 1;
|
||||
printf("%s: generating new host keys: ", __progname);
|
||||
}
|
||||
+ type = sshkey_type_from_name(key_types[i].key_type);
|
||||
+
|
||||
+ /* Skip the keys that are not supported in FIPS mode */
|
||||
+ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) {
|
||||
+ logit("Skipping %s key in FIPS mode",
|
||||
+ key_types[i].key_type_display);
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
printf("%s ", key_types[i].key_type_display);
|
||||
fflush(stdout);
|
||||
- type = sshkey_type_from_name(key_types[i].key_type);
|
||||
if ((fd = mkstemp(prv_tmp)) == -1) {
|
||||
error("Could not save your public key in %s: %s",
|
||||
prv_tmp, strerror(errno));
|
||||
diff -up openssh-8.0p1/sshd_config.xxx openssh-8.0p1/sshd_config
|
||||
--- openssh-8.0p1/sshd_config.xxx 2023-10-30 13:01:59.150952364 +0100
|
||||
+++ openssh-8.0p1/sshd_config 2023-10-30 13:02:56.662231354 +0100
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
HostKey /etc/ssh/ssh_host_rsa_key
|
||||
HostKey /etc/ssh/ssh_host_ecdsa_key
|
||||
+#In FIPS mode Ed25519 keys are not supported, please comment out the next line
|
||||
HostKey /etc/ssh/ssh_host_ed25519_key
|
||||
|
||||
# Ciphers and keying
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ index a5a81ed2..63f877f2 100644
|
|||
+ /* There is at least one other ccache in collection
|
||||
+ * we can switch to */
|
||||
+ krb5_cc_switch(ctx, ccache);
|
||||
+ } else {
|
||||
+ } else if (authctxt->krb5_ccname != NULL) {
|
||||
+ /* Clean up the collection too */
|
||||
+ strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10);
|
||||
+ krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1;
|
||||
|
|
@ -113,29 +113,12 @@ index a5a81ed2..63f877f2 100644
|
|||
if (authctxt->krb5_user) {
|
||||
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
|
||||
authctxt->krb5_user = NULL;
|
||||
@@ -237,36 +287,186 @@ krb5_cleanup_proc(Authctxt *authctxt)
|
||||
@@ -237,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt)
|
||||
}
|
||||
}
|
||||
|
||||
-#ifndef HEIMDAL
|
||||
-krb5_error_code
|
||||
-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
|
||||
- int tmpfd, ret, oerrno;
|
||||
- char ccname[40];
|
||||
- mode_t old_umask;
|
||||
|
||||
- ret = snprintf(ccname, sizeof(ccname),
|
||||
- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
- if (ret < 0 || (size_t)ret >= sizeof(ccname))
|
||||
- return ENOMEM;
|
||||
-
|
||||
- old_umask = umask(0177);
|
||||
- tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
- oerrno = errno;
|
||||
- umask(old_umask);
|
||||
- if (tmpfd == -1) {
|
||||
- logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
- return oerrno;
|
||||
+
|
||||
+#if !defined(HEIMDAL)
|
||||
+int
|
||||
+ssh_asprintf_append(char **dsc, const char *fmt, ...) {
|
||||
|
|
@ -195,14 +178,13 @@ index a5a81ed2..63f877f2 100644
|
|||
+ continue;
|
||||
+ } else {
|
||||
+ p_o = strchr(p_n, '}') + 1;
|
||||
+ p_o = '\0';
|
||||
+ *p_o = '\0';
|
||||
+ debug("%s: unsupported token %s in %s", __func__, p_n, template);
|
||||
+ /* unknown token, fallback to the default */
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
+ }
|
||||
+
|
||||
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1)
|
||||
+ goto cleanup;
|
||||
+
|
||||
|
|
@ -216,7 +198,10 @@ index a5a81ed2..63f877f2 100644
|
|||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code
|
||||
krb5_error_code
|
||||
-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
|
||||
- int tmpfd, ret, oerrno;
|
||||
- char ccname[40];
|
||||
+ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
|
||||
+ profile_t p;
|
||||
+ int ret = 0;
|
||||
|
|
@ -241,14 +226,27 @@ index a5a81ed2..63f877f2 100644
|
|||
+ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) {
|
||||
+ int tmpfd, ret, oerrno, type_len;
|
||||
+ char *ccname = NULL;
|
||||
+ mode_t old_umask;
|
||||
mode_t old_umask;
|
||||
+ char *type = NULL, *colon = NULL;
|
||||
+
|
||||
|
||||
- ret = snprintf(ccname, sizeof(ccname),
|
||||
- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
- if (ret < 0 || (size_t)ret >= sizeof(ccname))
|
||||
- return ENOMEM;
|
||||
-
|
||||
- old_umask = umask(0177);
|
||||
- tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
- oerrno = errno;
|
||||
- umask(old_umask);
|
||||
- if (tmpfd == -1) {
|
||||
- logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
- return oerrno;
|
||||
- }
|
||||
+ debug3("%s: called", __func__);
|
||||
+ if (need_environment)
|
||||
+ *need_environment = 0;
|
||||
+ ret = ssh_krb5_get_cctemplate(ctx, &ccname);
|
||||
+ if (ret || !ccname || options.kerberos_unique_ticket) {
|
||||
+ if (ret || !ccname || options.kerberos_unique_ccache) {
|
||||
+ /* Otherwise, go with the old method */
|
||||
+ if (ccname)
|
||||
+ free(ccname);
|
||||
|
|
@ -258,7 +256,8 @@ index a5a81ed2..63f877f2 100644
|
|||
+ "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
+ if (ret < 0)
|
||||
+ return ENOMEM;
|
||||
+
|
||||
|
||||
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
+ old_umask = umask(0177);
|
||||
+ tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
oerrno = errno;
|
||||
|
|
@ -307,6 +306,7 @@ index a5a81ed2..63f877f2 100644
|
|||
+ if (krb5_cc_support_switch(ctx, type)) {
|
||||
+ debug3("%s: calling cc_new_unique(%s)", __func__, ccname);
|
||||
+ ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
|
||||
+ free(type);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
|
|
@ -317,6 +317,7 @@ index a5a81ed2..63f877f2 100644
|
|||
+ * it is already unique from above or the type does not support
|
||||
+ * collections
|
||||
+ */
|
||||
+ free(type);
|
||||
+ debug3("%s: calling cc_resolve(%s)", __func__, ccname);
|
||||
+ return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
+ }
|
||||
|
|
@ -343,11 +344,10 @@ index 29491df9..fdab5040 100644
|
|||
+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
|
||||
#endif
|
||||
#endif
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
|
||||
index 795992d9..0623a107 100644
|
||||
--- a/gss-serv-krb5.c
|
||||
+++ b/gss-serv-krb5.c
|
||||
@@ -114,7 +114,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c
|
||||
--- openssh-7.9p1/gss-serv-krb5.c.ccache_name 2019-03-01 15:17:42.708611802 +0100
|
||||
+++ openssh-7.9p1/gss-serv-krb5.c 2019-03-01 15:17:42.713611844 +0100
|
||||
@@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
|
||||
/* This writes out any forwarded credentials from the structure populated
|
||||
* during userauth. Called after we have setuid to the user */
|
||||
|
||||
|
|
@ -356,12 +356,9 @@ index 795992d9..0623a107 100644
|
|||
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
{
|
||||
krb5_ccache ccache;
|
||||
@@ -121,16 +121,17 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
krb5_error_code problem;
|
||||
krb5_principal princ;
|
||||
@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
|
||||
OM_uint32 maj_status, min_status;
|
||||
- const char *new_ccname, *new_cctype;
|
||||
+ int len;
|
||||
const char *new_ccname, *new_cctype;
|
||||
const char *errmsg;
|
||||
+ int set_env = 0;
|
||||
|
||||
|
|
@ -377,7 +374,7 @@ index 795992d9..0623a107 100644
|
|||
|
||||
#ifdef HEIMDAL
|
||||
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
|
||||
@@ -144,14 +145,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
|
||||
krb5_get_err_text(krb_context, problem));
|
||||
# endif
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
|
|
@ -396,7 +393,7 @@ index 795992d9..0623a107 100644
|
|||
}
|
||||
#endif /* #ifdef HEIMDAL */
|
||||
|
||||
@@ -160,7 +161,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
|
||||
errmsg = krb5_get_error_message(krb_context, problem);
|
||||
logit("krb5_parse_name(): %.100s", errmsg);
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
|
|
@ -405,7 +402,7 @@ index 795992d9..0623a107 100644
|
|||
}
|
||||
|
||||
if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
|
||||
@@ -169,7 +170,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
krb5_free_principal(krb_context, princ);
|
||||
krb5_cc_destroy(krb_context, ccache);
|
||||
|
|
@ -414,7 +411,7 @@ index 795992d9..0623a107 100644
|
|||
}
|
||||
|
||||
krb5_free_principal(krb_context, princ);
|
||||
@@ -178,37 +179,27 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
|
||||
client->creds, ccache))) {
|
||||
logit("gss_krb5_copy_ccache() failed");
|
||||
krb5_cc_destroy(krb_context, ccache);
|
||||
|
|
@ -422,30 +419,29 @@ index 795992d9..0623a107 100644
|
|||
+ return 0;
|
||||
}
|
||||
|
||||
- new_cctype = krb5_cc_get_type(krb_context, ccache);
|
||||
- new_ccname = krb5_cc_get_name(krb_context, ccache);
|
||||
new_cctype = krb5_cc_get_type(krb_context, ccache);
|
||||
new_ccname = krb5_cc_get_name(krb_context, ccache);
|
||||
-
|
||||
- client->store.envvar = "KRB5CCNAME";
|
||||
-#ifdef USE_CCAPI
|
||||
- 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);
|
||||
xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname);
|
||||
- if (strcmp(new_cctype, "DIR") == 0) {
|
||||
- char *p;
|
||||
- p = strrchr(client->store.envval, '/');
|
||||
- if (p)
|
||||
- *p = '\0';
|
||||
- }
|
||||
-#endif
|
||||
+
|
||||
+ if (set_env) {
|
||||
+ const char *filename = krb5_cc_get_name(krb_context, ccache);
|
||||
+ client->store.envvar = "KRB5CCNAME";
|
||||
+ len = strlen(filename) + 6;
|
||||
+ client->store.envval = xmalloc(len);
|
||||
+ snprintf(client->store.envval, len, "FILE:%s", filename);
|
||||
+ }
|
||||
}
|
||||
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)
|
||||
|
|
@ -453,7 +449,7 @@ index 795992d9..0623a107 100644
|
|||
do_pam_putenv(client->store.envvar, client->store.envval);
|
||||
#endif
|
||||
|
||||
krb5_cc_close(krb_context, ccache);
|
||||
@@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
|
||||
|
||||
client->store.data = krb_context;
|
||||
|
||||
|
|
@ -484,15 +480,25 @@ index 6cae720e..16e55cbc 100644
|
|||
}
|
||||
|
||||
/* This allows GSSAPI methods to do things to the childs environment based
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index cb578658..a6e01df2 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -122,6 +122,7 @@ initialize_server_options(ServerOptions *options)
|
||||
@@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() {
|
||||
char *envstr;
|
||||
#endif
|
||||
|
||||
- if (gssapi_client.store.filename == NULL &&
|
||||
- gssapi_client.store.envval == NULL &&
|
||||
- gssapi_client.store.envvar == NULL)
|
||||
+ if (gssapi_client.store.envval == NULL)
|
||||
return;
|
||||
|
||||
ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
|
||||
diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c
|
||||
--- openssh-7.9p1/servconf.c.ccache_name 2019-03-01 15:17:42.704611768 +0100
|
||||
+++ openssh-7.9p1/servconf.c 2019-03-01 15:17:42.713611844 +0100
|
||||
@@ -123,6 +123,7 @@ initialize_server_options(ServerOptions
|
||||
options->kerberos_or_local_passwd = -1;
|
||||
options->kerberos_ticket_cleanup = -1;
|
||||
options->kerberos_get_afs_token = -1;
|
||||
+ options->kerberos_unique_ticket = -1;
|
||||
+ options->kerberos_unique_ccache = -1;
|
||||
options->gss_authentication=-1;
|
||||
options->gss_keyex = -1;
|
||||
options->gss_cleanup_creds = -1;
|
||||
|
|
@ -500,8 +506,8 @@ index cb578658..a6e01df2 100644
|
|||
options->kerberos_ticket_cleanup = 1;
|
||||
if (options->kerberos_get_afs_token == -1)
|
||||
options->kerberos_get_afs_token = 0;
|
||||
+ if (options->kerberos_unique_ticket == -1)
|
||||
+ options->kerberos_unique_ticket = 0;
|
||||
+ if (options->kerberos_unique_ccache == -1)
|
||||
+ options->kerberos_unique_ccache = 0;
|
||||
if (options->gss_authentication == -1)
|
||||
options->gss_authentication = 0;
|
||||
if (options->gss_keyex == -1)
|
||||
|
|
@ -510,7 +516,7 @@ index cb578658..a6e01df2 100644
|
|||
sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
- sKerberosGetAFSToken, sChallengeResponseAuthentication,
|
||||
+ sKerberosGetAFSToken, sKerberosUniqueTicket,
|
||||
+ sKerberosGetAFSToken, sKerberosUniqueCCache,
|
||||
+ sChallengeResponseAuthentication,
|
||||
sPasswordAuthentication, sKbdInteractiveAuthentication,
|
||||
sListenAddress, sAddressFamily,
|
||||
|
|
@ -519,13 +525,13 @@ index cb578658..a6e01df2 100644
|
|||
#else
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
+ { "kerberosuniqueticket", sKerberosUniqueTicket, SSHCFG_GLOBAL },
|
||||
+ { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
|
||||
#else
|
||||
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "kerberosuniqueticket", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
|
|
@ -533,8 +539,8 @@ index cb578658..a6e01df2 100644
|
|||
intptr = &options->kerberos_get_afs_token;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sKerberosUniqueTicket:
|
||||
+ intptr = &options->kerberos_unique_ticket;
|
||||
+ case sKerberosUniqueCCache:
|
||||
+ intptr = &options->kerberos_unique_ccache;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sGssAuthentication:
|
||||
|
|
@ -544,7 +550,7 @@ index cb578658..a6e01df2 100644
|
|||
# ifdef USE_AFS
|
||||
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
|
||||
# endif
|
||||
+ dump_cfg_fmtint(sKerberosUniqueTicket, o->kerberos_unique_ticket);
|
||||
+ dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
|
||||
|
|
@ -556,7 +562,7 @@ index db8362c6..4fa42d64 100644
|
|||
* file on logout. */
|
||||
int kerberos_get_afs_token; /* If true, try to get AFS token if
|
||||
* authenticated with Kerberos. */
|
||||
+ int kerberos_unique_ticket; /* If true, the aquired ticket will
|
||||
+ int kerberos_unique_ccache; /* If true, the acquired ticket will
|
||||
+ * be stored in per-session ccache */
|
||||
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||
int gss_keyex; /* If true, permit GSSAPI key exchange */
|
||||
|
|
@ -588,14 +594,6 @@ diff --git a/ssh-gss.h b/ssh-gss.h
|
|||
index 6593e422..245178af 100644
|
||||
--- a/ssh-gss.h
|
||||
+++ b/ssh-gss.h
|
||||
@@ -62,7 +62,6 @@
|
||||
#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-"
|
||||
|
||||
typedef struct {
|
||||
- char *filename;
|
||||
char *envvar;
|
||||
char *envval;
|
||||
struct passwd *owner;
|
||||
@@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct {
|
||||
int (*dochild) (ssh_gssapi_client *);
|
||||
int (*userok) (ssh_gssapi_client *, char *);
|
||||
|
|
@ -631,16 +629,18 @@ diff --git a/sshd_config.5 b/sshd_config.5
|
|||
index c0683d4a..2349f477 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -860,6 +860,12 @@ Specifies whether to automatically destroy the user's ticket cache
|
||||
@@ -860,6 +860,14 @@ Specifies whether to automatically destroy the user's ticket cache
|
||||
file on logout.
|
||||
The default is
|
||||
.Cm yes .
|
||||
+.It Cm KerberosUniqueTicket
|
||||
+Specifies whether to store the aquired tickets in the per-session credential
|
||||
+cache or whether to use per-user credential cache, which might overwrite
|
||||
+tickets aquired in different sessions of the same user.
|
||||
+The default is
|
||||
+.Cm no .
|
||||
+.It Cm KerberosUniqueCCache
|
||||
+Specifies whether to store the acquired tickets in the per-session credential
|
||||
+cache under /tmp/ or whether to use per-user credential cache as configured in
|
||||
+.Pa /etc/krb5.conf .
|
||||
+The default value
|
||||
+.Cm no
|
||||
+can lead to overwriting previous tickets by subseqent connections to the same
|
||||
+user account.
|
||||
.It Cm KexAlgorithms
|
||||
Specifies the available KEX (Key Exchange) algorithms.
|
||||
Multiple algorithms must be comma-separated.
|
||||
|
|
|
|||
|
|
@ -1,26 +1,25 @@
|
|||
diff -up openssh-7.7p1/ssh_config.redhat openssh-7.7p1/ssh_config
|
||||
--- openssh-7.7p1/ssh_config.redhat 2018-04-02 07:38:28.000000000 +0200
|
||||
+++ openssh-7.7p1/ssh_config 2018-07-03 10:44:06.522245125 +0200
|
||||
@@ -44,3 +44,7 @@
|
||||
@@ -44,3 +44,8 @@
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
# RekeyLimit 1G 1h
|
||||
+#
|
||||
+# This system is following system-wide crypto policy.
|
||||
+# To modify the system-wide ssh configuration, create a *.conf file under
|
||||
+# /etc/ssh/ssh_config.d/ which will be automatically included below
|
||||
+Include /etc/ssh/ssh_config.d/*.conf
|
||||
diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat
|
||||
--- openssh-7.7p1/ssh_config_redhat.redhat 2018-07-03 10:44:06.522245125 +0200
|
||||
+++ openssh-7.7p1/ssh_config_redhat 2018-07-03 10:44:06.522245125 +0200
|
||||
@@ -0,0 +1,20 @@
|
||||
+# Follow system-wide Crypto Policy, if defined:
|
||||
+Include /etc/crypto-policies/back-ends/openssh.config
|
||||
@@ -0,0 +1,21 @@
|
||||
+# The options here are in the "Match final block" to be applied as the last
|
||||
+# options and could be potentially overwritten by the user configuration
|
||||
+Match final all
|
||||
+ # Follow system-wide Crypto Policy, if defined:
|
||||
+ Include /etc/crypto-policies/back-ends/openssh.config
|
||||
+
|
||||
+# Uncomment this if you want to use .local domain
|
||||
+# Host *.local
|
||||
+# CheckHostIP no
|
||||
+
|
||||
+Host *
|
||||
+ GSSAPIAuthentication yes
|
||||
+
|
||||
+# If this option is set to yes then remote X11 clients will have full access
|
||||
|
|
@ -33,6 +32,10 @@ diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat
|
|||
+ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
|
||||
+ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
|
||||
+ SendEnv XMODIFIERS
|
||||
+
|
||||
+# Uncomment this if you want to use .local domain
|
||||
+# Host *.local
|
||||
+# CheckHostIP no
|
||||
diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0
|
||||
--- openssh-7.7p1/sshd_config.0.redhat 2018-04-02 07:39:27.000000000 +0200
|
||||
+++ openssh-7.7p1/sshd_config.0 2018-07-03 10:44:06.523245133 +0200
|
||||
|
|
@ -64,7 +67,7 @@ diff -up openssh-7.7p1/sshd_config.5.redhat openssh-7.7p1/sshd_config.5
|
|||
diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config
|
||||
--- openssh-7.7p1/sshd_config.redhat 2018-04-02 07:38:28.000000000 +0200
|
||||
+++ openssh-7.7p1/sshd_config 2018-07-03 10:45:16.950782466 +0200
|
||||
@@ -10,20 +10,34 @@
|
||||
@@ -10,20 +10,31 @@
|
||||
# possible, but leave them commented. Uncommented options override the
|
||||
# default value.
|
||||
|
||||
|
|
@ -87,14 +90,11 @@ diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config
|
|||
# Ciphers and keying
|
||||
#RekeyLimit default none
|
||||
|
||||
+# System-wide Crypto policy:
|
||||
+# This system is following system-wide crypto policy. The changes to
|
||||
+# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any
|
||||
+# effect here. They will be overridden by command-line options passed on
|
||||
+# the server start up.
|
||||
+# To opt out, uncomment a line with redefinition of CRYPTO_POLICY=
|
||||
+# variable in /etc/sysconfig/sshd to overwrite the policy.
|
||||
+# For more information, see manual page for update-crypto-policies(8).
|
||||
+# crypto properties (Ciphers, MACs, ...) will not have any effect here.
|
||||
+# They will be overridden by command-line options passed to the server
|
||||
+# on command line.
|
||||
+# Please, check manual pages for update-crypto-policies(8) and sshd_config(5).
|
||||
+
|
||||
# Logging
|
||||
#SyslogFacility AUTH
|
||||
|
|
@ -142,7 +142,7 @@ diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config
|
|||
#PermitTTY yes
|
||||
-#PrintMotd yes
|
||||
+
|
||||
+# It is recommended to use pam_motd in /etc/pam.d/ssh instead of PrintMotd,
|
||||
+# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd,
|
||||
+# as it is more configurable and versatile than the built-in version.
|
||||
+PrintMotd no
|
||||
+
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ diff --git a/sshd.c b/sshd.c
|
|||
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
|
||||
cfg, NULL);
|
||||
|
||||
+ /* 'UsePAM no' is not supported in Fedora */
|
||||
+ /* 'UsePAM no' is not supported in RHEL */
|
||||
+ if (! options.use_pam)
|
||||
+ logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems.");
|
||||
+ logit("WARNING: 'UsePAM no' is not supported in RHEL and may cause several problems.");
|
||||
+
|
||||
seed_rng();
|
||||
|
||||
/* Fill in default values for those options not explicitly set. */
|
||||
fill_default_server_options(&options);
|
||||
|
||||
diff --git a/sshd_config b/sshd_config
|
||||
--- a/sshd_config
|
||||
+++ b/sshd_config
|
||||
|
|
@ -19,7 +19,7 @@ diff --git a/sshd_config b/sshd_config
|
|||
# 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
|
||||
+# WARNING: 'UsePAM no' is not supported in RHEL and may cause several
|
||||
+# problems.
|
||||
UsePAM yes
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,72 +0,0 @@
|
|||
diff -up openssh/misc.c.config openssh/misc.c
|
||||
--- openssh/misc.c.config 2018-08-22 13:58:54.922807799 +0200
|
||||
+++ openssh/misc.c 2018-08-22 13:58:55.000808428 +0200
|
||||
@@ -485,7 +485,7 @@ put_host_port(const char *host, u_short
|
||||
* The delimiter char, if present, is stored in delim.
|
||||
* If this is the last field, *cp is set to NULL.
|
||||
*/
|
||||
-static char *
|
||||
+char *
|
||||
hpdelim2(char **cp, char *delim)
|
||||
{
|
||||
char *s, *old;
|
||||
diff -up openssh/misc.h.config openssh/misc.h
|
||||
--- openssh/misc.h.config 2018-08-20 07:57:29.000000000 +0200
|
||||
+++ openssh/misc.h 2018-08-22 13:58:55.001808436 +0200
|
||||
@@ -54,6 +54,7 @@ int set_rdomain(int, const char *);
|
||||
int a2port(const char *);
|
||||
int a2tun(const char *, int *);
|
||||
char *put_host_port(const char *, u_short);
|
||||
+char *hpdelim2(char **, char *);
|
||||
char *hpdelim(char **);
|
||||
char *cleanhostname(char *);
|
||||
char *colon(char *);
|
||||
diff -up openssh/servconf.c.config openssh/servconf.c
|
||||
--- openssh/servconf.c.config 2018-08-22 13:58:54.989808340 +0200
|
||||
+++ openssh/servconf.c 2018-08-22 14:18:49.235443937 +0200
|
||||
@@ -886,7 +886,7 @@ process_permitopen_list(struct ssh *ssh,
|
||||
{
|
||||
u_int i;
|
||||
int port;
|
||||
- char *host, *arg, *oarg;
|
||||
+ char *host, *arg, *oarg, ch;
|
||||
int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
|
||||
const char *what = lookup_opcode_name(opcode);
|
||||
|
||||
@@ -904,8 +904,8 @@ process_permitopen_list(struct ssh *ssh,
|
||||
/* Otherwise treat it as a list of permitted host:port */
|
||||
for (i = 0; i < num_opens; i++) {
|
||||
oarg = arg = xstrdup(opens[i]);
|
||||
- host = hpdelim(&arg);
|
||||
- if (host == NULL)
|
||||
+ host = hpdelim2(&arg, &ch);
|
||||
+ if (host == NULL || ch == '/')
|
||||
fatal("%s: missing host in %s", __func__, what);
|
||||
host = cleanhostname(host);
|
||||
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
|
||||
@@ -1323,8 +1323,10 @@ process_server_config_line(ServerOptions
|
||||
port = 0;
|
||||
p = arg;
|
||||
} else {
|
||||
- p = hpdelim(&arg);
|
||||
- if (p == NULL)
|
||||
+ char ch;
|
||||
+ arg2 = NULL;
|
||||
+ p = hpdelim2(&arg, &ch);
|
||||
+ if (p == NULL || ch == '/')
|
||||
fatal("%s line %d: bad address:port usage",
|
||||
filename, linenum);
|
||||
p = cleanhostname(p);
|
||||
@@ -1965,9 +1967,10 @@ process_server_config_line(ServerOptions
|
||||
*/
|
||||
xasprintf(&arg2, "*:%s", arg);
|
||||
} else {
|
||||
+ char ch;
|
||||
arg2 = xstrdup(arg);
|
||||
- p = hpdelim(&arg);
|
||||
- if (p == NULL) {
|
||||
+ p = hpdelim2(&arg, &ch);
|
||||
+ if (p == NULL || ch == '/') {
|
||||
fatal("%s line %d: missing host in %s",
|
||||
filename, linenum,
|
||||
lookup_opcode_name(opcode));
|
||||
|
|
@ -4,11 +4,11 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c
|
|||
@@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Authmethod *m = NULL;
|
||||
char *user, *service, *method, *style = NULL;
|
||||
char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ char *role = NULL;
|
||||
+#endif
|
||||
int authenticated = 0;
|
||||
int r, authenticated = 0;
|
||||
double tstart = monotime_double();
|
||||
|
||||
@@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32
|
||||
|
|
@ -37,9 +37,9 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c
|
|||
+ mm_inform_authrole(role);
|
||||
+#endif
|
||||
+ }
|
||||
userauth_banner();
|
||||
userauth_banner(ssh);
|
||||
if (auth2_setup_methods_lists(authctxt) != 0)
|
||||
packet_disconnect("no authentication methods enabled");
|
||||
ssh_packet_disconnect(ssh,
|
||||
diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
|
||||
--- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200
|
||||
+++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200
|
||||
|
|
@ -57,7 +57,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
|
|||
mic.length = len;
|
||||
- ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (authctxt->role && (strlen(authctxt->role) > 0))
|
||||
+ if (authctxt->role && authctxt->role[0] != 0)
|
||||
+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
|
||||
+ else
|
||||
+#endif
|
||||
|
|
@ -197,15 +197,15 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
|
|||
--- openssh/monitor.c.role-mls 2018-08-20 07:57:29.000000000 +0200
|
||||
+++ openssh/monitor.c 2018-08-22 11:19:56.006844867 +0200
|
||||
@@ -115,6 +115,9 @@ int mm_answer_sign(int, struct sshbuf *)
|
||||
int mm_answer_pwnamallow(int, struct sshbuf *);
|
||||
int mm_answer_auth2_read_banner(int, struct sshbuf *);
|
||||
int mm_answer_authserv(int, struct sshbuf *);
|
||||
int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
|
||||
+#ifdef WITH_SELINUX
|
||||
+int mm_answer_authrole(int, struct sshbuf *);
|
||||
+int mm_answer_authrole(struct ssh *, int, struct sshbuf *);
|
||||
+#endif
|
||||
int mm_answer_authpassword(int, struct sshbuf *);
|
||||
int mm_answer_bsdauthquery(int, struct sshbuf *);
|
||||
int mm_answer_bsdauthrespond(int, struct sshbuf *);
|
||||
int mm_answer_authpassword(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *);
|
||||
@@ -189,6 +192,9 @@ struct mon_table mon_dispatch_proto20[]
|
||||
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
|
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
|
||||
|
|
@ -227,12 +227,12 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
|
|||
|
||||
#ifdef USE_PAM
|
||||
@@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb
|
||||
return (0);
|
||||
return found;
|
||||
}
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+int
|
||||
+mm_answer_authrole(int sock, struct sshbuf *m)
|
||||
+mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
+{
|
||||
+ int r;
|
||||
+ monitor_permit_authentications(1);
|
||||
|
|
@ -251,7 +251,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
|
|||
+#endif
|
||||
+
|
||||
int
|
||||
mm_answer_authpassword(int sock, struct sshbuf *m)
|
||||
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
{
|
||||
@@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i
|
||||
{
|
||||
|
|
@ -284,7 +284,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
|
|||
fail++;
|
||||
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
+ if ((s = strchr(p, '/')) != NULL)
|
||||
+ if ((s = strchr(cp, '/')) != NULL)
|
||||
+ *s = '\0';
|
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
|
|
@ -338,13 +338,13 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h
|
|||
--- openssh/monitor_wrap.h.role-mls 2018-08-22 11:14:56.818430941 +0200
|
||||
+++ openssh/monitor_wrap.h 2018-08-22 11:22:10.439929513 +0200
|
||||
@@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int);
|
||||
int mm_sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t,
|
||||
const char *, u_int compat);
|
||||
int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *,
|
||||
const u_char *, size_t, const char *, u_int compat);
|
||||
void mm_inform_authserv(char *, char *);
|
||||
+#ifdef WITH_SELINUX
|
||||
+void mm_inform_authrole(char *);
|
||||
+#endif
|
||||
struct passwd *mm_getpwnamallow(const char *);
|
||||
struct passwd *mm_getpwnamallow(struct ssh *, const char *);
|
||||
char *mm_auth2_read_banner(void);
|
||||
int mm_auth_password(struct ssh *, char *);
|
||||
diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in
|
||||
|
|
|
|||
42
openssh-7.9p1-ssh-copy-id.patch
Normal file
42
openssh-7.9p1-ssh-copy-id.patch
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
diff -up openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id openssh-7.9p1/contrib/ssh-copy-id
|
||||
--- openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id 2018-10-17 02:01:20.000000000 +0200
|
||||
+++ openssh-7.9p1/contrib/ssh-copy-id 2019-01-23 20:49:30.513393667 +0100
|
||||
@@ -112,7 +112,8 @@ do
|
||||
usage
|
||||
}
|
||||
|
||||
- OPT= OPTARG=
|
||||
+ OPT=
|
||||
+ OPTARG=
|
||||
# implement something like getopt to avoid Solaris pain
|
||||
case "$1" in
|
||||
-i?*|-o?*|-p?*)
|
||||
@@ -185,8 +185,8 @@
|
||||
usage
|
||||
fi
|
||||
|
||||
-# drop trailing colon
|
||||
-USER_HOST=$(printf "%s\n" "$1" | sed 's/:$//')
|
||||
+# don't drop trailing colon because it can be a valid ipv6 address
|
||||
+USER_HOST=$(printf "%s\n" "$1")
|
||||
# tack the hostname onto SSH_OPTS
|
||||
SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }'$(quote "$USER_HOST")'"
|
||||
# and populate "$@" for later use (only way to get proper quoting of options)
|
||||
@@ -261,7 +262,7 @@ populate_new_ids() {
|
||||
fi
|
||||
if [ -z "$NEW_IDS" ] ; then
|
||||
printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2
|
||||
- printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2
|
||||
+ printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' >&2
|
||||
exit 0
|
||||
fi
|
||||
printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2
|
||||
@@ -296,7 +297,7 @@ case "$REMOTE_VERSION" in
|
||||
# in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
|
||||
# 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh.
|
||||
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \
|
||||
- ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
|
||||
+ ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys || exit 1; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
|
||||
|| exit 1
|
||||
ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l)
|
||||
;;
|
||||
20
openssh-8.0p1-avoidkillall.patch
Normal file
20
openssh-8.0p1-avoidkillall.patch
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
diff --git a/sftp.c b/sftp.c
|
||||
index b66037f1..54538ff9 100644
|
||||
--- a/sftp.c
|
||||
+++ b/sftp.c
|
||||
@@ -220,9 +220,12 @@ static const struct CMD cmds[] = {
|
||||
static void
|
||||
killchild(int signo)
|
||||
{
|
||||
- if (sshpid > 1) {
|
||||
- kill(sshpid, SIGTERM);
|
||||
- waitpid(sshpid, NULL, 0);
|
||||
+ pid_t pid;
|
||||
+
|
||||
+ pid = sshpid;
|
||||
+ if (pid > 1) {
|
||||
+ kill(pid, SIGTERM);
|
||||
+ (void)waitpid(pid, NULL, 0);
|
||||
}
|
||||
|
||||
_exit(1);
|
||||
13
openssh-8.0p1-bigsshdconfig.patch
Normal file
13
openssh-8.0p1-bigsshdconfig.patch
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
diff --git a/msg.c b/msg.c
|
||||
index 99c25cd2..574a566e 100644
|
||||
--- a/msg.c
|
||||
+++ b/msg.c
|
||||
@@ -77,7 +77,7 @@ ssh_msg_recv(int fd, struct sshbuf *m)
|
||||
return (-1);
|
||||
}
|
||||
msg_len = get_u32(buf);
|
||||
- if (msg_len > 256 * 1024) {
|
||||
+ if (msg_len > sshbuf_max_size(m)) {
|
||||
error("ssh_msg_recv: read: bad msg_len %u", msg_len);
|
||||
return (-1);
|
||||
}
|
||||
33
openssh-8.0p1-channel-limits.patch
Normal file
33
openssh-8.0p1-channel-limits.patch
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
diff -up openssh-8.0p1/channels.c.channel-limits openssh-8.0p1/channels.c
|
||||
--- openssh-8.0p1/channels.c.channel-limits 2021-03-16 12:17:58.905576511 +0100
|
||||
+++ openssh-8.0p1/channels.c 2021-03-16 12:17:58.925576667 +0100
|
||||
@@ -354,6 +354,7 @@ channel_new(struct ssh *ssh, char *ctype
|
||||
struct ssh_channels *sc = ssh->chanctxt;
|
||||
u_int i, found;
|
||||
Channel *c;
|
||||
+ int r;
|
||||
|
||||
/* Try to find a free slot where to put the new channel. */
|
||||
for (i = 0; i < sc->channels_alloc; i++) {
|
||||
@@ -383,6 +384,8 @@ channel_new(struct ssh *ssh, char *ctype
|
||||
(c->output = sshbuf_new()) == NULL ||
|
||||
(c->extended = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
+ if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)
|
||||
+ fatal("%s: sshbuf_set_max_size: %s", __func__, ssh_err(r));
|
||||
c->ostate = CHAN_OUTPUT_OPEN;
|
||||
c->istate = CHAN_INPUT_OPEN;
|
||||
channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);
|
||||
diff -up openssh-8.0p1/channels.h.channel-limits openssh-8.0p1/channels.h
|
||||
--- openssh-8.0p1/channels.h.channel-limits 2021-03-16 12:17:58.868576223 +0100
|
||||
+++ openssh-8.0p1/channels.h 2021-03-16 12:17:58.907576527 +0100
|
||||
@@ -215,6 +215,9 @@ struct Channel {
|
||||
/* Read buffer size */
|
||||
#define CHAN_RBUF (16*1024)
|
||||
|
||||
+/* Maximum channel input buffer size */
|
||||
+#define CHAN_INPUT_MAX (16*1024*1024)
|
||||
+
|
||||
/* Hard limit on number of channels */
|
||||
#define CHANNELS_MAX_CHANNELS (16*1024)
|
||||
|
||||
28
openssh-8.0p1-client_alive_count_max.patch
Normal file
28
openssh-8.0p1-client_alive_count_max.patch
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
diff --git a/serverloop.c b/serverloop.c
|
||||
index e16eabe2..a8c99e2e 100644
|
||||
--- a/serverloop.c
|
||||
+++ b/serverloop.c
|
||||
@@ -184,7 +184,8 @@ client_alive_check(struct ssh *ssh)
|
||||
int r, channel_id;
|
||||
|
||||
/* timeout, check to see how many we have had */
|
||||
- if (ssh_packet_inc_alive_timeouts(ssh) >
|
||||
+ if (options.client_alive_count_max > 0 &&
|
||||
+ ssh_packet_inc_alive_timeouts(ssh) >
|
||||
options.client_alive_count_max) {
|
||||
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
|
||||
logit("Timeout, client not responding from %s", remote_id);
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index d47cb0d2..2cddbd59 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -519,6 +519,9 @@ is set to 15, and
|
||||
.Cm ClientAliveCountMax
|
||||
is left at the default, unresponsive SSH clients
|
||||
will be disconnected after approximately 45 seconds.
|
||||
+Setting a zero
|
||||
+.Cm ClientAliveCountMax
|
||||
+disables connection termination.
|
||||
.It Cm ClientAliveInterval
|
||||
Sets a timeout interval in seconds after which if no data has been received
|
||||
from the client,
|
||||
424
openssh-8.0p1-crypto-policies.patch
Normal file
424
openssh-8.0p1-crypto-policies.patch
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5
|
||||
--- openssh-8.0p1/ssh_config.5.crypto-policies 2020-03-24 17:32:54.821789205 +0100
|
||||
+++ openssh-8.0p1/ssh_config.5 2020-03-24 17:59:58.174122920 +0100
|
||||
@@ -357,17 +357,17 @@ or
|
||||
.Qq *.c.example.com
|
||||
domains.
|
||||
.It Cm CASignatureAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies which algorithms are allowed for signing of certificates
|
||||
by certificate authorities (CAs).
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-ecdsa-sha2-nistp256.ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
|
||||
-.Ed
|
||||
-.Pp
|
||||
.Xr ssh 1
|
||||
will not accept host certificates signed using algorithms other than those
|
||||
specified.
|
||||
+.Pp
|
||||
.It Cm CertificateFile
|
||||
Specifies a file from which the user's certificate is read.
|
||||
A corresponding private key must be provided separately in order
|
||||
@@ -420,16 +420,21 @@ If the option is set to
|
||||
.Cm no ,
|
||||
the check will not be executed.
|
||||
.It Cm Ciphers
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the ciphers allowed and their order of preference.
|
||||
Multiple ciphers must be comma-separated.
|
||||
If the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the specified ciphers will be appended to the default set
|
||||
+character, then the specified ciphers will be appended to the built-in default set
|
||||
instead of replacing them.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified ciphers (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in default set instead of replacing them.
|
||||
.Pp
|
||||
The supported ciphers are:
|
||||
.Bd -literal -offset indent
|
||||
@@ -445,13 +450,6 @@ aes256-gcm@openssh.com
|
||||
chacha20-poly1305@openssh.com
|
||||
.Ed
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-chacha20-poly1305@openssh.com,
|
||||
-aes128-ctr,aes192-ctr,aes256-ctr,
|
||||
-aes128-gcm@openssh.com,aes256-gcm@openssh.com
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available ciphers may also be obtained using
|
||||
.Qq ssh -Q cipher .
|
||||
.It Cm ClearAllForwardings
|
||||
@@ -800,6 +798,11 @@ command line will be passed untouched to
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm GSSAPIKexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
The list of key exchange algorithms that are offered for GSSAPI
|
||||
key exchange. Possible values are
|
||||
.Bd -literal -offset 3n
|
||||
@@ -812,9 +815,8 @@ gss-nistp256-sha256-,
|
||||
gss-curve25519-sha256-
|
||||
.Ed
|
||||
.Pp
|
||||
-The default is
|
||||
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
|
||||
This option only applies to connections using GSSAPI.
|
||||
+.Pp
|
||||
.It Cm HashKnownHosts
|
||||
Indicates that
|
||||
.Xr ssh 1
|
||||
@@ -1114,26 +1115,21 @@ it may be zero or more of:
|
||||
and
|
||||
.Cm pam .
|
||||
.It Cm KexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the available KEX (Key Exchange) algorithms.
|
||||
Multiple algorithms must be comma-separated.
|
||||
Alternately if the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the specified methods will be appended to the default set
|
||||
+character, then the specified methods will be appended to the built-in default set
|
||||
instead of replacing them.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified methods (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-curve25519-sha256,curve25519-sha256@libssh.org,
|
||||
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
|
||||
-diffie-hellman-group-exchange-sha256,
|
||||
-diffie-hellman-group16-sha512,
|
||||
-diffie-hellman-group18-sha512,
|
||||
-diffie-hellman-group14-sha256,
|
||||
-diffie-hellman-group14-sha1
|
||||
-.Ed
|
||||
+from the built-in default set instead of replacing them.
|
||||
.Pp
|
||||
The list of available key exchange algorithms may also be obtained using
|
||||
.Qq ssh -Q kex .
|
||||
@@ -1193,33 +1189,29 @@ The default is INFO.
|
||||
DEBUG and DEBUG1 are equivalent.
|
||||
DEBUG2 and DEBUG3 each specify higher levels of verbose output.
|
||||
.It Cm MACs
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the MAC (message authentication code) algorithms
|
||||
in order of preference.
|
||||
The MAC algorithm is used for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
If the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the specified algorithms will be appended to the default set
|
||||
+character, then the specified algorithms will be appended to the built-in default set
|
||||
instead of replacing them.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in default set instead of replacing them.
|
||||
.Pp
|
||||
The algorithms that contain
|
||||
.Qq -etm
|
||||
calculate the MAC after encryption (encrypt-then-mac).
|
||||
These are considered safer and their use recommended.
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
|
||||
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
|
||||
-hmac-sha1-etm@openssh.com,
|
||||
-umac-64@openssh.com,umac-128@openssh.com,
|
||||
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available MAC algorithms may also be obtained using
|
||||
.Qq ssh -Q mac .
|
||||
.It Cm NoHostAuthenticationForLocalhost
|
||||
@@ -1352,27 +1344,21 @@ instead of continuing to execute and pas
|
||||
The default is
|
||||
.Cm no .
|
||||
.It Cm PubkeyAcceptedKeyTypes
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the key types that will be used for public key authentication
|
||||
as a comma-separated list of patterns.
|
||||
Alternately if the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the key types after it will be appended to the default
|
||||
+character, then the key types after it will be appended to the built-in default
|
||||
instead of replacing it.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified key types (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
-The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-rsa-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
|
||||
-.Ed
|
||||
+from the built-in default set instead of replacing them.
|
||||
.Pp
|
||||
The list of available key types may also be obtained using
|
||||
.Qq ssh -Q key .
|
||||
diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5
|
||||
--- openssh-8.0p1/sshd_config.5.crypto-policies 2020-03-24 17:32:54.802788908 +0100
|
||||
+++ openssh-8.0p1/sshd_config.5 2020-03-24 17:54:13.347740176 +0100
|
||||
@@ -383,16 +383,16 @@ If the argument is
|
||||
then no banner is displayed.
|
||||
By default, no banner is displayed.
|
||||
.It Cm CASignatureAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies which algorithms are allowed for signing of certificates
|
||||
by certificate authorities (CAs).
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-ecdsa-sha2-nistp256.ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
|
||||
-.Ed
|
||||
-.Pp
|
||||
Certificates signed using other algorithms will not be accepted for
|
||||
public key or host-based authentication.
|
||||
+.Pp
|
||||
.It Cm ChallengeResponseAuthentication
|
||||
Specifies whether challenge-response authentication is allowed (e.g. via
|
||||
PAM or through authentication styles supported in
|
||||
@@ -454,16 +454,21 @@ The default is
|
||||
indicating not to
|
||||
.Xr chroot 2 .
|
||||
.It Cm Ciphers
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the ciphers allowed.
|
||||
Multiple ciphers must be comma-separated.
|
||||
If the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the specified ciphers will be appended to the default set
|
||||
+character, then the specified ciphers will be appended to the built-in default set
|
||||
instead of replacing them.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified ciphers (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in default set instead of replacing them.
|
||||
.Pp
|
||||
The supported ciphers are:
|
||||
.Pp
|
||||
@@ -490,13 +495,6 @@ aes256-gcm@openssh.com
|
||||
chacha20-poly1305@openssh.com
|
||||
.El
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-chacha20-poly1305@openssh.com,
|
||||
-aes128-ctr,aes192-ctr,aes256-ctr,
|
||||
-aes128-gcm@openssh.com,aes256-gcm@openssh.com
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available ciphers may also be obtained using
|
||||
.Qq ssh -Q cipher .
|
||||
.It Cm ClientAliveCountMax
|
||||
@@ -688,6 +686,11 @@ For this to work
|
||||
.Cm GSSAPIKeyExchange
|
||||
needs to be enabled in the server and also used by the client.
|
||||
.It Cm GSSAPIKexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
The list of key exchange algorithms that are accepted by GSSAPI
|
||||
key exchange. Possible values are
|
||||
.Bd -literal -offset 3n
|
||||
@@ -700,8 +703,6 @@ gss-nistp256-sha256-,
|
||||
gss-curve25519-sha256-
|
||||
.Ed
|
||||
.Pp
|
||||
-The default is
|
||||
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
|
||||
This option only applies to connections using GSSAPI.
|
||||
.It Cm HostbasedAcceptedKeyTypes
|
||||
Specifies the key types that will be accepted for hostbased authentication
|
||||
@@ -791,19 +791,13 @@ is specified, the location of the socket
|
||||
.Ev SSH_AUTH_SOCK
|
||||
environment variable.
|
||||
.It Cm HostKeyAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the host key algorithms
|
||||
that the server offers.
|
||||
-The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-rsa-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
|
||||
-.Ed
|
||||
.Pp
|
||||
The list of available key types may also be obtained using
|
||||
.Qq ssh -Q key .
|
||||
@@ -922,16 +916,21 @@ Specifies whether to look at .k5login fi
|
||||
The default is
|
||||
.Cm yes .
|
||||
.It Cm KexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the available KEX (Key Exchange) algorithms.
|
||||
Multiple algorithms must be comma-separated.
|
||||
Alternately if the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the specified methods will be appended to the default set
|
||||
+character, then the specified methods will be appended to the built-in default set
|
||||
instead of replacing them.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified methods (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in default set instead of replacing them.
|
||||
The supported algorithms are:
|
||||
.Pp
|
||||
.Bl -item -compact -offset indent
|
||||
@@ -961,15 +960,6 @@ ecdh-sha2-nistp384
|
||||
ecdh-sha2-nistp521
|
||||
.El
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-curve25519-sha256,curve25519-sha256@libssh.org,
|
||||
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
|
||||
-diffie-hellman-group-exchange-sha256,
|
||||
-diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
|
||||
-diffie-hellman-group14-sha256,diffie-hellman-group14-sha1
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available key exchange algorithms may also be obtained using
|
||||
.Qq ssh -Q kex .
|
||||
.It Cm ListenAddress
|
||||
@@ -1038,17 +1028,22 @@ DEBUG and DEBUG1 are equivalent.
|
||||
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
|
||||
Logging with a DEBUG level violates the privacy of users and is not recommended.
|
||||
.It Cm MACs
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the available MAC (message authentication code) algorithms.
|
||||
The MAC algorithm is used for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
If the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the specified algorithms will be appended to the default set
|
||||
+character, then the specified algorithms will be appended to the built-in default set
|
||||
instead of replacing them.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in default set instead of replacing them.
|
||||
.Pp
|
||||
The algorithms that contain
|
||||
.Qq -etm
|
||||
@@ -1091,15 +1086,6 @@ umac-64-etm@openssh.com
|
||||
umac-128-etm@openssh.com
|
||||
.El
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
|
||||
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
|
||||
-hmac-sha1-etm@openssh.com,
|
||||
-umac-64@openssh.com,umac-128@openssh.com,
|
||||
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available MAC algorithms may also be obtained using
|
||||
.Qq ssh -Q mac .
|
||||
.It Cm Match
|
||||
@@ -1446,27 +1432,21 @@ or equivalent.)
|
||||
The default is
|
||||
.Cm yes .
|
||||
.It Cm PubkeyAcceptedKeyTypes
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+To see the current defaults and how to modify them, see manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the key types that will be accepted for public key authentication
|
||||
as a list of comma-separated patterns.
|
||||
Alternately if the specified value begins with a
|
||||
.Sq +
|
||||
-character, then the specified key types will be appended to the default set
|
||||
+character, then the specified key types will be appended to the built-in default set
|
||||
instead of replacing them.
|
||||
If the specified value begins with a
|
||||
.Sq -
|
||||
character, then the specified key types (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
-The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-rsa-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
|
||||
-.Ed
|
||||
+from the built-in default set instead of replacing them.
|
||||
.Pp
|
||||
The list of available key types may also be obtained using
|
||||
.Qq ssh -Q key .
|
||||
25
openssh-8.0p1-crypto-policy-doc.patch
Normal file
25
openssh-8.0p1-crypto-policy-doc.patch
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
diff --color -ru a/sshd.8 b/sshd.8
|
||||
--- a/sshd.8 2022-05-31 13:39:10.231843926 +0200
|
||||
+++ b/sshd.8 2022-05-31 14:34:01.460815420 +0200
|
||||
@@ -78,6 +78,7 @@
|
||||
.Xr sshd_config 5 ) ;
|
||||
command-line options override values specified in the
|
||||
configuration file.
|
||||
+This mechanism is used by systemd to apply system-wide crypto-policies to ssh server.
|
||||
.Nm
|
||||
rereads its configuration file when it receives a hangup signal,
|
||||
.Dv SIGHUP ,
|
||||
@@ -207,6 +208,13 @@
|
||||
rules may be applied by specifying the connection parameters using one or more
|
||||
.Fl C
|
||||
options.
|
||||
+The configuration does not contain the system-wide crypto-policy configuration.
|
||||
+To show the most accurate runtime configuration, use:
|
||||
+.Bd -literal -offset 3n
|
||||
+source /etc/crypto-policies/back-ends/opensshserver.config
|
||||
+source /etc/sysconfig/sshd
|
||||
+sshd -T $OPTIONS $CRYPTO_POLICY
|
||||
+.Ed
|
||||
.It Fl t
|
||||
Test mode.
|
||||
Only check the validity of the configuration file and sanity of the keys.
|
||||
127
openssh-8.0p1-cve-2020-14145.patch
Normal file
127
openssh-8.0p1-cve-2020-14145.patch
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
diff -up openssh-8.0p1/hostfile.c.cve-2020-14145 openssh-8.0p1/hostfile.c
|
||||
--- openssh-8.0p1/hostfile.c.cve-2020-14145 2019-04-18 00:52:57.000000000 +0200
|
||||
+++ openssh-8.0p1/hostfile.c 2021-05-17 16:53:38.694577251 +0200
|
||||
@@ -409,6 +409,18 @@ lookup_key_in_hostkeys_by_type(struct ho
|
||||
found) == HOST_FOUND);
|
||||
}
|
||||
|
||||
+int
|
||||
+lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker)
|
||||
+{
|
||||
+ u_int i;
|
||||
+
|
||||
+ for (i = 0; i < hostkeys->num_entries; i++) {
|
||||
+ if (hostkeys->entries[i].marker == (HostkeyMarker)want_marker)
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
write_host_entry(FILE *f, const char *host, const char *ip,
|
||||
const struct sshkey *key, int store_hash)
|
||||
diff -up openssh-8.0p1/hostfile.h.cve-2020-14145 openssh-8.0p1/hostfile.h
|
||||
--- openssh-8.0p1/hostfile.h.cve-2020-14145 2019-04-18 00:52:57.000000000 +0200
|
||||
+++ openssh-8.0p1/hostfile.h 2021-05-17 16:53:38.694577251 +0200
|
||||
@@ -39,6 +39,7 @@ HostStatus check_key_in_hostkeys(struct
|
||||
const struct hostkey_entry **);
|
||||
int lookup_key_in_hostkeys_by_type(struct hostkeys *, int,
|
||||
const struct hostkey_entry **);
|
||||
+int lookup_marker_in_hostkeys(struct hostkeys *, int);
|
||||
|
||||
int hostfile_read_key(char **, u_int *, struct sshkey *);
|
||||
int add_host_to_hostfile(const char *, const char *,
|
||||
diff -up openssh-8.0p1/sshconnect2.c.cve-2020-14145 openssh-8.0p1/sshconnect2.c
|
||||
--- openssh-8.0p1/sshconnect2.c.cve-2020-14145 2021-05-17 16:53:38.610576561 +0200
|
||||
+++ openssh-8.0p1/sshconnect2.c 2021-05-17 16:54:58.169230103 +0200
|
||||
@@ -98,12 +98,25 @@ verify_host_key_callback(struct sshkey *
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Returns the first item from a comma-separated algorithm list */
|
||||
+static char *
|
||||
+first_alg(const char *algs)
|
||||
+{
|
||||
+ char *ret, *cp;
|
||||
+
|
||||
+ ret = xstrdup(algs);
|
||||
+ if ((cp = strchr(ret, ',')) != NULL)
|
||||
+ *cp = '\0';
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
|
||||
{
|
||||
- char *oavail, *avail, *first, *last, *alg, *hostname, *ret;
|
||||
+ char *oavail = NULL, *avail = NULL, *first = NULL, *last = NULL;
|
||||
+ char *alg = NULL, *hostname = NULL, *ret = NULL, *best = NULL;
|
||||
size_t maxlen;
|
||||
- struct hostkeys *hostkeys;
|
||||
+ struct hostkeys *hostkeys = NULL;
|
||||
int ktype;
|
||||
u_int i;
|
||||
|
||||
@@ -115,6 +128,26 @@ order_hostkeyalgs(char *host, struct soc
|
||||
for (i = 0; i < options.num_system_hostfiles; i++)
|
||||
load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
|
||||
|
||||
+ /*
|
||||
+ * If a plain public key exists that matches the type of the best
|
||||
+ * preference HostkeyAlgorithms, then use the whole list as is.
|
||||
+ * Note that we ignore whether the best preference algorithm is a
|
||||
+ * certificate type, as sshconnect.c will downgrade certs to
|
||||
+ * plain keys if necessary.
|
||||
+ */
|
||||
+ best = first_alg(options.hostkeyalgorithms);
|
||||
+ if (lookup_key_in_hostkeys_by_type(hostkeys,
|
||||
+ sshkey_type_plain(sshkey_type_from_name(best)), NULL)) {
|
||||
+ debug3("%s: have matching best-preference key type %s, "
|
||||
+ "using HostkeyAlgorithms verbatim", __func__, best);
|
||||
+ ret = xstrdup(options.hostkeyalgorithms);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Otherwise, prefer the host key algorithms that match known keys
|
||||
+ * while keeping the ordering of HostkeyAlgorithms as much as possible.
|
||||
+ */
|
||||
oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
|
||||
maxlen = strlen(avail) + 1;
|
||||
first = xmalloc(maxlen);
|
||||
@@ -131,11 +164,23 @@ order_hostkeyalgs(char *host, struct soc
|
||||
while ((alg = strsep(&avail, ",")) && *alg != '\0') {
|
||||
if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
|
||||
fatal("%s: unknown alg %s", __func__, alg);
|
||||
+ /*
|
||||
+ * If we have a @cert-authority marker in known_hosts then
|
||||
+ * prefer all certificate algorithms.
|
||||
+ */
|
||||
+ if (sshkey_type_is_cert(ktype) &&
|
||||
+ lookup_marker_in_hostkeys(hostkeys, MRK_CA)) {
|
||||
+ ALG_APPEND(first, alg);
|
||||
+ continue;
|
||||
+ }
|
||||
+ /* If the key appears in known_hosts then prefer it */
|
||||
if (lookup_key_in_hostkeys_by_type(hostkeys,
|
||||
- sshkey_type_plain(ktype), NULL))
|
||||
+ sshkey_type_plain(ktype), NULL)) {
|
||||
ALG_APPEND(first, alg);
|
||||
- else
|
||||
- ALG_APPEND(last, alg);
|
||||
+ continue;
|
||||
+ }
|
||||
+ /* Otherwise, put it last */
|
||||
+ ALG_APPEND(last, alg);
|
||||
}
|
||||
#undef ALG_APPEND
|
||||
xasprintf(&ret, "%s%s%s", first,
|
||||
@@ -143,6 +188,8 @@ order_hostkeyalgs(char *host, struct soc
|
||||
if (*first != '\0')
|
||||
debug3("%s: prefer hostkeyalgs: %s", __func__, first);
|
||||
|
||||
+ out:
|
||||
+ free(best);
|
||||
free(first);
|
||||
free(last);
|
||||
free(hostname);
|
||||
302
openssh-8.0p1-entropy.patch
Normal file
302
openssh-8.0p1-entropy.patch
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
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)
|
||||
}
|
||||
#endif /* OPENSSL_PRNG_ONLY */
|
||||
|
||||
+#ifdef __linux__
|
||||
+ linux_seed();
|
||||
+#endif /* __linux__ */
|
||||
if (RAND_status() != 1)
|
||||
fatal("PRNG is not seeded");
|
||||
|
||||
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,6 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di
|
||||
port-solaris.o \
|
||||
port-net.o \
|
||||
port-uw.o \
|
||||
+ port-linux-prng.o \
|
||||
port-linux-sshd.o
|
||||
|
||||
.c.o:
|
||||
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,78 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2011 - 2020 Red Hat, Inc.
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Jan F. Chadima <jchadima@redhat.com>
|
||||
+ * Jakub Jelen <jjelen@redhat.com>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Linux-specific portability code - prng support
|
||||
+ */
|
||||
+
|
||||
+#include "includes.h"
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <string.h>
|
||||
+#include <openssl/rand.h>
|
||||
+#include <sys/random.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+
|
||||
+void
|
||||
+linux_seed(void)
|
||||
+{
|
||||
+ char *env = NULL;
|
||||
+ size_t randlen = 14, left;
|
||||
+ unsigned int flags = 0;
|
||||
+ unsigned char buf[256], *p;
|
||||
+
|
||||
+ env = getenv("SSH_USE_STRONG_RNG");
|
||||
+ if (env && strcmp(env, "0") != 0) {
|
||||
+ size_t ienv = atoi(env);
|
||||
+
|
||||
+ /* Max on buffer length */
|
||||
+ if (ienv > sizeof(buf))
|
||||
+ ienv = sizeof(buf);
|
||||
+ /* Minimum is always 14 B */
|
||||
+ if (ienv > randlen)
|
||||
+ randlen = ienv;
|
||||
+ flags = GRND_RANDOM;
|
||||
+ }
|
||||
+
|
||||
+ errno = 0;
|
||||
+ left = randlen;
|
||||
+ p = buf;
|
||||
+ do {
|
||||
+ ssize_t len = getrandom(p, left, flags);
|
||||
+ if (len == -1) {
|
||||
+ if (errno != EINTR) {
|
||||
+ if (flags) {
|
||||
+ /* With the variable present, this is fatal error */
|
||||
+ fatal("Failed to seed from getrandom: %s", strerror(errno));
|
||||
+ } else {
|
||||
+ /* Otherwise we log the issue drop out from here */
|
||||
+ debug("Failed to seed from getrandom: %s", strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ } else if (len > 0) {
|
||||
+ left -= len;
|
||||
+ p += len;
|
||||
+ }
|
||||
+ } while (left > 0);
|
||||
+
|
||||
+ RAND_seed(buf, randlen);
|
||||
+}
|
||||
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,22 @@ to make this work.)
|
||||
Identifies the path of a
|
||||
.Ux Ns -domain
|
||||
socket used to communicate with the agent.
|
||||
+.It Ev SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm getrandom(1)
|
||||
+without any specific flags.
|
||||
+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 getrandom(1)
|
||||
+with GRND_RANDOM flag specified.
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 14 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
diff --git a/ssh-agent.1 b/ssh-agent.1
|
||||
index 281ecbd..1a9a635 100644
|
||||
--- a/ssh-agent.1
|
||||
+++ b/ssh-agent.1
|
||||
@@ -201,6 +201,26 @@ 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
|
||||
+.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 getrandom(1)
|
||||
+without any specific flags.
|
||||
+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 getrandom(1)
|
||||
+with GRND_RANDOM flag specified.
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 14 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
diff --git a/ssh-keygen.1 b/ssh-keygen.1
|
||||
index 12e00d4..1b51a4a 100644
|
||||
--- a/ssh-keygen.1
|
||||
+++ b/ssh-keygen.1
|
||||
@@ -832,6 +832,26 @@ Contains Diffie-Hellman groups used for DH-GEX.
|
||||
The file format is described in
|
||||
.Xr moduli 5 .
|
||||
.El
|
||||
+.Sh ENVIRONMENT
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.Pp
|
||||
+.It Pa SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm getrandom(1)
|
||||
+without any specific flags.
|
||||
+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 getrandom(1)
|
||||
+with GRND_RANDOM flag specified.
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 14 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
diff --git a/ssh-keysign.8 b/ssh-keysign.8
|
||||
index 69d0829..02d79f8 100644
|
||||
--- a/ssh-keysign.8
|
||||
+++ b/ssh-keysign.8
|
||||
@@ -80,6 +80,26 @@ must be set-uid root if host-based authentication is used.
|
||||
If these files exist they are assumed to contain public certificate
|
||||
information corresponding with the private keys above.
|
||||
.El
|
||||
+.Sh ENVIRONMENT
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.Pp
|
||||
+.It Pa SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm getrandom(1)
|
||||
+without any specific flags.
|
||||
+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 getrandom(1)
|
||||
+with GRND_RANDOM flag specified.
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 14 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
diff --git a/ssh.1 b/ssh.1
|
||||
index 929904b..f65e42f 100644
|
||||
--- a/ssh.1
|
||||
+++ b/ssh.1
|
||||
@@ -1309,6 +1309,25 @@ For more information, see the
|
||||
.Cm PermitUserEnvironment
|
||||
option in
|
||||
.Xr sshd_config 5 .
|
||||
+.Bl -tag -width "SSH_ORIGINAL_COMMAND"
|
||||
+.Pp
|
||||
+.It Ev SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm getrandom(1)
|
||||
+without any specific flags.
|
||||
+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 getrandom(1)
|
||||
+with GRND_RANDOM flag specified.
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 14 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Pa ~/.rhosts
|
||||
diff --git a/sshd.8 b/sshd.8
|
||||
index c2c237f..058d37a 100644
|
||||
--- a/sshd.8
|
||||
+++ b/sshd.8
|
||||
@@ -951,6 +951,26 @@ 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 Ev SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm getrandom(1)
|
||||
+without any specific flags.
|
||||
+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 getrandom(1)
|
||||
+with GRND_RANDOM flag specified.
|
||||
+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
|
||||
|
||||
File diff suppressed because it is too large
Load diff
3971
openssh-8.0p1-gssapi-keyex.patch
Normal file
3971
openssh-8.0p1-gssapi-keyex.patch
Normal file
File diff suppressed because it is too large
Load diff
2335
openssh-8.0p1-hpn-14.19.patch
Normal file
2335
openssh-8.0p1-hpn-14.19.patch
Normal file
File diff suppressed because it is too large
Load diff
27
openssh-8.0p1-ipv6-process.patch
Normal file
27
openssh-8.0p1-ipv6-process.patch
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
diff --git a/sftp.c b/sftp.c
|
||||
index 04881c83..03c7a5c7 100644
|
||||
--- a/sftp.c
|
||||
+++ b/sftp.c
|
||||
@@ -2527,12 +2527,17 @@ main(int argc, char **argv)
|
||||
port = tmp;
|
||||
break;
|
||||
default:
|
||||
+ /* Try with user, host and path. */
|
||||
if (parse_user_host_path(*argv, &user, &host,
|
||||
- &file1) == -1) {
|
||||
- /* Treat as a plain hostname. */
|
||||
- host = xstrdup(*argv);
|
||||
- host = cleanhostname(host);
|
||||
- }
|
||||
+ &file1) == 0)
|
||||
+ break;
|
||||
+ /* Try with user and host. */
|
||||
+ if (parse_user_host_port(*argv, &user, &host, NULL)
|
||||
+ == 0)
|
||||
+ break;
|
||||
+ /* Treat as a plain hostname. */
|
||||
+ host = xstrdup(*argv);
|
||||
+ host = cleanhostname(host);
|
||||
break;
|
||||
}
|
||||
file2 = *(argv + 1);
|
||||
107
openssh-8.0p1-keygen-sha2.patch
Normal file
107
openssh-8.0p1-keygen-sha2.patch
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
From 4a41d245d6b13bd3882c8dc058dbd2e2b39a9f67 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Fri, 24 Jan 2020 00:27:04 +0000
|
||||
Subject: [PATCH] upstream: when signing a certificate with an RSA key, default
|
||||
to
|
||||
|
||||
a safe signature algorithm (rsa-sha-512) if not is explicitly specified by
|
||||
the user; ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: e05f638f0be6c0266e1d3d799716b461011e83a9
|
||||
---
|
||||
ssh-keygen.c | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ssh-keygen.c b/ssh-keygen.c
|
||||
index 564c3c481..f2192edb9 100644
|
||||
--- a/ssh-keygen.c
|
||||
+++ b/ssh-keygen.c
|
||||
@@ -1788,10 +1788,14 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
- if (key_type_name != NULL &&
|
||||
- sshkey_type_from_name(key_type_name) != ca->type) {
|
||||
- fatal("CA key type %s doesn't match specified %s",
|
||||
- sshkey_ssh_name(ca), key_type_name);
|
||||
+ if (key_type_name != NULL) {
|
||||
+ if (sshkey_type_from_name(key_type_name) != ca->type) {
|
||||
+ fatal("CA key type %s doesn't match specified %s",
|
||||
+ sshkey_ssh_name(ca), key_type_name);
|
||||
+ }
|
||||
+ } else if (ca->type == KEY_RSA) {
|
||||
+ /* Default to a good signature algorithm */
|
||||
+ key_type_name = "rsa-sha2-512";
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
|
||||
From 476e3551b2952ef73acc43d995e832539bf9bc4d Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Mon, 20 May 2019 00:20:35 +0000
|
||||
Subject: [PATCH] upstream: When signing certificates with an RSA key, default
|
||||
to
|
||||
|
||||
using the rsa-sha2-512 signature algorithm. Certificates signed by RSA keys
|
||||
will therefore be incompatible with OpenSSH < 7.2 unless the default is
|
||||
overridden.
|
||||
|
||||
Document the ability of the ssh-keygen -t flag to override the
|
||||
signature algorithm when signing certificates, and the new default.
|
||||
|
||||
ok deraadt@
|
||||
|
||||
OpenBSD-Commit-ID: 400c9c15013978204c2cb80f294b03ae4cfc8b95
|
||||
---
|
||||
ssh-keygen.1 | 13 +++++++++++--
|
||||
sshkey.c | 9 ++++++++-
|
||||
2 files changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ssh-keygen.1 b/ssh-keygen.1
|
||||
index f29774249..673bf6e2f 100644
|
||||
--- a/ssh-keygen.1
|
||||
+++ b/ssh-keygen.1
|
||||
@@ -35,7 +35,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
-.Dd $Mdocdate: March 5 2019 $
|
||||
+.Dd $Mdocdate: May 20 2019 $
|
||||
.Dt SSH-KEYGEN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -577,6 +577,15 @@ The possible values are
|
||||
.Dq ed25519 ,
|
||||
or
|
||||
.Dq rsa .
|
||||
+.Pp
|
||||
+This flag may also be used to specify the desired signature type when
|
||||
+signing certificates using a RSA CA key.
|
||||
+The available RSA signature variants are
|
||||
+.Dq ssh-rsa
|
||||
+(SHA1 signatures, not recommended),
|
||||
+.Dq rsa-sha2-256
|
||||
+.Dq rsa-sha2-512
|
||||
+(the default).
|
||||
.It Fl U
|
||||
When used in combination with
|
||||
.Fl s ,
|
||||
diff --git a/sshkey.c b/sshkey.c
|
||||
index 9849cb237..379a579cf 100644
|
||||
--- a/sshkey.c
|
||||
+++ b/sshkey.c
|
||||
@@ -2528,6 +2528,13 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
|
||||
strcmp(alg, k->cert->signature_type) != 0)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
|
||||
+ /*
|
||||
+ * If no signing algorithm or signature_type was specified and we're
|
||||
+ * using a RSA key, then default to a good signature algorithm.
|
||||
+ */
|
||||
+ if (alg == NULL && ca->type == KEY_RSA)
|
||||
+ alg = "rsa-sha2-512";
|
||||
+
|
||||
if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
|
||||
return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
|
||||
|
||||
|
||||
12
openssh-8.0p1-keygen-strip-doseol.patch
Normal file
12
openssh-8.0p1-keygen-strip-doseol.patch
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c
|
||||
--- openssh-8.0p1/ssh-keygen.c.strip-doseol 2021-03-18 17:41:34.472404994 +0100
|
||||
+++ openssh-8.0p1/ssh-keygen.c 2021-03-18 17:41:55.255538761 +0100
|
||||
@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw)
|
||||
while (getline(&line, &linesize, f) != -1) {
|
||||
lnum++;
|
||||
cp = line;
|
||||
- cp[strcspn(cp, "\n")] = '\0';
|
||||
+ cp[strcspn(cp, "\r\n")] = '\0';
|
||||
/* Trim leading space and comments */
|
||||
cp = line + strspn(line, " \t");
|
||||
if (*cp == '#' || *cp == '\0')
|
||||
33
openssh-8.0p1-keyscan-rsa-sha2.patch
Normal file
33
openssh-8.0p1-keyscan-rsa-sha2.patch
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
From 7250879c72d28275a53f2f220e49646c3e42ef18 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Fri, 12 Jul 2019 04:08:39 +0000
|
||||
Subject: [PATCH] upstream: include SHA2-variant RSA key algorithms in KEX
|
||||
proposal;
|
||||
|
||||
allows ssh-keyscan to harvest keys from servers that disable olde SHA1
|
||||
ssh-rsa. bz#3029 from Jakub Jelen
|
||||
|
||||
OpenBSD-Commit-ID: 9f95ebf76a150c2f727ca4780fb2599d50bbab7a
|
||||
---
|
||||
ssh-keyscan.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
|
||||
index d95ba1b37..d383b57b9 100644
|
||||
--- a/ssh-keyscan.c
|
||||
+++ b/ssh-keyscan.c
|
||||
@@ -233,7 +233,12 @@ keygrab_ssh2(con *c)
|
||||
break;
|
||||
case KT_RSA:
|
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
|
||||
- "ssh-rsa-cert-v01@openssh.com" : "ssh-rsa";
|
||||
+ "rsa-sha2-512-cert-v01@openssh.com,"
|
||||
+ "rsa-sha2-256-cert-v01@openssh.com,"
|
||||
+ "ssh-rsa-cert-v01@openssh.com" :
|
||||
+ "rsa-sha2-512,"
|
||||
+ "rsa-sha2-256,"
|
||||
+ "ssh-rsa";
|
||||
break;
|
||||
case KT_ED25519:
|
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
|
||||
|
||||
720
openssh-8.0p1-openssl-evp.patch
Normal file
720
openssh-8.0p1-openssl-evp.patch
Normal file
|
|
@ -0,0 +1,720 @@
|
|||
From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Tue, 14 May 2019 10:45:45 +0200
|
||||
Subject: [PATCH] Use high-level OpenSSL API for signatures
|
||||
|
||||
---
|
||||
digest-openssl.c | 16 ++++
|
||||
digest.h | 6 ++
|
||||
ssh-dss.c | 65 ++++++++++------
|
||||
ssh-ecdsa.c | 69 ++++++++++-------
|
||||
ssh-rsa.c | 193 +++++++++--------------------------------------
|
||||
sshkey.c | 77 +++++++++++++++++++
|
||||
sshkey.h | 4 +
|
||||
7 files changed, 221 insertions(+), 209 deletions(-)
|
||||
|
||||
diff --git a/digest-openssl.c b/digest-openssl.c
|
||||
index da7ed72bc..6a21d8adb 100644
|
||||
--- a/digest-openssl.c
|
||||
+++ b/digest-openssl.c
|
||||
@@ -63,6 +63,22 @@ const struct ssh_digest digests[] = {
|
||||
{ -1, NULL, 0, NULL },
|
||||
};
|
||||
|
||||
+const EVP_MD *
|
||||
+ssh_digest_to_md(int digest_type)
|
||||
+{
|
||||
+ switch (digest_type) {
|
||||
+ case SSH_DIGEST_SHA1:
|
||||
+ return EVP_sha1();
|
||||
+ case SSH_DIGEST_SHA256:
|
||||
+ return EVP_sha256();
|
||||
+ case SSH_DIGEST_SHA384:
|
||||
+ return EVP_sha384();
|
||||
+ case SSH_DIGEST_SHA512:
|
||||
+ return EVP_sha512();
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static const struct ssh_digest *
|
||||
ssh_digest_by_alg(int alg)
|
||||
{
|
||||
diff --git a/digest.h b/digest.h
|
||||
index 274574d0e..c7ceeb36f 100644
|
||||
--- a/digest.h
|
||||
+++ b/digest.h
|
||||
@@ -32,6 +32,12 @@
|
||||
struct sshbuf;
|
||||
struct ssh_digest_ctx;
|
||||
|
||||
+#ifdef WITH_OPENSSL
|
||||
+#include <openssl/evp.h>
|
||||
+/* Converts internal digest representation to the OpenSSL one */
|
||||
+const EVP_MD *ssh_digest_to_md(int digest_type);
|
||||
+#endif
|
||||
+
|
||||
/* Looks up a digest algorithm by name */
|
||||
int ssh_digest_alg_by_name(const char *name);
|
||||
|
||||
diff --git a/ssh-dss.c b/ssh-dss.c
|
||||
index a23c383dc..ea45e7275 100644
|
||||
--- a/ssh-dss.c
|
||||
+++ b/ssh-dss.c
|
||||
@@ -52,11 +52,15 @@ int
|
||||
ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
{
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
DSA_SIG *sig = NULL;
|
||||
const BIGNUM *sig_r, *sig_s;
|
||||
- u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
|
||||
- size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
|
||||
+ u_char sigblob[SIGBLOB_LEN];
|
||||
+ size_t rlen, slen;
|
||||
+ int len;
|
||||
struct sshbuf *b = NULL;
|
||||
+ u_char *sigb = NULL;
|
||||
+ const u_char *psig = NULL;
|
||||
int ret = SSH_ERR_INVALID_ARGUMENT;
|
||||
|
||||
if (lenp != NULL)
|
||||
@@ -67,17 +71,24 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
if (key == NULL || key->dsa == NULL ||
|
||||
sshkey_type_plain(key->type) != KEY_DSA)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
- if (dlen == 0)
|
||||
- return SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
|
||||
- digest, sizeof(digest))) != 0)
|
||||
+ if ((pkey = EVP_PKEY_new()) == NULL ||
|
||||
+ EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
|
||||
+ return SSH_ERR_ALLOC_FAIL;
|
||||
+ ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,
|
||||
+ data, datalen);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ if (ret < 0) {
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
- if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
|
||||
+ psig = sigb;
|
||||
+ if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
+ free(sigb);
|
||||
+ sigb = NULL;
|
||||
|
||||
DSA_SIG_get0(sig, &sig_r, &sig_s);
|
||||
rlen = BN_num_bytes(sig_r);
|
||||
@@ -110,7 +121,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
*lenp = len;
|
||||
ret = 0;
|
||||
out:
|
||||
- explicit_bzero(digest, sizeof(digest));
|
||||
+ free(sigb);
|
||||
DSA_SIG_free(sig);
|
||||
sshbuf_free(b);
|
||||
return ret;
|
||||
@@ -121,20 +132,20 @@ ssh_dss_verify(const struct sshkey *key,
|
||||
const u_char *signature, size_t signaturelen,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
{
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
DSA_SIG *sig = NULL;
|
||||
BIGNUM *sig_r = NULL, *sig_s = NULL;
|
||||
- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
|
||||
- size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
|
||||
+ u_char *sigblob = NULL;
|
||||
+ size_t len, slen;
|
||||
int ret = SSH_ERR_INTERNAL_ERROR;
|
||||
struct sshbuf *b = NULL;
|
||||
char *ktype = NULL;
|
||||
+ u_char *sigb = NULL, *psig = NULL;
|
||||
|
||||
if (key == NULL || key->dsa == NULL ||
|
||||
sshkey_type_plain(key->type) != KEY_DSA ||
|
||||
signature == NULL || signaturelen == 0)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
- if (dlen == 0)
|
||||
- return SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
/* fetch signature */
|
||||
if ((b = sshbuf_from(signature, signaturelen)) == NULL)
|
||||
@@ -176,25 +187,31 @@ ssh_dss_verify(const struct sshkey *key,
|
||||
}
|
||||
sig_r = sig_s = NULL; /* transferred */
|
||||
|
||||
- /* sha1 the data */
|
||||
- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
|
||||
- digest, sizeof(digest))) != 0)
|
||||
+ if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
-
|
||||
- switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
|
||||
- case 1:
|
||||
- ret = 0;
|
||||
- break;
|
||||
- case 0:
|
||||
- ret = SSH_ERR_SIGNATURE_INVALID;
|
||||
+ }
|
||||
+ if ((sigb = malloc(slen)) == NULL) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
- default:
|
||||
+ }
|
||||
+ psig = sigb;
|
||||
+ if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if ((pkey = EVP_PKEY_new()) == NULL ||
|
||||
+ EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,
|
||||
+ sigb, slen);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+
|
||||
out:
|
||||
- explicit_bzero(digest, sizeof(digest));
|
||||
+ free(sigb);
|
||||
DSA_SIG_free(sig);
|
||||
BN_clear_free(sig_r);
|
||||
BN_clear_free(sig_s);
|
||||
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
|
||||
index 599c7199d..b036796e8 100644
|
||||
--- a/ssh-ecdsa.c
|
||||
+++ b/ssh-ecdsa.c
|
||||
@@ -50,11 +50,13 @@ int
|
||||
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
{
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
+ unsigned char *sigb = NULL;
|
||||
+ const unsigned char *psig;
|
||||
const BIGNUM *sig_r, *sig_s;
|
||||
int hash_alg;
|
||||
- u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
- size_t len, dlen;
|
||||
+ int len;
|
||||
struct sshbuf *b = NULL, *bb = NULL;
|
||||
int ret = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
@@ -67,18 +69,24 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
sshkey_type_plain(key->type) != KEY_ECDSA)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
|
||||
- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
|
||||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
|
||||
+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
|
||||
- digest, sizeof(digest))) != 0)
|
||||
+
|
||||
+ if ((pkey = EVP_PKEY_new()) == NULL ||
|
||||
+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
|
||||
+ return SSH_ERR_ALLOC_FAIL;
|
||||
+ ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,
|
||||
+ datalen);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ if (ret < 0) {
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
- if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
|
||||
+ psig = sigb;
|
||||
+ if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
-
|
||||
if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
|
||||
ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
@@ -102,7 +110,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
*lenp = len;
|
||||
ret = 0;
|
||||
out:
|
||||
- explicit_bzero(digest, sizeof(digest));
|
||||
+ free(sigb);
|
||||
sshbuf_free(b);
|
||||
sshbuf_free(bb);
|
||||
ECDSA_SIG_free(sig);
|
||||
@@ -115,22 +123,21 @@ ssh_ecdsa_verify(const struct sshkey *key,
|
||||
const u_char *signature, size_t signaturelen,
|
||||
const u_char *data, size_t datalen, u_int compat)
|
||||
{
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
BIGNUM *sig_r = NULL, *sig_s = NULL;
|
||||
- int hash_alg;
|
||||
- u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
- size_t dlen;
|
||||
+ int hash_alg, len;
|
||||
int ret = SSH_ERR_INTERNAL_ERROR;
|
||||
struct sshbuf *b = NULL, *sigbuf = NULL;
|
||||
char *ktype = NULL;
|
||||
+ unsigned char *sigb = NULL, *psig = NULL;
|
||||
|
||||
if (key == NULL || key->ecdsa == NULL ||
|
||||
sshkey_type_plain(key->type) != KEY_ECDSA ||
|
||||
signature == NULL || signaturelen == 0)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
|
||||
- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
|
||||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
|
||||
+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
/* fetch signature */
|
||||
@@ -166,28 +173,36 @@ ssh_ecdsa_verify(const struct sshkey *key,
|
||||
}
|
||||
sig_r = sig_s = NULL; /* transferred */
|
||||
|
||||
- if (sshbuf_len(sigbuf) != 0) {
|
||||
- ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
|
||||
+ /* Figure out the length */
|
||||
+ if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if ((sigb = malloc(len)) == NULL) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
|
||||
- digest, sizeof(digest))) != 0)
|
||||
+ psig = sigb;
|
||||
+ if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
- switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
|
||||
- case 1:
|
||||
- ret = 0;
|
||||
- break;
|
||||
- case 0:
|
||||
- ret = SSH_ERR_SIGNATURE_INVALID;
|
||||
+ if (sshbuf_len(sigbuf) != 0) {
|
||||
+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
|
||||
goto out;
|
||||
- default:
|
||||
- ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if ((pkey = EVP_PKEY_new()) == NULL ||
|
||||
+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
|
||||
out:
|
||||
- explicit_bzero(digest, sizeof(digest));
|
||||
+ free(sigb);
|
||||
sshbuf_free(sigbuf);
|
||||
sshbuf_free(b);
|
||||
ECDSA_SIG_free(sig);
|
||||
diff --git a/ssh-rsa.c b/ssh-rsa.c
|
||||
index 9b14f9a9a..8ef3a6aca 100644
|
||||
--- a/ssh-rsa.c
|
||||
+++ b/ssh-rsa.c
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
-static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
|
||||
+static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *);
|
||||
|
||||
static const char *
|
||||
rsa_hash_alg_ident(int hash_alg)
|
||||
@@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static int
|
||||
-rsa_hash_alg_nid(int type)
|
||||
-{
|
||||
- switch (type) {
|
||||
- case SSH_DIGEST_SHA1:
|
||||
- return NID_sha1;
|
||||
- case SSH_DIGEST_SHA256:
|
||||
- return NID_sha256;
|
||||
- case SSH_DIGEST_SHA512:
|
||||
- return NID_sha512;
|
||||
- default:
|
||||
- return -1;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
int
|
||||
ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
|
||||
{
|
||||
@@ -164,11 +149,10 @@ int
|
||||
ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, const char *alg_ident)
|
||||
{
|
||||
- const BIGNUM *rsa_n;
|
||||
- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
|
||||
- size_t slen = 0;
|
||||
- u_int dlen, len;
|
||||
- int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
+ u_char *sig = NULL;
|
||||
+ int len, slen = 0;
|
||||
+ int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
|
||||
struct sshbuf *b = NULL;
|
||||
|
||||
if (lenp != NULL)
|
||||
@@ -180,33 +164,24 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
hash_alg = SSH_DIGEST_SHA1;
|
||||
else
|
||||
hash_alg = rsa_hash_id_from_keyname(alg_ident);
|
||||
+
|
||||
if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
|
||||
sshkey_type_plain(key->type) != KEY_RSA)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
|
||||
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
|
||||
- return SSH_ERR_KEY_LENGTH;
|
||||
slen = RSA_size(key->rsa);
|
||||
- if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
|
||||
- return SSH_ERR_INVALID_ARGUMENT;
|
||||
-
|
||||
- /* hash the data */
|
||||
- nid = rsa_hash_alg_nid(hash_alg);
|
||||
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
|
||||
- return SSH_ERR_INTERNAL_ERROR;
|
||||
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
|
||||
- digest, sizeof(digest))) != 0)
|
||||
- goto out;
|
||||
+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
|
||||
+ return SSH_ERR_KEY_LENGTH;
|
||||
|
||||
- if ((sig = malloc(slen)) == NULL) {
|
||||
- ret = SSH_ERR_ALLOC_FAIL;
|
||||
+ if ((pkey = EVP_PKEY_new()) == NULL ||
|
||||
+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
|
||||
+ return SSH_ERR_ALLOC_FAIL;
|
||||
+ ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
|
||||
+ datalen);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
|
||||
- ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
- goto out;
|
||||
- }
|
||||
if (len < slen) {
|
||||
size_t diff = slen - len;
|
||||
memmove(sig + diff, sig, len);
|
||||
@@ -215,6 +190,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
ret = SSH_ERR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
+
|
||||
/* encode signature */
|
||||
if ((b = sshbuf_new()) == NULL) {
|
||||
ret = SSH_ERR_ALLOC_FAIL;
|
||||
@@ -235,7 +211,6 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||
*lenp = len;
|
||||
ret = 0;
|
||||
out:
|
||||
- explicit_bzero(digest, sizeof(digest));
|
||||
freezero(sig, slen);
|
||||
sshbuf_free(b);
|
||||
return ret;
|
||||
@@ -246,10 +221,10 @@ ssh_rsa_verify(const struct sshkey *key,
|
||||
const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
|
||||
const char *alg)
|
||||
{
|
||||
- const BIGNUM *rsa_n;
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
char *sigtype = NULL;
|
||||
int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
|
||||
- size_t len = 0, diff, modlen, dlen;
|
||||
+ size_t len = 0, diff, modlen;
|
||||
struct sshbuf *b = NULL;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
|
||||
|
||||
@@ -257,8 +232,7 @@ ssh_rsa_verify(const struct sshkey *key,
|
||||
sshkey_type_plain(key->type) != KEY_RSA ||
|
||||
sig == NULL || siglen == 0)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
|
||||
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
|
||||
+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
|
||||
return SSH_ERR_KEY_LENGTH;
|
||||
|
||||
if ((b = sshbuf_from(sig, siglen)) == NULL)
|
||||
@@ -310,16 +284,15 @@ ssh_rsa_verify(const struct sshkey *key,
|
||||
explicit_bzero(sigblob, diff);
|
||||
len = modlen;
|
||||
}
|
||||
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
|
||||
- ret = SSH_ERR_INTERNAL_ERROR;
|
||||
+
|
||||
+ if ((pkey = EVP_PKEY_new()) == NULL ||
|
||||
+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
|
||||
- digest, sizeof(digest))) != 0)
|
||||
- goto out;
|
||||
+ ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
|
||||
- ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
|
||||
- key->rsa);
|
||||
out:
|
||||
freezero(sigblob, len);
|
||||
free(sigtype);
|
||||
@@ -328,122 +301,26 @@ ssh_rsa_verify(const struct sshkey *key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * See:
|
||||
- * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
|
||||
- * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
|
||||
- */
|
||||
-
|
||||
-/*
|
||||
- * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
|
||||
- * oiw(14) secsig(3) algorithms(2) 26 }
|
||||
- */
|
||||
-static const u_char id_sha1[] = {
|
||||
- 0x30, 0x21, /* type Sequence, length 0x21 (33) */
|
||||
- 0x30, 0x09, /* type Sequence, length 0x09 */
|
||||
- 0x06, 0x05, /* type OID, length 0x05 */
|
||||
- 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
|
||||
- 0x05, 0x00, /* NULL */
|
||||
- 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
|
||||
-};
|
||||
-
|
||||
-/*
|
||||
- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
|
||||
- * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
|
||||
- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
|
||||
- * id-sha256(1) }
|
||||
- */
|
||||
-static const u_char id_sha256[] = {
|
||||
- 0x30, 0x31, /* type Sequence, length 0x31 (49) */
|
||||
- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
|
||||
- 0x06, 0x09, /* type OID, length 0x09 */
|
||||
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
|
||||
- 0x05, 0x00, /* NULL */
|
||||
- 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
|
||||
-};
|
||||
-
|
||||
-/*
|
||||
- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
|
||||
- * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
|
||||
- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
|
||||
- * id-sha256(3) }
|
||||
- */
|
||||
-static const u_char id_sha512[] = {
|
||||
- 0x30, 0x51, /* type Sequence, length 0x51 (81) */
|
||||
- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
|
||||
- 0x06, 0x09, /* type OID, length 0x09 */
|
||||
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
|
||||
- 0x05, 0x00, /* NULL */
|
||||
- 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
|
||||
-};
|
||||
-
|
||||
static int
|
||||
-rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
|
||||
+openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen,
|
||||
+ u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)
|
||||
{
|
||||
- switch (hash_alg) {
|
||||
- case SSH_DIGEST_SHA1:
|
||||
- *oidp = id_sha1;
|
||||
- *oidlenp = sizeof(id_sha1);
|
||||
- break;
|
||||
- case SSH_DIGEST_SHA256:
|
||||
- *oidp = id_sha256;
|
||||
- *oidlenp = sizeof(id_sha256);
|
||||
- break;
|
||||
- case SSH_DIGEST_SHA512:
|
||||
- *oidp = id_sha512;
|
||||
- *oidlenp = sizeof(id_sha512);
|
||||
- break;
|
||||
- default:
|
||||
- return SSH_ERR_INVALID_ARGUMENT;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
+ size_t rsasize = 0;
|
||||
+ const RSA *rsa;
|
||||
+ int ret;
|
||||
|
||||
-static int
|
||||
-openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
|
||||
- u_char *sigbuf, size_t siglen, RSA *rsa)
|
||||
-{
|
||||
- size_t rsasize = 0, oidlen = 0, hlen = 0;
|
||||
- int ret, len, oidmatch, hashmatch;
|
||||
- const u_char *oid = NULL;
|
||||
- u_char *decrypted = NULL;
|
||||
-
|
||||
- if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
|
||||
- return ret;
|
||||
- ret = SSH_ERR_INTERNAL_ERROR;
|
||||
- hlen = ssh_digest_bytes(hash_alg);
|
||||
- if (hashlen != hlen) {
|
||||
- ret = SSH_ERR_INVALID_ARGUMENT;
|
||||
- goto done;
|
||||
- }
|
||||
+ rsa = EVP_PKEY_get0_RSA(pkey);
|
||||
rsasize = RSA_size(rsa);
|
||||
if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
|
||||
siglen == 0 || siglen > rsasize) {
|
||||
ret = SSH_ERR_INVALID_ARGUMENT;
|
||||
goto done;
|
||||
}
|
||||
- if ((decrypted = malloc(rsasize)) == NULL) {
|
||||
- ret = SSH_ERR_ALLOC_FAIL;
|
||||
- goto done;
|
||||
- }
|
||||
- if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
|
||||
- RSA_PKCS1_PADDING)) < 0) {
|
||||
- ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
- goto done;
|
||||
- }
|
||||
- if (len < 0 || (size_t)len != hlen + oidlen) {
|
||||
- ret = SSH_ERR_INVALID_FORMAT;
|
||||
- goto done;
|
||||
- }
|
||||
- oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
|
||||
- hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
|
||||
- if (!oidmatch || !hashmatch) {
|
||||
- ret = SSH_ERR_SIGNATURE_INVALID;
|
||||
- goto done;
|
||||
- }
|
||||
- ret = 0;
|
||||
+
|
||||
+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen,
|
||||
+ sigbuf, siglen);
|
||||
+
|
||||
done:
|
||||
- freezero(decrypted, rsasize);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WITH_OPENSSL */
|
||||
diff --git a/sshkey.c b/sshkey.c
|
||||
index ad1957762..b95ed0b10 100644
|
||||
--- a/sshkey.c
|
||||
+++ b/sshkey.c
|
||||
@@ -358,6 +358,83 @@ sshkey_type_plain(int type)
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
+int
|
||||
+sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
|
||||
+ int *lenp, const u_char *data, size_t datalen)
|
||||
+{
|
||||
+ EVP_MD_CTX *ctx = NULL;
|
||||
+ u_char *sig = NULL;
|
||||
+ int ret, slen, len;
|
||||
+
|
||||
+ if (sigp == NULL || lenp == NULL) {
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ slen = EVP_PKEY_size(pkey);
|
||||
+ if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+
|
||||
+ len = slen;
|
||||
+ if ((sig = malloc(slen)) == NULL) {
|
||||
+ return SSH_ERR_ALLOC_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
|
||||
+ EVP_SignUpdate(ctx, data, datalen) <= 0 ||
|
||||
+ EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ *sigp = sig;
|
||||
+ *lenp = len;
|
||||
+ /* Now owned by the caller */
|
||||
+ sig = NULL;
|
||||
+ ret = 0;
|
||||
+
|
||||
+error:
|
||||
+ EVP_MD_CTX_free(ctx);
|
||||
+ free(sig);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data,
|
||||
+ size_t datalen, u_char *sigbuf, int siglen)
|
||||
+{
|
||||
+ EVP_MD_CTX *ctx = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
|
||||
+ return SSH_ERR_ALLOC_FAIL;
|
||||
+ }
|
||||
+ if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
|
||||
+ EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
|
||||
+ switch (ret) {
|
||||
+ case 1:
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ case 0:
|
||||
+ ret = SSH_ERR_SIGNATURE_INVALID;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ EVP_MD_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/* XXX: these are really begging for a table-driven approach */
|
||||
int
|
||||
sshkey_curve_name_to_nid(const char *name)
|
||||
diff --git a/sshkey.h b/sshkey.h
|
||||
index a91e60436..270901a87 100644
|
||||
--- a/sshkey.h
|
||||
+++ b/sshkey.h
|
||||
@@ -179,6 +179,10 @@ const char *sshkey_ssh_name(const struct sshkey *);
|
||||
const char *sshkey_ssh_name_plain(const struct sshkey *);
|
||||
int sshkey_names_valid2(const char *, int);
|
||||
char *sshkey_alg_list(int, int, int, char);
|
||||
+int sshkey_calculate_signature(EVP_PKEY*, int, u_char **,
|
||||
+ int *, const u_char *, size_t);
|
||||
+int sshkey_verify_signature(EVP_PKEY *, int, const u_char *,
|
||||
+ size_t, u_char *, int);
|
||||
|
||||
int sshkey_from_blob(const u_char *, size_t, struct sshkey **);
|
||||
int sshkey_fromb(struct sshbuf *, struct sshkey **);
|
||||
|
||||
137
openssh-8.0p1-openssl-kdf.patch
Normal file
137
openssh-8.0p1-openssl-kdf.patch
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a
|
||||
Author: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Tue Apr 16 15:35:18 2019 +0200
|
||||
|
||||
Use the new OpenSSL KDF
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 2a455e4e..e01c3d43 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2712,6 +2712,7 @@ if test "x$openssl" = "xyes" ; then
|
||||
HMAC_CTX_init \
|
||||
RSA_generate_key_ex \
|
||||
RSA_get_default_method \
|
||||
+ EVP_KDF_CTX_new_id \
|
||||
])
|
||||
|
||||
# OpenSSL_add_all_algorithms may be a macro.
|
||||
diff --git a/kex.c b/kex.c
|
||||
index b6f041f4..1fbce2bb 100644
|
||||
--- a/kex.c
|
||||
+++ b/kex.c
|
||||
@@ -38,6 +38,9 @@
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/dh.h>
|
||||
+# ifdef HAVE_EVP_KDF_CTX_NEW_ID
|
||||
+# include <openssl/kdf.h>
|
||||
+# endif
|
||||
#endif
|
||||
|
||||
#include "ssh.h"
|
||||
@@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh)
|
||||
return r;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_EVP_KDF_CTX_NEW_ID
|
||||
+static const EVP_MD *
|
||||
+digest_to_md(int digest_type)
|
||||
+{
|
||||
+ switch (digest_type) {
|
||||
+ case SSH_DIGEST_SHA1:
|
||||
+ return EVP_sha1();
|
||||
+ case SSH_DIGEST_SHA256:
|
||||
+ return EVP_sha256();
|
||||
+ case SSH_DIGEST_SHA384:
|
||||
+ return EVP_sha384();
|
||||
+ case SSH_DIGEST_SHA512:
|
||||
+ return EVP_sha512();
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
+ const struct sshbuf *shared_secret, u_char **keyp)
|
||||
+{
|
||||
+ struct kex *kex = ssh->kex;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ u_char *key = NULL;
|
||||
+ int r, key_len;
|
||||
+
|
||||
+ if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0)
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ key_len = ROUNDUP(need, key_len);
|
||||
+ if ((key = calloc(1, key_len)) == NULL) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
|
||||
+ if (!ctx) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg));
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY,
|
||||
+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret));
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen);
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id);
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
|
||||
+ kex->session_id, kex->session_id_len);
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ r = EVP_KDF_derive(ctx, key, key_len);
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+#ifdef DEBUG_KEX
|
||||
+ fprintf(stderr, "key '%c'== ", id);
|
||||
+ dump_digest("key", key, key_len);
|
||||
+#endif
|
||||
+ *keyp = key;
|
||||
+ key = NULL;
|
||||
+ r = 0;
|
||||
+
|
||||
+out:
|
||||
+ free (key);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ if (r < 0) {
|
||||
+ return r;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
static int
|
||||
derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
const struct sshbuf *shared_secret, u_char **keyp)
|
||||
@@ -1004,6 +1096,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
ssh_digest_free(hashctx);
|
||||
return r;
|
||||
}
|
||||
+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
|
||||
|
||||
#define NKEYS 6
|
||||
int
|
||||
|
||||
324
openssh-8.0p1-openssl-pem.patch
Normal file
324
openssh-8.0p1-openssl-pem.patch
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
From eb0d8e708a1f958aecd2d6e2ff2450af488d4c2a Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Mon, 15 Jul 2019 13:16:29 +0000
|
||||
Subject: [PATCH] upstream: support PKCS8 as an optional format for storage of
|
||||
|
||||
private keys, enabled via "ssh-keygen -m PKCS8" on operations that save
|
||||
private keys to disk.
|
||||
|
||||
The OpenSSH native key format remains the default, but PKCS8 is a
|
||||
superior format to PEM if interoperability with non-OpenSSH software
|
||||
is required, as it may use a less terrible KDF (IIRC PEM uses a single
|
||||
round of MD5 as a KDF).
|
||||
|
||||
adapted from patch by Jakub Jelen via bz3013; ok markus
|
||||
|
||||
OpenBSD-Commit-ID: 027824e3bc0b1c243dc5188504526d73a55accb1
|
||||
---
|
||||
authfile.c | 6 ++--
|
||||
ssh-keygen.1 | 9 +++---
|
||||
ssh-keygen.c | 25 +++++++++--------
|
||||
sshkey.c | 78 +++++++++++++++++++++++++++++++++++++---------------
|
||||
sshkey.h | 11 ++++++--
|
||||
5 files changed, 87 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/authfile.c b/authfile.c
|
||||
index 2166c1689..851c1a8a1 100644
|
||||
--- a/authfile.c
|
||||
+++ b/authfile.c
|
||||
@@ -74,7 +74,7 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
|
||||
int
|
||||
sshkey_save_private(struct sshkey *key, const char *filename,
|
||||
const char *passphrase, const char *comment,
|
||||
- int force_new_format, const char *new_format_cipher, int new_format_rounds)
|
||||
+ int format, const char *openssh_format_cipher, int openssh_format_rounds)
|
||||
{
|
||||
struct sshbuf *keyblob = NULL;
|
||||
int r;
|
||||
@@ -82,7 +82,7 @@ sshkey_save_private(struct sshkey *key, const char *filename,
|
||||
if ((keyblob = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
|
||||
- force_new_format, new_format_cipher, new_format_rounds)) != 0)
|
||||
+ format, openssh_format_cipher, openssh_format_rounds)) != 0)
|
||||
goto out;
|
||||
if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
|
||||
goto out;
|
||||
diff --git a/ssh-keygen.1 b/ssh-keygen.1
|
||||
index f42127c60..8184a1797 100644
|
||||
--- a/ssh-keygen.1
|
||||
+++ b/ssh-keygen.1
|
||||
@@ -419,11 +419,12 @@ The supported key formats are:
|
||||
.Dq RFC4716
|
||||
(RFC 4716/SSH2 public or private key),
|
||||
.Dq PKCS8
|
||||
-(PEM PKCS8 public key)
|
||||
+(PKCS8 public or private key)
|
||||
or
|
||||
.Dq PEM
|
||||
(PEM public key).
|
||||
-The default conversion format is
|
||||
+By default OpenSSH will write newly-generated private keys in its own
|
||||
+format, but when converting public keys for export the default format is
|
||||
.Dq RFC4716 .
|
||||
Setting a format of
|
||||
.Dq PEM
|
||||
diff --git a/ssh-keygen.c b/ssh-keygen.c
|
||||
index b019a02ff..5dcad1f61 100644
|
||||
--- a/ssh-keygen.c
|
||||
+++ b/ssh-keygen.c
|
||||
@@ -147,11 +147,11 @@ static char *key_type_name = NULL;
|
||||
/* Load key from this PKCS#11 provider */
|
||||
static char *pkcs11provider = NULL;
|
||||
|
||||
-/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */
|
||||
-static int use_new_format = 1;
|
||||
+/* Format for writing private keys */
|
||||
+static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
|
||||
|
||||
/* Cipher for new-format private keys */
|
||||
-static char *new_format_cipher = NULL;
|
||||
+static char *openssh_format_cipher = NULL;
|
||||
|
||||
/*
|
||||
* Number of KDF rounds to derive new format keys /
|
||||
@@ -1048,7 +1048,8 @@ do_gen_all_hostkeys(struct passwd *pw)
|
||||
snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
|
||||
hostname);
|
||||
if ((r = sshkey_save_private(private, prv_tmp, "",
|
||||
- comment, use_new_format, new_format_cipher, rounds)) != 0) {
|
||||
+ comment, private_key_format, openssh_format_cipher,
|
||||
+ rounds)) != 0) {
|
||||
error("Saving key \"%s\" failed: %s",
|
||||
prv_tmp, ssh_err(r));
|
||||
goto failnext;
|
||||
@@ -1391,7 +1392,7 @@ do_change_passphrase(struct passwd *pw)
|
||||
|
||||
/* Save the file using the new passphrase. */
|
||||
if ((r = sshkey_save_private(private, identity_file, passphrase1,
|
||||
- comment, use_new_format, new_format_cipher, rounds)) != 0) {
|
||||
+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
|
||||
error("Saving key \"%s\" failed: %s.",
|
||||
identity_file, ssh_err(r));
|
||||
explicit_bzero(passphrase1, strlen(passphrase1));
|
||||
@@ -1480,7 +1481,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
|
||||
}
|
||||
|
||||
if (private->type != KEY_ED25519 && private->type != KEY_XMSS &&
|
||||
- !use_new_format) {
|
||||
+ private_key_format != SSHKEY_PRIVATE_OPENSSH) {
|
||||
error("Comments are only supported for keys stored in "
|
||||
"the new format (-o).");
|
||||
explicit_bzero(passphrase, strlen(passphrase));
|
||||
@@ -1514,7 +1515,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
|
||||
|
||||
/* Save the file using the new passphrase. */
|
||||
if ((r = sshkey_save_private(private, identity_file, passphrase,
|
||||
- new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
|
||||
+ new_comment, private_key_format, openssh_format_cipher,
|
||||
+ rounds)) != 0) {
|
||||
error("Saving key \"%s\" failed: %s",
|
||||
identity_file, ssh_err(r));
|
||||
explicit_bzero(passphrase, strlen(passphrase));
|
||||
@@ -2525,11 +2527,12 @@ main(int argc, char **argv)
|
||||
}
|
||||
if (strcasecmp(optarg, "PKCS8") == 0) {
|
||||
convert_format = FMT_PKCS8;
|
||||
+ private_key_format = SSHKEY_PRIVATE_PKCS8;
|
||||
break;
|
||||
}
|
||||
if (strcasecmp(optarg, "PEM") == 0) {
|
||||
convert_format = FMT_PEM;
|
||||
- use_new_format = 0;
|
||||
+ private_key_format = SSHKEY_PRIVATE_PEM;
|
||||
break;
|
||||
}
|
||||
fatal("Unsupported conversion format \"%s\"", optarg);
|
||||
@@ -2567,7 +2570,7 @@ main(int argc, char **argv)
|
||||
add_cert_option(optarg);
|
||||
break;
|
||||
case 'Z':
|
||||
- new_format_cipher = optarg;
|
||||
+ openssh_format_cipher = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
identity_comment = optarg;
|
||||
@@ -2912,7 +2915,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* Save the key with the given passphrase and comment. */
|
||||
if ((r = sshkey_save_private(private, identity_file, passphrase1,
|
||||
- comment, use_new_format, new_format_cipher, rounds)) != 0) {
|
||||
+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
|
||||
error("Saving key \"%s\" failed: %s",
|
||||
identity_file, ssh_err(r));
|
||||
explicit_bzero(passphrase1, strlen(passphrase1));
|
||||
diff --git a/sshkey.c b/sshkey.c
|
||||
index 6b5ff0485..a0cea9257 100644
|
||||
--- a/sshkey.c
|
||||
+++ b/sshkey.c
|
||||
@@ -3975,10 +3975,10 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
|
||||
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
-/* convert SSH v2 key in OpenSSL PEM format */
|
||||
+/* convert SSH v2 key to PEM or PKCS#8 format */
|
||||
static int
|
||||
-sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
|
||||
- const char *_passphrase, const char *comment)
|
||||
+sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *blob,
|
||||
+ int format, const char *_passphrase, const char *comment)
|
||||
{
|
||||
int success, r;
|
||||
int blen, len = strlen(_passphrase);
|
||||
@@ -3988,26 +3988,46 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
|
||||
const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
|
||||
char *bptr;
|
||||
BIO *bio = NULL;
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
|
||||
if (len > 0 && len <= 4)
|
||||
return SSH_ERR_PASSPHRASE_TOO_SHORT;
|
||||
- if ((bio = BIO_new(BIO_s_mem())) == NULL)
|
||||
- return SSH_ERR_ALLOC_FAIL;
|
||||
+ if ((bio = BIO_new(BIO_s_mem())) == NULL) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
switch (key->type) {
|
||||
case KEY_DSA:
|
||||
- success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
|
||||
- cipher, passphrase, len, NULL, NULL);
|
||||
+ if (format == SSHKEY_PRIVATE_PEM) {
|
||||
+ success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
|
||||
+ cipher, passphrase, len, NULL, NULL);
|
||||
+ } else {
|
||||
+ success = EVP_PKEY_set1_DSA(pkey, key->dsa);
|
||||
+ }
|
||||
break;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
case KEY_ECDSA:
|
||||
- success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
|
||||
- cipher, passphrase, len, NULL, NULL);
|
||||
+ if (format == SSHKEY_PRIVATE_PEM) {
|
||||
+ success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
|
||||
+ cipher, passphrase, len, NULL, NULL);
|
||||
+ } else {
|
||||
+ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
|
||||
+ }
|
||||
break;
|
||||
#endif
|
||||
case KEY_RSA:
|
||||
- success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
|
||||
- cipher, passphrase, len, NULL, NULL);
|
||||
+ if (format == SSHKEY_PRIVATE_PEM) {
|
||||
+ success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
|
||||
+ cipher, passphrase, len, NULL, NULL);
|
||||
+ } else {
|
||||
+ success = EVP_PKEY_set1_RSA(pkey, key->rsa);
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
success = 0;
|
||||
@@ -4023,6 +4040,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
+ if (format == SSHKEY_PRIVATE_PKCS8) {
|
||||
+ if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
|
||||
+ passphrase, len, NULL, NULL)) == 0) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
|
||||
r = SSH_ERR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
@@ -4035,6 +4059,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
|
||||
goto out;
|
||||
r = 0;
|
||||
out:
|
||||
+ EVP_PKEY_free(pkey);
|
||||
BIO_free(bio);
|
||||
return r;
|
||||
}
|
||||
@@ -4046,29 +4071,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
|
||||
int
|
||||
sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
|
||||
const char *passphrase, const char *comment,
|
||||
- int force_new_format, const char *new_format_cipher, int new_format_rounds)
|
||||
+ int format, const char *openssh_format_cipher, int openssh_format_rounds)
|
||||
{
|
||||
switch (key->type) {
|
||||
#ifdef WITH_OPENSSL
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
case KEY_RSA:
|
||||
- if (force_new_format) {
|
||||
- return sshkey_private_to_blob2(key, blob, passphrase,
|
||||
- comment, new_format_cipher, new_format_rounds);
|
||||
- }
|
||||
- return sshkey_private_pem_to_blob(key, blob,
|
||||
- passphrase, comment);
|
||||
+ break; /* see below */
|
||||
#endif /* WITH_OPENSSL */
|
||||
case KEY_ED25519:
|
||||
#ifdef WITH_XMSS
|
||||
case KEY_XMSS:
|
||||
#endif /* WITH_XMSS */
|
||||
return sshkey_private_to_blob2(key, blob, passphrase,
|
||||
- comment, new_format_cipher, new_format_rounds);
|
||||
+ comment, openssh_format_cipher, openssh_format_rounds);
|
||||
default:
|
||||
return SSH_ERR_KEY_TYPE_UNKNOWN;
|
||||
}
|
||||
+
|
||||
+#ifdef WITH_OPENSSL
|
||||
+ switch (format) {
|
||||
+ case SSHKEY_PRIVATE_OPENSSH:
|
||||
+ return sshkey_private_to_blob2(key, blob, passphrase,
|
||||
+ comment, openssh_format_cipher, openssh_format_rounds);
|
||||
+ case SSHKEY_PRIVATE_PEM:
|
||||
+ case SSHKEY_PRIVATE_PKCS8:
|
||||
+ return sshkey_private_to_blob_pem_pkcs8(key, blob,
|
||||
+ format, passphrase, comment);
|
||||
+ default:
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+#endif /* WITH_OPENSSL */
|
||||
}
|
||||
|
||||
|
||||
diff --git a/sshkey.h b/sshkey.h
|
||||
index 41d159a1b..d30a69cc9 100644
|
||||
--- a/sshkey.h
|
||||
+++ b/sshkey.h
|
||||
@@ -88,6 +88,13 @@ enum sshkey_serialize_rep {
|
||||
SSHKEY_SERIALIZE_INFO = 254,
|
||||
};
|
||||
|
||||
+/* Private key disk formats */
|
||||
+enum sshkey_private_format {
|
||||
+ SSHKEY_PRIVATE_OPENSSH = 0,
|
||||
+ SSHKEY_PRIVATE_PEM = 1,
|
||||
+ SSHKEY_PRIVATE_PKCS8 = 2,
|
||||
+};
|
||||
+
|
||||
/* key is stored in external hardware */
|
||||
#define SSHKEY_FLAG_EXT 0x0001
|
||||
|
||||
@@ -221,7 +228,7 @@ int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp);
|
||||
/* private key file format parsing and serialisation */
|
||||
int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
|
||||
const char *passphrase, const char *comment,
|
||||
- int force_new_format, const char *new_format_cipher, int new_format_rounds);
|
||||
+ int format, const char *openssh_format_cipher, int openssh_format_rounds);
|
||||
int sshkey_parse_private_fileblob(struct sshbuf *buffer,
|
||||
const char *passphrase, struct sshkey **keyp, char **commentp);
|
||||
int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
|
||||
|
||||
3140
openssh-8.0p1-pkcs11-uri.patch
Normal file
3140
openssh-8.0p1-pkcs11-uri.patch
Normal file
File diff suppressed because it is too large
Load diff
44
openssh-8.0p1-preserve-pam-errors.patch
Normal file
44
openssh-8.0p1-preserve-pam-errors.patch
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c
|
||||
--- openssh-8.0p1/auth-pam.c.preserve-pam-errors 2021-03-31 17:03:15.618592347 +0200
|
||||
+++ openssh-8.0p1/auth-pam.c 2021-03-31 17:06:58.115220014 +0200
|
||||
@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp)
|
||||
goto auth_fail;
|
||||
|
||||
if (!do_pam_account()) {
|
||||
- sshpam_err = PAM_ACCT_EXPIRED;
|
||||
+ /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN.
|
||||
+ * Backward compatibility for other errors. */
|
||||
+ if (sshpam_err != PAM_PERM_DENIED
|
||||
+ && sshpam_err != PAM_USER_UNKNOWN)
|
||||
+ sshpam_err = PAM_ACCT_EXPIRED;
|
||||
goto auth_fail;
|
||||
}
|
||||
if (sshpam_authctxt->force_pwchange) {
|
||||
@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp)
|
||||
pam_strerror(sshpam_handle, sshpam_err))) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
/* XXX - can't do much about an error here */
|
||||
- if (sshpam_err == PAM_ACCT_EXPIRED)
|
||||
- ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
|
||||
+ if (sshpam_err == PAM_PERM_DENIED
|
||||
+ || sshpam_err == PAM_USER_UNKNOWN
|
||||
+ || sshpam_err == PAM_ACCT_EXPIRED)
|
||||
+ ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer);
|
||||
else if (sshpam_maxtries_reached)
|
||||
ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
|
||||
else
|
||||
@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha
|
||||
plen++;
|
||||
free(msg);
|
||||
break;
|
||||
+ case PAM_USER_UNKNOWN:
|
||||
+ case PAM_PERM_DENIED:
|
||||
case PAM_ACCT_EXPIRED:
|
||||
+ sshpam_account_status = 0;
|
||||
+ /* FALLTHROUGH */
|
||||
case PAM_MAXTRIES:
|
||||
- if (type == PAM_ACCT_EXPIRED)
|
||||
- sshpam_account_status = 0;
|
||||
if (type == PAM_MAXTRIES)
|
||||
sshpam_set_maxtries_reached(1);
|
||||
/* FALLTHROUGH */
|
||||
33
openssh-8.0p1-proxyjump-loops.patch
Normal file
33
openssh-8.0p1-proxyjump-loops.patch
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
From de1f3564cd85915b3002859873a37cb8d31ac9ce Mon Sep 17 00:00:00 2001
|
||||
From: "dtucker@openbsd.org" <dtucker@openbsd.org>
|
||||
Date: Tue, 18 Feb 2020 08:49:49 +0000
|
||||
Subject: [PATCH] upstream: Detect and prevent simple configuration loops when
|
||||
using
|
||||
|
||||
ProxyJump. bz#3057, ok djm@
|
||||
|
||||
OpenBSD-Commit-ID: 077d21c564c886c98309d871ed6f8ef267b9f037
|
||||
---
|
||||
ssh.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ssh.c b/ssh.c
|
||||
index 15aee569e..a983a108b 100644
|
||||
--- a/ssh.c
|
||||
+++ b/ssh.c
|
||||
@@ -1208,6 +1208,14 @@ main(int ac, char **av)
|
||||
if (options.jump_host != NULL) {
|
||||
char port_s[8];
|
||||
const char *sshbin = argv0;
|
||||
+ int port = options.port, jumpport = options.jump_port;
|
||||
+
|
||||
+ if (port <= 0)
|
||||
+ port = default_ssh_port();
|
||||
+ if (jumpport <= 0)
|
||||
+ jumpport = default_ssh_port();
|
||||
+ if (strcmp(options.jump_host, host) == 0 && port == jumpport)
|
||||
+ fatal("jumphost loop via %s", options.jump_host);
|
||||
|
||||
/*
|
||||
* Try to use SSH indicated by argv[0], but fall back to
|
||||
|
||||
44
openssh-8.0p1-rdomain.patch
Normal file
44
openssh-8.0p1-rdomain.patch
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
commit 5481d0b4036b33b92c372ee36258ed11bff57d5d
|
||||
Author: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Thu Feb 27 10:07:33 2020 +0100
|
||||
|
||||
Mark the RDomain configuration option unsupported on non-openbsd builds
|
||||
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index db80e943..153d2525 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -698,7 +698,11 @@ static struct {
|
||||
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
|
||||
{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
|
||||
{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
|
||||
+#if defined(__OpenBSD__)
|
||||
{ "rdomain", sRDomain, SSHCFG_ALL },
|
||||
+#else
|
||||
+ { "rdomain", sUnsupported, SSHCFG_ALL },
|
||||
+#endif
|
||||
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
|
||||
{ NULL, sBadOption, 0 }
|
||||
};
|
||||
@@ -2841,7 +2845,9 @@ dump_config(ServerOptions *o)
|
||||
o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
|
||||
dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
|
||||
o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
|
||||
+#if defined(__OpenBSD__)
|
||||
dump_cfg_string(sRDomain, o->routing_domain);
|
||||
+#endif
|
||||
|
||||
/* string arguments requiring a lookup */
|
||||
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index 5dca8981..766e9b90 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -1542,6 +1542,7 @@ will be bound to this
|
||||
If the routing domain is set to
|
||||
.Cm \&%D ,
|
||||
then the domain in which the incoming connection was received will be applied.
|
||||
+This feature is available on OpenBSD only.
|
||||
.It Cm SetEnv
|
||||
Specifies one or more environment variables to set in child sessions started
|
||||
by
|
||||
311
openssh-8.0p1-restore-nonblock.patch
Normal file
311
openssh-8.0p1-restore-nonblock.patch
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
diff -up openssh-8.0p1/channels.c.restore-nonblock openssh-8.0p1/channels.c
|
||||
--- openssh-8.0p1/channels.c.restore-nonblock 2021-06-21 10:44:26.380559612 +0200
|
||||
+++ openssh-8.0p1/channels.c 2021-06-21 10:48:47.754579151 +0200
|
||||
@@ -333,7 +333,27 @@ channel_register_fds(struct ssh *ssh, Ch
|
||||
#endif
|
||||
|
||||
/* enable nonblocking mode */
|
||||
- if (nonblock) {
|
||||
+ c->restore_block = 0;
|
||||
+ if (nonblock == CHANNEL_NONBLOCK_STDIO) {
|
||||
+ /*
|
||||
+ * Special handling for stdio file descriptors: do not set
|
||||
+ * non-blocking mode if they are TTYs. Otherwise prepare to
|
||||
+ * restore their blocking state on exit to avoid interfering
|
||||
+ * with other programs that follow.
|
||||
+ */
|
||||
+ if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) {
|
||||
+ c->restore_block |= CHANNEL_RESTORE_RFD;
|
||||
+ set_nonblock(rfd);
|
||||
+ }
|
||||
+ if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) {
|
||||
+ c->restore_block |= CHANNEL_RESTORE_WFD;
|
||||
+ set_nonblock(wfd);
|
||||
+ }
|
||||
+ if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) {
|
||||
+ c->restore_block |= CHANNEL_RESTORE_EFD;
|
||||
+ set_nonblock(efd);
|
||||
+ }
|
||||
+ } else if (nonblock) {
|
||||
if (rfd != -1)
|
||||
set_nonblock(rfd);
|
||||
if (wfd != -1)
|
||||
@@ -422,17 +442,23 @@ channel_find_maxfd(struct ssh_channels *
|
||||
}
|
||||
|
||||
int
|
||||
-channel_close_fd(struct ssh *ssh, int *fdp)
|
||||
+channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
|
||||
{
|
||||
struct ssh_channels *sc = ssh->chanctxt;
|
||||
- int ret = 0, fd = *fdp;
|
||||
+ int ret, fd = *fdp;
|
||||
|
||||
- if (fd != -1) {
|
||||
- ret = close(fd);
|
||||
- *fdp = -1;
|
||||
- if (fd == sc->channel_max_fd)
|
||||
- channel_find_maxfd(sc);
|
||||
- }
|
||||
+ if (fd == -1)
|
||||
+ return 0;
|
||||
+
|
||||
+ if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) ||
|
||||
+ (*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) ||
|
||||
+ (*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0))
|
||||
+ (void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */
|
||||
+
|
||||
+ ret = close(fd);
|
||||
+ *fdp = -1;
|
||||
+ if (fd == sc->channel_max_fd)
|
||||
+ channel_find_maxfd(sc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -442,13 +468,13 @@ channel_close_fds(struct ssh *ssh, Chann
|
||||
{
|
||||
int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd;
|
||||
|
||||
- channel_close_fd(ssh, &c->sock);
|
||||
+ channel_close_fd(ssh, c, &c->sock);
|
||||
if (rfd != sock)
|
||||
- channel_close_fd(ssh, &c->rfd);
|
||||
+ channel_close_fd(ssh, c, &c->rfd);
|
||||
if (wfd != sock && wfd != rfd)
|
||||
- channel_close_fd(ssh, &c->wfd);
|
||||
+ channel_close_fd(ssh, c, &c->wfd);
|
||||
if (efd != sock && efd != rfd && efd != wfd)
|
||||
- channel_close_fd(ssh, &c->efd);
|
||||
+ channel_close_fd(ssh, c, &c->efd);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -681,7 +707,7 @@ channel_stop_listening(struct ssh *ssh)
|
||||
case SSH_CHANNEL_X11_LISTENER:
|
||||
case SSH_CHANNEL_UNIX_LISTENER:
|
||||
case SSH_CHANNEL_RUNIX_LISTENER:
|
||||
- channel_close_fd(ssh, &c->sock);
|
||||
+ channel_close_fd(ssh, c, &c->sock);
|
||||
channel_free(ssh, c);
|
||||
break;
|
||||
}
|
||||
@@ -1487,7 +1513,8 @@ channel_decode_socks5(Channel *c, struct
|
||||
|
||||
Channel *
|
||||
channel_connect_stdio_fwd(struct ssh *ssh,
|
||||
- const char *host_to_connect, u_short port_to_connect, int in, int out)
|
||||
+ const char *host_to_connect, u_short port_to_connect,
|
||||
+ int in, int out, int nonblock)
|
||||
{
|
||||
Channel *c;
|
||||
|
||||
@@ -1495,7 +1522,7 @@ channel_connect_stdio_fwd(struct ssh *ss
|
||||
|
||||
c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out,
|
||||
-1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
|
||||
- 0, "stdio-forward", /*nonblock*/0);
|
||||
+ 0, "stdio-forward", nonblock);
|
||||
|
||||
c->path = xstrdup(host_to_connect);
|
||||
c->host_port = port_to_connect;
|
||||
@@ -1650,7 +1677,7 @@ channel_post_x11_listener(struct ssh *ss
|
||||
if (c->single_connection) {
|
||||
oerrno = errno;
|
||||
debug2("single_connection: closing X11 listener.");
|
||||
- channel_close_fd(ssh, &c->sock);
|
||||
+ channel_close_fd(ssh, c, &c->sock);
|
||||
chan_mark_dead(ssh, c);
|
||||
errno = oerrno;
|
||||
}
|
||||
@@ -2087,7 +2114,7 @@ channel_handle_efd_write(struct ssh *ssh
|
||||
return 1;
|
||||
if (len <= 0) {
|
||||
debug2("channel %d: closing write-efd %d", c->self, c->efd);
|
||||
- channel_close_fd(ssh, &c->efd);
|
||||
+ channel_close_fd(ssh, c, &c->efd);
|
||||
} else {
|
||||
if ((r = sshbuf_consume(c->extended, len)) != 0) {
|
||||
fatal("%s: channel %d: consume: %s",
|
||||
@@ -2119,7 +2146,7 @@ channel_handle_efd_read(struct ssh *ssh,
|
||||
if (len <= 0) {
|
||||
debug2("channel %d: closing read-efd %d",
|
||||
c->self, c->efd);
|
||||
- channel_close_fd(ssh, &c->efd);
|
||||
+ channel_close_fd(ssh, c, &c->efd);
|
||||
} else {
|
||||
if (c->extended_usage == CHAN_EXTENDED_IGNORE) {
|
||||
debug3("channel %d: discard efd",
|
||||
diff -up openssh-8.0p1/channels.h.restore-nonblock openssh-8.0p1/channels.h
|
||||
--- openssh-8.0p1/channels.h.restore-nonblock 2021-06-21 10:44:26.380559612 +0200
|
||||
+++ openssh-8.0p1/channels.h 2021-06-21 10:44:26.387559665 +0200
|
||||
@@ -63,6 +63,16 @@
|
||||
|
||||
#define CHANNEL_CANCEL_PORT_STATIC -1
|
||||
|
||||
+/* nonblocking flags for channel_new */
|
||||
+#define CHANNEL_NONBLOCK_LEAVE 0 /* don't modify non-blocking state */
|
||||
+#define CHANNEL_NONBLOCK_SET 1 /* set non-blocking state */
|
||||
+#define CHANNEL_NONBLOCK_STDIO 2 /* set non-blocking and restore on close */
|
||||
+
|
||||
+/* c->restore_block mask flags */
|
||||
+#define CHANNEL_RESTORE_RFD 0x01
|
||||
+#define CHANNEL_RESTORE_WFD 0x02
|
||||
+#define CHANNEL_RESTORE_EFD 0x04
|
||||
+
|
||||
/* TCP forwarding */
|
||||
#define FORWARD_DENY 0
|
||||
#define FORWARD_REMOTE (1)
|
||||
@@ -131,6 +141,7 @@ struct Channel {
|
||||
* to a matching pre-select handler.
|
||||
* this way post-select handlers are not
|
||||
* accidentally called if a FD gets reused */
|
||||
+ int restore_block; /* fd mask to restore blocking status */
|
||||
struct sshbuf *input; /* data read from socket, to be sent over
|
||||
* encrypted connection */
|
||||
struct sshbuf *output; /* data received over encrypted connection for
|
||||
@@ -258,7 +269,7 @@ void channel_register_filter(struct ssh
|
||||
void channel_register_status_confirm(struct ssh *, int,
|
||||
channel_confirm_cb *, channel_confirm_abandon_cb *, void *);
|
||||
void channel_cancel_cleanup(struct ssh *, int);
|
||||
-int channel_close_fd(struct ssh *, int *);
|
||||
+int channel_close_fd(struct ssh *, Channel *, int *);
|
||||
void channel_send_window_changes(struct ssh *);
|
||||
|
||||
/* mux proxy support */
|
||||
@@ -305,7 +316,7 @@ Channel *channel_connect_to_port(struct
|
||||
char *, char *, int *, const char **);
|
||||
Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
|
||||
Channel *channel_connect_stdio_fwd(struct ssh *, const char*,
|
||||
- u_short, int, int);
|
||||
+ u_short, int, int, int);
|
||||
Channel *channel_connect_by_listen_address(struct ssh *, const char *,
|
||||
u_short, char *, char *);
|
||||
Channel *channel_connect_by_listen_path(struct ssh *, const char *,
|
||||
diff -up openssh-8.0p1/clientloop.c.restore-nonblock openssh-8.0p1/clientloop.c
|
||||
--- openssh-8.0p1/clientloop.c.restore-nonblock 2021-06-21 10:44:26.290558923 +0200
|
||||
+++ openssh-8.0p1/clientloop.c 2021-06-21 10:44:26.387559665 +0200
|
||||
@@ -1436,14 +1436,6 @@ client_loop(struct ssh *ssh, int have_pt
|
||||
if (have_pty)
|
||||
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
|
||||
|
||||
- /* restore blocking io */
|
||||
- if (!isatty(fileno(stdin)))
|
||||
- unset_nonblock(fileno(stdin));
|
||||
- if (!isatty(fileno(stdout)))
|
||||
- unset_nonblock(fileno(stdout));
|
||||
- if (!isatty(fileno(stderr)))
|
||||
- unset_nonblock(fileno(stderr));
|
||||
-
|
||||
/*
|
||||
* If there was no shell or command requested, there will be no remote
|
||||
* exit status to be returned. In that case, clear error code if the
|
||||
diff -up openssh-8.0p1/mux.c.restore-nonblock openssh-8.0p1/mux.c
|
||||
--- openssh-8.0p1/mux.c.restore-nonblock 2019-04-18 00:52:57.000000000 +0200
|
||||
+++ openssh-8.0p1/mux.c 2021-06-21 10:50:51.007537336 +0200
|
||||
@@ -454,14 +454,6 @@ mux_master_process_new_session(struct ss
|
||||
if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
|
||||
error("%s: tcgetattr: %s", __func__, strerror(errno));
|
||||
|
||||
- /* enable nonblocking unless tty */
|
||||
- if (!isatty(new_fd[0]))
|
||||
- set_nonblock(new_fd[0]);
|
||||
- if (!isatty(new_fd[1]))
|
||||
- set_nonblock(new_fd[1]);
|
||||
- if (!isatty(new_fd[2]))
|
||||
- set_nonblock(new_fd[2]);
|
||||
-
|
||||
window = CHAN_SES_WINDOW_DEFAULT;
|
||||
packetmax = CHAN_SES_PACKET_DEFAULT;
|
||||
if (cctx->want_tty) {
|
||||
@@ -471,7 +463,7 @@ mux_master_process_new_session(struct ss
|
||||
|
||||
nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING,
|
||||
new_fd[0], new_fd[1], new_fd[2], window, packetmax,
|
||||
- CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
|
||||
+ CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO);
|
||||
|
||||
nc->ctl_chan = c->self; /* link session -> control channel */
|
||||
c->remote_id = nc->self; /* link control -> session channel */
|
||||
@@ -1033,13 +1025,8 @@ mux_master_process_stdio_fwd(struct ssh
|
||||
}
|
||||
}
|
||||
|
||||
- /* enable nonblocking unless tty */
|
||||
- if (!isatty(new_fd[0]))
|
||||
- set_nonblock(new_fd[0]);
|
||||
- if (!isatty(new_fd[1]))
|
||||
- set_nonblock(new_fd[1]);
|
||||
-
|
||||
- nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]);
|
||||
+ nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1],
|
||||
+ CHANNEL_NONBLOCK_STDIO);
|
||||
free(chost);
|
||||
|
||||
nc->ctl_chan = c->self; /* link session -> control channel */
|
||||
diff -up openssh-8.0p1/nchan.c.restore-nonblock openssh-8.0p1/nchan.c
|
||||
--- openssh-8.0p1/nchan.c.restore-nonblock 2021-06-21 10:44:26.388559673 +0200
|
||||
+++ openssh-8.0p1/nchan.c 2021-06-21 10:52:42.685405537 +0200
|
||||
@@ -387,7 +387,7 @@ chan_shutdown_write(struct ssh *ssh, Cha
|
||||
strerror(errno));
|
||||
}
|
||||
} else {
|
||||
- if (channel_close_fd(ssh, &c->wfd) < 0) {
|
||||
+ if (channel_close_fd(ssh, c, &c->wfd) < 0) {
|
||||
logit("channel %d: %s: close() failed for "
|
||||
"fd %d [i%d o%d]: %.100s",
|
||||
c->self, __func__, c->wfd, c->istate, c->ostate,
|
||||
@@ -417,7 +417,7 @@ chan_shutdown_read(struct ssh *ssh, Chan
|
||||
strerror(errno));
|
||||
}
|
||||
} else {
|
||||
- if (channel_close_fd(ssh, &c->rfd) < 0) {
|
||||
+ if (channel_close_fd(ssh, c, &c->rfd) < 0) {
|
||||
logit("channel %d: %s: close() failed for "
|
||||
"fd %d [i%d o%d]: %.100s",
|
||||
c->self, __func__, c->rfd, c->istate, c->ostate,
|
||||
@@ -437,7 +437,7 @@ chan_shutdown_extended_read(struct ssh *
|
||||
debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])",
|
||||
c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd,
|
||||
channel_format_extended_usage(c));
|
||||
- if (channel_close_fd(ssh, &c->efd) < 0) {
|
||||
+ if (channel_close_fd(ssh, c, &c->efd) < 0) {
|
||||
logit("channel %d: %s: close() failed for "
|
||||
"extended fd %d [i%d o%d]: %.100s",
|
||||
c->self, __func__, c->efd, c->istate, c->ostate,
|
||||
diff -up openssh-8.0p1/ssh.c.restore-nonblock openssh-8.0p1/ssh.c
|
||||
--- openssh-8.0p1/ssh.c.restore-nonblock 2021-06-21 10:44:26.389559681 +0200
|
||||
+++ openssh-8.0p1/ssh.c 2021-06-21 10:54:47.651377045 +0200
|
||||
@@ -1709,7 +1709,8 @@ ssh_init_stdio_forwarding(struct ssh *ss
|
||||
(out = dup(STDOUT_FILENO)) < 0)
|
||||
fatal("channel_connect_stdio_fwd: dup() in/out failed");
|
||||
if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host,
|
||||
- options.stdio_forward_port, in, out)) == NULL)
|
||||
+ options.stdio_forward_port, in, out,
|
||||
+ CHANNEL_NONBLOCK_STDIO)) == NULL)
|
||||
fatal("%s: channel_connect_stdio_fwd failed", __func__);
|
||||
channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0);
|
||||
channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL);
|
||||
@@ -1862,14 +1863,6 @@ ssh_session2_open(struct ssh *ssh)
|
||||
if (in < 0 || out < 0 || err < 0)
|
||||
fatal("dup() in/out/err failed");
|
||||
|
||||
- /* enable nonblocking unless tty */
|
||||
- if (!isatty(in))
|
||||
- set_nonblock(in);
|
||||
- if (!isatty(out))
|
||||
- set_nonblock(out);
|
||||
- if (!isatty(err))
|
||||
- set_nonblock(err);
|
||||
-
|
||||
window = CHAN_SES_WINDOW_DEFAULT;
|
||||
packetmax = CHAN_SES_PACKET_DEFAULT;
|
||||
if (tty_flag) {
|
||||
@@ -1879,7 +1872,7 @@ ssh_session2_open(struct ssh *ssh)
|
||||
c = channel_new(ssh,
|
||||
"session", SSH_CHANNEL_OPENING, in, out, err,
|
||||
window, packetmax, CHAN_EXTENDED_WRITE,
|
||||
- "client-session", /*nonblock*/0);
|
||||
+ "client-session", CHANNEL_NONBLOCK_STDIO);
|
||||
|
||||
debug3("%s: channel_new: %d", __func__, c->self);
|
||||
|
||||
61
openssh-8.0p1-scp-tests.patch
Normal file
61
openssh-8.0p1-scp-tests.patch
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh
|
||||
index 59f1ff63..dd48a482 100644
|
||||
--- a/regress/scp-ssh-wrapper.sh
|
||||
+++ b/regress/scp-ssh-wrapper.sh
|
||||
@@ -51,6 +51,18 @@ badserver_4)
|
||||
echo "C755 2 file"
|
||||
echo "X"
|
||||
;;
|
||||
+badserver_5)
|
||||
+ echo "D0555 0 "
|
||||
+ echo "X"
|
||||
+ ;;
|
||||
+badserver_6)
|
||||
+ echo "D0555 0 ."
|
||||
+ echo "X"
|
||||
+ ;;
|
||||
+badserver_7)
|
||||
+ echo "C0755 2 extrafile"
|
||||
+ echo "X"
|
||||
+ ;;
|
||||
*)
|
||||
set -- $arg
|
||||
shift
|
||||
diff --git a/regress/scp.sh b/regress/scp.sh
|
||||
index 57cc7706..104c89e1 100644
|
||||
--- a/regress/scp.sh
|
||||
+++ b/regress/scp.sh
|
||||
@@ -25,6 +25,7 @@ export SCP # used in scp-ssh-wrapper.scp
|
||||
scpclean() {
|
||||
rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2}
|
||||
mkdir ${DIR} ${DIR2}
|
||||
+ chmod 755 ${DIR} ${DIR2}
|
||||
}
|
||||
|
||||
verbose "$tid: simple copy local file to local file"
|
||||
@@ -101,7 +102,7 @@ if [ ! -z "$SUDO" ]; then
|
||||
$SUDO rm ${DIR2}/copy
|
||||
fi
|
||||
|
||||
-for i in 0 1 2 3 4; do
|
||||
+for i in 0 1 2 3 4 5 6 7; do
|
||||
verbose "$tid: disallow bad server #$i"
|
||||
SCPTESTMODE=badserver_$i
|
||||
export DIR SCPTESTMODE
|
||||
@@ -113,6 +114,15 @@ for i in 0 1 2 3 4; do
|
||||
scpclean
|
||||
$SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
|
||||
[ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir"
|
||||
+
|
||||
+ scpclean
|
||||
+ $SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
|
||||
+ [ ! -w ${DIR2} ] && fail "allows target root attribute change"
|
||||
+
|
||||
+ scpclean
|
||||
+ $SCP $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
|
||||
+ [ -e ${DIR2}/extrafile ] && fail "allows extranous object creation"
|
||||
+ rm -f ${DIR2}/extrafile
|
||||
done
|
||||
|
||||
verbose "$tid: detect non-directory target"
|
||||
|
||||
273
openssh-8.0p1-sftp-realpath.patch
Normal file
273
openssh-8.0p1-sftp-realpath.patch
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
diff --color -ruN a/Makefile.in b/Makefile.in
|
||||
--- a/Makefile.in 2022-06-23 11:31:10.168186838 +0200
|
||||
+++ b/Makefile.in 2022-06-23 11:32:19.146513347 +0200
|
||||
@@ -125,7 +125,7 @@
|
||||
monitor.o monitor_wrap.o auth-krb5.o \
|
||||
auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \
|
||||
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
|
||||
- sftp-server.o sftp-common.o \
|
||||
+ sftp-server.o sftp-common.o sftp-realpath.o \
|
||||
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
|
||||
sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \
|
||||
sandbox-solaris.o uidswap.o
|
||||
@@ -217,8 +217,8 @@
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
|
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(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)
|
||||
+sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-realpath.o sftp-server.o sftp-server-main.o
|
||||
+ $(LD) -o $@ sftp-server.o sftp-common.o sftp-realpath.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
|
||||
$(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
|
||||
diff --color -ruN a/sftp-realpath.c b/sftp-realpath.c
|
||||
--- a/sftp-realpath.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/sftp-realpath.c 2022-06-23 11:35:33.193244873 +0200
|
||||
@@ -0,0 +1,225 @@
|
||||
+/* $OpenBSD: sftp-realpath.c,v 1.2 2021/09/02 21:03:54 deraadt Exp $ */
|
||||
+/*
|
||||
+ * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ * 3. The names of the authors may not be used to endorse or promote
|
||||
+ * products derived from this software without specific prior written
|
||||
+ * permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
+ * SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+#include "includes.h"
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stddef.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+#include <limits.h>
|
||||
+
|
||||
+#ifndef SYMLOOP_MAX
|
||||
+# define SYMLOOP_MAX 32
|
||||
+#endif
|
||||
+
|
||||
+/* XXX rewrite sftp-server to use POSIX realpath and remove this hack */
|
||||
+
|
||||
+char *sftp_realpath(const char *path, char *resolved);
|
||||
+
|
||||
+/*
|
||||
+ * char *realpath(const char *path, char resolved[PATH_MAX]);
|
||||
+ *
|
||||
+ * Find the real name of path, by removing all ".", ".." and symlink
|
||||
+ * components. Returns (resolved) on success, or (NULL) on failure,
|
||||
+ * in which case the path which caused trouble is left in (resolved).
|
||||
+ */
|
||||
+char *
|
||||
+sftp_realpath(const char *path, char *resolved)
|
||||
+{
|
||||
+ struct stat sb;
|
||||
+ char *p, *q, *s;
|
||||
+ size_t left_len, resolved_len;
|
||||
+ unsigned symlinks;
|
||||
+ int serrno, slen, mem_allocated;
|
||||
+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
|
||||
+
|
||||
+ if (path[0] == '\0') {
|
||||
+ errno = ENOENT;
|
||||
+ return (NULL);
|
||||
+ }
|
||||
+
|
||||
+ serrno = errno;
|
||||
+
|
||||
+ if (resolved == NULL) {
|
||||
+ resolved = malloc(PATH_MAX);
|
||||
+ if (resolved == NULL)
|
||||
+ return (NULL);
|
||||
+ mem_allocated = 1;
|
||||
+ } else
|
||||
+ mem_allocated = 0;
|
||||
+
|
||||
+ symlinks = 0;
|
||||
+ if (path[0] == '/') {
|
||||
+ resolved[0] = '/';
|
||||
+ resolved[1] = '\0';
|
||||
+ if (path[1] == '\0')
|
||||
+ return (resolved);
|
||||
+ resolved_len = 1;
|
||||
+ left_len = strlcpy(left, path + 1, sizeof(left));
|
||||
+ } else {
|
||||
+ if (getcwd(resolved, PATH_MAX) == NULL) {
|
||||
+ if (mem_allocated)
|
||||
+ free(resolved);
|
||||
+ else
|
||||
+ strlcpy(resolved, ".", PATH_MAX);
|
||||
+ return (NULL);
|
||||
+ }
|
||||
+ resolved_len = strlen(resolved);
|
||||
+ left_len = strlcpy(left, path, sizeof(left));
|
||||
+ }
|
||||
+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Iterate over path components in `left'.
|
||||
+ */
|
||||
+ while (left_len != 0) {
|
||||
+ /*
|
||||
+ * Extract the next path component and adjust `left'
|
||||
+ * and its length.
|
||||
+ */
|
||||
+ p = strchr(left, '/');
|
||||
+ s = p ? p : left + left_len;
|
||||
+ if (s - left >= (ptrdiff_t)sizeof(next_token)) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ memcpy(next_token, left, s - left);
|
||||
+ next_token[s - left] = '\0';
|
||||
+ left_len -= s - left;
|
||||
+ if (p != NULL)
|
||||
+ memmove(left, s + 1, left_len + 1);
|
||||
+ if (resolved[resolved_len - 1] != '/') {
|
||||
+ if (resolved_len + 1 >= PATH_MAX) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ resolved[resolved_len++] = '/';
|
||||
+ resolved[resolved_len] = '\0';
|
||||
+ }
|
||||
+ if (next_token[0] == '\0')
|
||||
+ continue;
|
||||
+ else if (strcmp(next_token, ".") == 0)
|
||||
+ continue;
|
||||
+ else if (strcmp(next_token, "..") == 0) {
|
||||
+ /*
|
||||
+ * Strip the last path component except when we have
|
||||
+ * single "/"
|
||||
+ */
|
||||
+ if (resolved_len > 1) {
|
||||
+ resolved[resolved_len - 1] = '\0';
|
||||
+ q = strrchr(resolved, '/') + 1;
|
||||
+ *q = '\0';
|
||||
+ resolved_len = q - resolved;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Append the next path component and lstat() it. If
|
||||
+ * lstat() fails we still can return successfully if
|
||||
+ * there are no more path components left.
|
||||
+ */
|
||||
+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
|
||||
+ if (resolved_len >= PATH_MAX) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ if (lstat(resolved, &sb) != 0) {
|
||||
+ if (errno == ENOENT && p == NULL) {
|
||||
+ errno = serrno;
|
||||
+ return (resolved);
|
||||
+ }
|
||||
+ goto err;
|
||||
+ }
|
||||
+ if (S_ISLNK(sb.st_mode)) {
|
||||
+ if (symlinks++ > SYMLOOP_MAX) {
|
||||
+ errno = ELOOP;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
|
||||
+ if (slen < 0)
|
||||
+ goto err;
|
||||
+ symlink[slen] = '\0';
|
||||
+ if (symlink[0] == '/') {
|
||||
+ resolved[1] = 0;
|
||||
+ resolved_len = 1;
|
||||
+ } else if (resolved_len > 1) {
|
||||
+ /* Strip the last path component. */
|
||||
+ resolved[resolved_len - 1] = '\0';
|
||||
+ q = strrchr(resolved, '/') + 1;
|
||||
+ *q = '\0';
|
||||
+ resolved_len = q - resolved;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * If there are any path components left, then
|
||||
+ * append them to symlink. The result is placed
|
||||
+ * in `left'.
|
||||
+ */
|
||||
+ if (p != NULL) {
|
||||
+ if (symlink[slen - 1] != '/') {
|
||||
+ if (slen + 1 >=
|
||||
+ (ptrdiff_t)sizeof(symlink)) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ symlink[slen] = '/';
|
||||
+ symlink[slen + 1] = 0;
|
||||
+ }
|
||||
+ left_len = strlcat(symlink, left, sizeof(symlink));
|
||||
+ if (left_len >= sizeof(symlink)) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ }
|
||||
+ left_len = strlcpy(left, symlink, sizeof(left));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Remove trailing slash except when the resolved pathname
|
||||
+ * is a single "/".
|
||||
+ */
|
||||
+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
|
||||
+ resolved[resolved_len - 1] = '\0';
|
||||
+ return (resolved);
|
||||
+
|
||||
+err:
|
||||
+ if (mem_allocated)
|
||||
+ free(resolved);
|
||||
+ return (NULL);
|
||||
+}
|
||||
diff --color -ruN a/sftp-server.c b/sftp-server.c
|
||||
--- a/sftp-server.c 2022-06-23 11:31:10.147186434 +0200
|
||||
+++ b/sftp-server.c 2022-06-23 11:32:19.147513366 +0200
|
||||
@@ -51,6 +51,8 @@
|
||||
#include "sftp.h"
|
||||
#include "sftp-common.h"
|
||||
|
||||
+char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
|
||||
+
|
||||
/* Our verbosity */
|
||||
static LogLevel log_level = SYSLOG_LEVEL_ERROR;
|
||||
|
||||
@@ -1185,7 +1187,7 @@
|
||||
}
|
||||
debug3("request %u: realpath", id);
|
||||
verbose("realpath \"%s\"", path);
|
||||
- if (realpath(path, resolvedname) == NULL) {
|
||||
+ if (sftp_realpath(path, resolvedname) == NULL) {
|
||||
send_status(id, errno_to_portable(errno));
|
||||
} else {
|
||||
Stat s;
|
||||
16
openssh-8.0p1-sftp-timespeccmp.patch
Normal file
16
openssh-8.0p1-sftp-timespeccmp.patch
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
diff -up openssh-8.0p1/sftp.c.original openssh-8.0p1/sftp.c
|
||||
--- openssh-8.0p1/sftp.c.original 2020-12-22 17:05:02.105698989 +0900
|
||||
+++ openssh-8.0p1/sftp.c 2020-12-22 17:05:42.922035780 +0900
|
||||
@@ -937,7 +937,11 @@ sglob_comp(const void *aa, const void *b
|
||||
return (rmul * strcmp(ap, bp));
|
||||
else if (sort_flag & LS_TIME_SORT) {
|
||||
#if defined(HAVE_STRUCT_STAT_ST_MTIM)
|
||||
- return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
|
||||
+ if (timespeccmp(&as->st_mtim, &bs->st_mtim, <)){
|
||||
+ return rmul;
|
||||
+ } else {
|
||||
+ return -rmul;
|
||||
+ }
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIME)
|
||||
return (rmul * NCMP(as->st_mtime, bs->st_mtime));
|
||||
#else
|
||||
97
openssh-8.0p1-sshd_config.patch
Normal file
97
openssh-8.0p1-sshd_config.patch
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
diff --git a/servconf.c b/servconf.c
|
||||
index ffac5d2c..340045b2 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -1042,7 +1042,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
return -1;
|
||||
}
|
||||
if (strcasecmp(attrib, "user") == 0) {
|
||||
- if (ci == NULL) {
|
||||
+ if (ci == NULL || (ci->test && ci->user == NULL)) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -1054,7 +1054,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
debug("user %.100s matched 'User %.100s' at "
|
||||
"line %d", ci->user, arg, line);
|
||||
} else if (strcasecmp(attrib, "group") == 0) {
|
||||
- if (ci == NULL) {
|
||||
+ if (ci == NULL || (ci->test && ci->user == NULL)) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -1067,7 +1067,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
result = 0;
|
||||
}
|
||||
} else if (strcasecmp(attrib, "host") == 0) {
|
||||
- if (ci == NULL) {
|
||||
+ if (ci == NULL || (ci->test && ci->host == NULL)) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -1079,7 +1079,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
debug("connection from %.100s matched 'Host "
|
||||
"%.100s' at line %d", ci->host, arg, line);
|
||||
} else if (strcasecmp(attrib, "address") == 0) {
|
||||
- if (ci == NULL) {
|
||||
+ if (ci == NULL || (ci->test && ci->address == NULL)) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -1098,7 +1098,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
return -1;
|
||||
}
|
||||
} else if (strcasecmp(attrib, "localaddress") == 0){
|
||||
- if (ci == NULL) {
|
||||
+ if (ci == NULL || (ci->test && ci->laddress == NULL)) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -1124,7 +1124,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
arg);
|
||||
return -1;
|
||||
}
|
||||
- if (ci == NULL) {
|
||||
+ if (ci == NULL || (ci->test && ci->lport == -1)) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -1138,10 +1138,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
else
|
||||
result = 0;
|
||||
} else if (strcasecmp(attrib, "rdomain") == 0) {
|
||||
- if (ci == NULL || ci->rdomain == NULL) {
|
||||
+ if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
|
||||
result = 0;
|
||||
continue;
|
||||
}
|
||||
+ if (ci->rdomain == NULL)
|
||||
+ match_test_missing_fatal("RDomain", "rdomain");
|
||||
if (match_pattern_list(ci->rdomain, arg, 0) != 1)
|
||||
result = 0;
|
||||
else
|
||||
diff --git a/servconf.h b/servconf.h
|
||||
index 54e0a8d8..5483da05 100644
|
||||
--- a/servconf.h
|
||||
+++ b/servconf.h
|
||||
@@ -221,6 +221,8 @@ struct connection_info {
|
||||
const char *laddress; /* local address */
|
||||
int lport; /* local port */
|
||||
const char *rdomain; /* routing domain if available */
|
||||
+ int test; /* test mode, allow some attributes to be
|
||||
+ * unspecified */
|
||||
};
|
||||
|
||||
|
||||
diff --git a/sshd.c b/sshd.c
|
||||
index cbd3bce9..1fcde502 100644
|
||||
--- a/sshd.c
|
||||
+++ b/sshd.c
|
||||
@@ -1843,6 +1843,7 @@ main(int ac, char **av)
|
||||
*/
|
||||
if (connection_info == NULL)
|
||||
connection_info = get_connection_info(ssh, 0, 0);
|
||||
+ connection_info->test = 1;
|
||||
parse_server_match_config(&options, connection_info);
|
||||
dump_config(&options);
|
||||
}
|
||||
805
openssh-8.0p1-sshd_include.patch
Normal file
805
openssh-8.0p1-sshd_include.patch
Normal file
|
|
@ -0,0 +1,805 @@
|
|||
diff -up openssh-8.0p1/auth.c.sshdinclude openssh-8.0p1/auth.c
|
||||
--- openssh-8.0p1/auth.c.sshdinclude 2021-10-20 15:18:49.740331098 +0200
|
||||
+++ openssh-8.0p1/auth.c 2021-10-20 15:19:41.324781344 +0200
|
||||
@@ -80,6 +80,7 @@
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
+extern struct include_list includes;
|
||||
extern int use_privsep;
|
||||
extern struct sshbuf *loginmsg;
|
||||
extern struct passwd *privsep_pw;
|
||||
@@ -573,7 +574,7 @@ getpwnamallow(struct ssh *ssh, const cha
|
||||
|
||||
ci = get_connection_info(ssh, 1, options.use_dns);
|
||||
ci->user = user;
|
||||
- parse_server_match_config(&options, ci);
|
||||
+ parse_server_match_config(&options, &includes, ci);
|
||||
log_change_level(options.log_level);
|
||||
process_permitopen(ssh, &options);
|
||||
|
||||
diff -up openssh-8.0p1/readconf.c.sshdinclude openssh-8.0p1/readconf.c
|
||||
--- openssh-8.0p1/readconf.c.sshdinclude 2021-10-20 15:21:43.541848103 +0200
|
||||
+++ openssh-8.0p1/readconf.c 2021-10-20 15:22:06.302046768 +0200
|
||||
@@ -711,7 +711,7 @@ match_cfg_line(Options *options, char **
|
||||
static void
|
||||
rm_env(Options *options, const char *arg, const char *filename, int linenum)
|
||||
{
|
||||
- int i, j;
|
||||
+ int i, j, onum_send_env = options->num_send_env;
|
||||
char *cp;
|
||||
|
||||
/* Remove an environment variable */
|
||||
@@ -734,6 +734,11 @@ rm_env(Options *options, const char *arg
|
||||
options->num_send_env--;
|
||||
/* NB. don't increment i */
|
||||
}
|
||||
+ if (onum_send_env != options->num_send_env) {
|
||||
+ options->send_env = xrecallocarray(options->send_env,
|
||||
+ onum_send_env, options->num_send_env,
|
||||
+ sizeof(*options->send_env));
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
diff -up openssh-8.0p1/regress/Makefile.sshdinclude openssh-8.0p1/regress/Makefile
|
||||
--- openssh-8.0p1/regress/Makefile.sshdinclude 2021-10-20 15:18:49.742331115 +0200
|
||||
+++ openssh-8.0p1/regress/Makefile 2021-10-20 15:19:41.324781344 +0200
|
||||
@@ -82,6 +82,7 @@ LTESTS= connect \
|
||||
principals-command \
|
||||
cert-file \
|
||||
cfginclude \
|
||||
+ servcfginclude \
|
||||
allow-deny-users \
|
||||
authinfo
|
||||
|
||||
@@ -118,7 +119,7 @@ CLEANFILES= *.core actual agent-key.* au
|
||||
sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \
|
||||
ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
|
||||
ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \
|
||||
- sshd_config.orig sshd_proxy sshd_proxy.* sshd_proxy_bak \
|
||||
+ sshd_config.* sshd_proxy sshd_proxy.* sshd_proxy_bak \
|
||||
sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \
|
||||
t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
|
||||
t8.out t8.out.pub t9.out t9.out.pub testdata \
|
||||
diff -up openssh-8.0p1/regress/servcfginclude.sh.sshdinclude openssh-8.0p1/regress/servcfginclude.sh
|
||||
--- openssh-8.0p1/regress/servcfginclude.sh.sshdinclude 2021-10-20 15:18:49.744331132 +0200
|
||||
+++ openssh-8.0p1/regress/servcfginclude.sh 2021-10-20 15:22:06.303046777 +0200
|
||||
@@ -0,0 +1,188 @@
|
||||
+# Placed in the Public Domain.
|
||||
+
|
||||
+tid="server config include"
|
||||
+
|
||||
+cat > $OBJ/sshd_config.i << _EOF
|
||||
+HostKey $OBJ/host.ssh-ed25519
|
||||
+Match host a
|
||||
+ Banner /aa
|
||||
+
|
||||
+Match host b
|
||||
+ Banner /bb
|
||||
+ Include $OBJ/sshd_config.i.*
|
||||
+
|
||||
+Match host c
|
||||
+ Include $OBJ/sshd_config.i.*
|
||||
+ Banner /cc
|
||||
+
|
||||
+Match host m
|
||||
+ Include $OBJ/sshd_config.i.*
|
||||
+
|
||||
+Match Host d
|
||||
+ Banner /dd
|
||||
+
|
||||
+Match Host e
|
||||
+ Banner /ee
|
||||
+ Include $OBJ/sshd_config.i.*
|
||||
+
|
||||
+Match Host f
|
||||
+ Include $OBJ/sshd_config.i.*
|
||||
+ Banner /ff
|
||||
+
|
||||
+Match Host n
|
||||
+ Include $OBJ/sshd_config.i.*
|
||||
+_EOF
|
||||
+
|
||||
+cat > $OBJ/sshd_config.i.0 << _EOF
|
||||
+Match host xxxxxx
|
||||
+_EOF
|
||||
+
|
||||
+cat > $OBJ/sshd_config.i.1 << _EOF
|
||||
+Match host a
|
||||
+ Banner /aaa
|
||||
+
|
||||
+Match host b
|
||||
+ Banner /bbb
|
||||
+
|
||||
+Match host c
|
||||
+ Banner /ccc
|
||||
+
|
||||
+Match Host d
|
||||
+ Banner /ddd
|
||||
+
|
||||
+Match Host e
|
||||
+ Banner /eee
|
||||
+
|
||||
+Match Host f
|
||||
+ Banner /fff
|
||||
+_EOF
|
||||
+
|
||||
+cat > $OBJ/sshd_config.i.2 << _EOF
|
||||
+Match host a
|
||||
+ Banner /aaaa
|
||||
+
|
||||
+Match host b
|
||||
+ Banner /bbbb
|
||||
+
|
||||
+Match host c
|
||||
+ Banner /cccc
|
||||
+
|
||||
+Match Host d
|
||||
+ Banner /dddd
|
||||
+
|
||||
+Match Host e
|
||||
+ Banner /eeee
|
||||
+
|
||||
+Match Host f
|
||||
+ Banner /ffff
|
||||
+
|
||||
+Match all
|
||||
+ Banner /xxxx
|
||||
+_EOF
|
||||
+
|
||||
+trial() {
|
||||
+ _host="$1"
|
||||
+ _exp="$2"
|
||||
+ _desc="$3"
|
||||
+ test -z "$_desc" && _desc="test match"
|
||||
+ trace "$_desc host=$_host expect=$_exp"
|
||||
+ ${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \
|
||||
+ -C "host=$_host,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out ||
|
||||
+ fatal "ssh config parse failed: $_desc host=$_host expect=$_exp"
|
||||
+ _got=`grep -i '^banner ' $OBJ/sshd_config.out | awk '{print $2}'`
|
||||
+ if test "x$_exp" != "x$_got" ; then
|
||||
+ fail "$desc_ host $_host include fail: expected $_exp got $_got"
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+trial a /aa
|
||||
+trial b /bb
|
||||
+trial c /ccc
|
||||
+trial d /dd
|
||||
+trial e /ee
|
||||
+trial f /fff
|
||||
+trial m /xxxx
|
||||
+trial n /xxxx
|
||||
+trial x none
|
||||
+
|
||||
+# Prepare an included config with an error.
|
||||
+
|
||||
+cat > $OBJ/sshd_config.i.3 << _EOF
|
||||
+Banner xxxx
|
||||
+ Junk
|
||||
+_EOF
|
||||
+
|
||||
+trace "disallow invalid config host=a"
|
||||
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i \
|
||||
+ -C "host=a,user=test,addr=127.0.0.1" 2>/dev/null && \
|
||||
+ fail "sshd include allowed invalid config"
|
||||
+
|
||||
+trace "disallow invalid config host=x"
|
||||
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i \
|
||||
+ -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
|
||||
+ fail "sshd include allowed invalid config"
|
||||
+
|
||||
+rm -f $OBJ/sshd_config.i.*
|
||||
+
|
||||
+# Ensure that a missing include is not fatal.
|
||||
+cat > $OBJ/sshd_config.i << _EOF
|
||||
+HostKey $OBJ/host.ssh-ed25519
|
||||
+Include $OBJ/sshd_config.i.*
|
||||
+Banner /aa
|
||||
+_EOF
|
||||
+
|
||||
+trial a /aa "missing include non-fatal"
|
||||
+
|
||||
+# Ensure that Match/Host in an included config does not affect parent.
|
||||
+cat > $OBJ/sshd_config.i.x << _EOF
|
||||
+Match host x
|
||||
+_EOF
|
||||
+
|
||||
+trial a /aa "included file does not affect match state"
|
||||
+
|
||||
+# Ensure the empty include directive is not accepted
|
||||
+cat > $OBJ/sshd_config.i.x << _EOF
|
||||
+Include
|
||||
+_EOF
|
||||
+
|
||||
+trace "disallow invalid with no argument"
|
||||
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i.x -T \
|
||||
+ -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
|
||||
+ fail "sshd allowed Include with no argument"
|
||||
+
|
||||
+# Ensure the Include before any Match block works as expected (bug #3122)
|
||||
+cat > $OBJ/sshd_config.i << _EOF
|
||||
+Banner /xx
|
||||
+HostKey $OBJ/host.ssh-ed25519
|
||||
+Include $OBJ/sshd_config.i.2
|
||||
+Match host a
|
||||
+ Banner /aaaa
|
||||
+_EOF
|
||||
+cat > $OBJ/sshd_config.i.2 << _EOF
|
||||
+Match host a
|
||||
+ Banner /aa
|
||||
+_EOF
|
||||
+
|
||||
+trace "Include before match blocks"
|
||||
+trial a /aa "included file before match blocks is properly evaluated"
|
||||
+
|
||||
+# Port in included file is correctly interpretted (bug #3169)
|
||||
+cat > $OBJ/sshd_config.i << _EOF
|
||||
+Include $OBJ/sshd_config.i.2
|
||||
+Port 7722
|
||||
+_EOF
|
||||
+cat > $OBJ/sshd_config.i.2 << _EOF
|
||||
+HostKey $OBJ/host.ssh-ed25519
|
||||
+_EOF
|
||||
+
|
||||
+trace "Port after included files"
|
||||
+${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \
|
||||
+ -C "host=x,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out || \
|
||||
+ fail "failed to parse Port after included files"
|
||||
+_port=`grep -i '^port ' $OBJ/sshd_config.out | awk '{print $2}'`
|
||||
+if test "x7722" != "x$_port" ; then
|
||||
+ fail "The Port in included file was intertepretted wrongly. Expected 7722, got $_port"
|
||||
+fi
|
||||
+
|
||||
+# cleanup
|
||||
+rm -f $OBJ/sshd_config.i $OBJ/sshd_config.i.* $OBJ/sshd_config.out
|
||||
diff -up openssh-8.0p1/regress/test-exec.sh.sshdinclude openssh-8.0p1/regress/test-exec.sh
|
||||
--- openssh-8.0p1/regress/test-exec.sh.sshdinclude 2021-10-20 15:18:49.746331150 +0200
|
||||
+++ openssh-8.0p1/regress/test-exec.sh 2021-10-20 15:19:41.324781344 +0200
|
||||
@@ -220,6 +220,7 @@ echo "exec ${SSH} -E${TEST_SSH_LOGFILE}
|
||||
|
||||
chmod a+rx $OBJ/ssh-log-wrapper.sh
|
||||
REAL_SSH="$SSH"
|
||||
+REAL_SSHD="$SSHD"
|
||||
SSH="$SSHLOGWRAP"
|
||||
|
||||
# Some test data. We make a copy because some tests will overwrite it.
|
||||
diff -up openssh-8.0p1/servconf.c.sshdinclude openssh-8.0p1/servconf.c
|
||||
--- openssh-8.0p1/servconf.c.sshdinclude 2021-10-20 15:18:49.748331167 +0200
|
||||
+++ openssh-8.0p1/servconf.c 2021-10-20 15:22:06.303046777 +0200
|
||||
@@ -40,6 +40,11 @@
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
+#ifdef USE_SYSTEM_GLOB
|
||||
+# include <glob.h>
|
||||
+#else
|
||||
+# include "openbsd-compat/glob.h"
|
||||
+#endif
|
||||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
#include "xmalloc.h"
|
||||
@@ -70,6 +75,9 @@ static void add_listen_addr(ServerOption
|
||||
const char *, int);
|
||||
static void add_one_listen_addr(ServerOptions *, const char *,
|
||||
const char *, int);
|
||||
+static void parse_server_config_depth(ServerOptions *options,
|
||||
+ const char *filename, struct sshbuf *conf, struct include_list *includes,
|
||||
+ struct connection_info *connectinfo, int flags, int *activep, int depth);
|
||||
|
||||
/* Use of privilege separation or not */
|
||||
extern int use_privsep;
|
||||
@@ -528,7 +536,7 @@ typedef enum {
|
||||
sAcceptEnv, sSetEnv, sPermitTunnel,
|
||||
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
- sHostCertificate,
|
||||
+ sHostCertificate, sInclude,
|
||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
|
||||
sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
|
||||
@@ -540,9 +548,11 @@ typedef enum {
|
||||
sDeprecated, sIgnore, sUnsupported
|
||||
} ServerOpCodes;
|
||||
|
||||
-#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
|
||||
-#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
|
||||
-#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
|
||||
+#define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */
|
||||
+#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
|
||||
+#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
|
||||
+#define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */
|
||||
+#define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */
|
||||
|
||||
/* Textual representation of the tokens. */
|
||||
static struct {
|
||||
@@ -687,6 +697,7 @@ static struct {
|
||||
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
|
||||
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
|
||||
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
|
||||
+ { "include", sInclude, SSHCFG_ALL },
|
||||
{ "ipqos", sIPQoS, SSHCFG_ALL },
|
||||
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
|
||||
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
|
||||
@@ -1259,13 +1270,14 @@ static const struct multistate multistat
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
-int
|
||||
-process_server_config_line(ServerOptions *options, char *line,
|
||||
+static int
|
||||
+process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
const char *filename, int linenum, int *activep,
|
||||
- struct connection_info *connectinfo)
|
||||
+ struct connection_info *connectinfo, int *inc_flags, int depth,
|
||||
+ struct include_list *includes)
|
||||
{
|
||||
char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
|
||||
- int cmdline = 0, *intptr, value, value2, n, port;
|
||||
+ int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
|
||||
SyslogFacility *log_facility_ptr;
|
||||
LogLevel *log_level_ptr;
|
||||
ServerOpCodes opcode;
|
||||
@@ -1274,6 +1286,8 @@ process_server_config_line(ServerOptions
|
||||
long long val64;
|
||||
const struct multistate *multistate_ptr;
|
||||
const char *errstr;
|
||||
+ struct include_item *item;
|
||||
+ glob_t gbuf;
|
||||
|
||||
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
|
||||
if ((len = strlen(line)) == 0)
|
||||
@@ -1300,7 +1314,7 @@ process_server_config_line(ServerOptions
|
||||
cmdline = 1;
|
||||
activep = &cmdline;
|
||||
}
|
||||
- if (*activep && opcode != sMatch)
|
||||
+ if (*activep && opcode != sMatch && opcode != sInclude)
|
||||
debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
|
||||
if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
|
||||
if (connectinfo == NULL) {
|
||||
@@ -1980,15 +1994,112 @@ process_server_config_line(ServerOptions
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
+ case sInclude:
|
||||
+ if (cmdline) {
|
||||
+ fatal("Include directive not supported as a "
|
||||
+ "command-line option");
|
||||
+ }
|
||||
+ value = 0;
|
||||
+ while ((arg2 = strdelim(&cp)) != NULL && *arg2 != '\0') {
|
||||
+ value++;
|
||||
+ found = 0;
|
||||
+ if (*arg2 != '/' && *arg2 != '~') {
|
||||
+ xasprintf(&arg, "%s/%s", SSHDIR, arg2);
|
||||
+ } else
|
||||
+ arg = xstrdup(arg2);
|
||||
+
|
||||
+ /*
|
||||
+ * Don't let included files clobber the containing
|
||||
+ * file's Match state.
|
||||
+ */
|
||||
+ oactive = *activep;
|
||||
+
|
||||
+ /* consult cache of include files */
|
||||
+ TAILQ_FOREACH(item, includes, entry) {
|
||||
+ if (strcmp(item->selector, arg) != 0)
|
||||
+ continue;
|
||||
+ if (item->filename != NULL) {
|
||||
+ parse_server_config_depth(options,
|
||||
+ item->filename, item->contents,
|
||||
+ includes, connectinfo,
|
||||
+ (*inc_flags & SSHCFG_MATCH_ONLY
|
||||
+ ? SSHCFG_MATCH_ONLY : (oactive
|
||||
+ ? 0 : SSHCFG_NEVERMATCH)),
|
||||
+ activep, depth + 1);
|
||||
+ }
|
||||
+ found = 1;
|
||||
+ *activep = oactive;
|
||||
+ }
|
||||
+ if (found != 0) {
|
||||
+ free(arg);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* requested glob was not in cache */
|
||||
+ debug2("%s line %d: new include %s",
|
||||
+ filename, linenum, arg);
|
||||
+ if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
|
||||
+ if (r != GLOB_NOMATCH) {
|
||||
+ fatal("%s line %d: include \"%s\" "
|
||||
+ "glob failed", filename,
|
||||
+ linenum, arg);
|
||||
+ }
|
||||
+ /*
|
||||
+ * If no entry matched then record a
|
||||
+ * placeholder to skip later glob calls.
|
||||
+ */
|
||||
+ debug2("%s line %d: no match for %s",
|
||||
+ filename, linenum, arg);
|
||||
+ item = xcalloc(1, sizeof(*item));
|
||||
+ item->selector = strdup(arg);
|
||||
+ TAILQ_INSERT_TAIL(includes,
|
||||
+ item, entry);
|
||||
+ }
|
||||
+ if (gbuf.gl_pathc > INT_MAX)
|
||||
+ fatal("%s: too many glob results", __func__);
|
||||
+ for (n = 0; n < (int)gbuf.gl_pathc; n++) {
|
||||
+ debug2("%s line %d: including %s",
|
||||
+ filename, linenum, gbuf.gl_pathv[n]);
|
||||
+ item = xcalloc(1, sizeof(*item));
|
||||
+ item->selector = strdup(arg);
|
||||
+ item->filename = strdup(gbuf.gl_pathv[n]);
|
||||
+ if ((item->contents = sshbuf_new()) == NULL) {
|
||||
+ fatal("%s: sshbuf_new failed",
|
||||
+ __func__);
|
||||
+ }
|
||||
+ load_server_config(item->filename,
|
||||
+ item->contents);
|
||||
+ parse_server_config_depth(options,
|
||||
+ item->filename, item->contents,
|
||||
+ includes, connectinfo,
|
||||
+ (*inc_flags & SSHCFG_MATCH_ONLY
|
||||
+ ? SSHCFG_MATCH_ONLY : (oactive
|
||||
+ ? 0 : SSHCFG_NEVERMATCH)),
|
||||
+ activep, depth + 1);
|
||||
+ *activep = oactive;
|
||||
+ TAILQ_INSERT_TAIL(includes, item, entry);
|
||||
+ }
|
||||
+ globfree(&gbuf);
|
||||
+ free(arg);
|
||||
+ }
|
||||
+ if (value == 0) {
|
||||
+ fatal("%s line %d: Include missing filename argument",
|
||||
+ filename, linenum);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
case sMatch:
|
||||
if (cmdline)
|
||||
fatal("Match directive not supported as a command-line "
|
||||
"option");
|
||||
- value = match_cfg_line(&cp, linenum, connectinfo);
|
||||
+ value = match_cfg_line(&cp, linenum,
|
||||
+ (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
|
||||
if (value < 0)
|
||||
fatal("%s line %d: Bad Match condition", filename,
|
||||
linenum);
|
||||
- *activep = value;
|
||||
+ *activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
|
||||
+ /* The MATCH_ONLY is applicable only until the first match block */
|
||||
+ *inc_flags &= ~SSHCFG_MATCH_ONLY;
|
||||
break;
|
||||
|
||||
case sKerberosUseKuserok:
|
||||
@@ -2275,6 +2386,18 @@ process_server_config_line(ServerOptions
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int
|
||||
+process_server_config_line(ServerOptions *options, char *line,
|
||||
+ const char *filename, int linenum, int *activep,
|
||||
+ struct connection_info *connectinfo, struct include_list *includes)
|
||||
+{
|
||||
+ int inc_flags = 0;
|
||||
+
|
||||
+ return process_server_config_line_depth(options, line, filename,
|
||||
+ linenum, activep, connectinfo, &inc_flags, 0, includes);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Reads the server configuration file. */
|
||||
|
||||
void
|
||||
@@ -2313,12 +2436,13 @@ load_server_config(const char *filename,
|
||||
|
||||
void
|
||||
parse_server_match_config(ServerOptions *options,
|
||||
- struct connection_info *connectinfo)
|
||||
+ struct include_list *includes, struct connection_info *connectinfo)
|
||||
{
|
||||
ServerOptions mo;
|
||||
|
||||
initialize_server_options(&mo);
|
||||
- parse_server_config(&mo, "reprocess config", cfg, connectinfo);
|
||||
+ parse_server_config(&mo, "reprocess config", cfg, includes,
|
||||
+ connectinfo);
|
||||
copy_set_server_options(options, &mo, 0);
|
||||
}
|
||||
|
||||
@@ -2464,28 +2588,44 @@ copy_set_server_options(ServerOptions *d
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
|
||||
-void
|
||||
-parse_server_config(ServerOptions *options, const char *filename,
|
||||
- struct sshbuf *conf, struct connection_info *connectinfo)
|
||||
+#define SERVCONF_MAX_DEPTH 16
|
||||
+static void
|
||||
+parse_server_config_depth(ServerOptions *options, const char *filename,
|
||||
+ struct sshbuf *conf, struct include_list *includes,
|
||||
+ struct connection_info *connectinfo, int flags, int *activep, int depth)
|
||||
{
|
||||
- int active, linenum, bad_options = 0;
|
||||
+ int linenum, bad_options = 0;
|
||||
char *cp, *obuf, *cbuf;
|
||||
|
||||
- debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
|
||||
+ if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
|
||||
+ fatal("Too many recursive configuration includes");
|
||||
+
|
||||
+ debug2("%s: config %s len %zu%s", __func__, filename, sshbuf_len(conf),
|
||||
+ (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
|
||||
|
||||
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
|
||||
fatal("%s: sshbuf_dup_string failed", __func__);
|
||||
- active = connectinfo ? 0 : 1;
|
||||
linenum = 1;
|
||||
while ((cp = strsep(&cbuf, "\n")) != NULL) {
|
||||
- if (process_server_config_line(options, cp, filename,
|
||||
- linenum++, &active, connectinfo) != 0)
|
||||
+ if (process_server_config_line_depth(options, cp,
|
||||
+ filename, linenum++, activep, connectinfo, &flags,
|
||||
+ depth, includes) != 0)
|
||||
bad_options++;
|
||||
}
|
||||
free(obuf);
|
||||
if (bad_options > 0)
|
||||
fatal("%s: terminating, %d bad configuration options",
|
||||
filename, bad_options);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+parse_server_config(ServerOptions *options, const char *filename,
|
||||
+ struct sshbuf *conf, struct include_list *includes,
|
||||
+ struct connection_info *connectinfo)
|
||||
+{
|
||||
+ int active = connectinfo ? 0 : 1;
|
||||
+ parse_server_config_depth(options, filename, conf, includes,
|
||||
+ connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
|
||||
process_queued_listen_addrs(options);
|
||||
}
|
||||
|
||||
diff -up openssh-8.0p1/servconf.h.sshdinclude openssh-8.0p1/servconf.h
|
||||
--- openssh-8.0p1/servconf.h.sshdinclude 2021-10-20 15:18:49.750331185 +0200
|
||||
+++ openssh-8.0p1/servconf.h 2021-10-20 15:19:41.325781353 +0200
|
||||
@@ -16,6 +16,8 @@
|
||||
#ifndef SERVCONF_H
|
||||
#define SERVCONF_H
|
||||
|
||||
+#include <sys/queue.h>
|
||||
+
|
||||
#define MAX_PORTS 256 /* Max # ports. */
|
||||
|
||||
#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
|
||||
@@ -234,6 +236,15 @@ struct connection_info {
|
||||
* unspecified */
|
||||
};
|
||||
|
||||
+/* List of included files for re-exec from the parsed configuration */
|
||||
+struct include_item {
|
||||
+ char *selector;
|
||||
+ char *filename;
|
||||
+ struct sshbuf *contents;
|
||||
+ TAILQ_ENTRY(include_item) entry;
|
||||
+};
|
||||
+TAILQ_HEAD(include_list, include_item);
|
||||
+
|
||||
|
||||
/*
|
||||
* These are string config options that must be copied between the
|
||||
@@ -273,12 +284,13 @@ struct connection_info *get_connection_i
|
||||
void initialize_server_options(ServerOptions *);
|
||||
void fill_default_server_options(ServerOptions *);
|
||||
int process_server_config_line(ServerOptions *, char *, const char *, int,
|
||||
- int *, struct connection_info *);
|
||||
+ int *, struct connection_info *, struct include_list *includes);
|
||||
void process_permitopen(struct ssh *ssh, ServerOptions *options);
|
||||
void load_server_config(const char *, struct sshbuf *);
|
||||
void parse_server_config(ServerOptions *, const char *, struct sshbuf *,
|
||||
- struct connection_info *);
|
||||
-void parse_server_match_config(ServerOptions *, struct connection_info *);
|
||||
+ struct include_list *includes, struct connection_info *);
|
||||
+void parse_server_match_config(ServerOptions *,
|
||||
+ struct include_list *includes, struct connection_info *);
|
||||
int parse_server_match_testspec(struct connection_info *, char *);
|
||||
int server_match_spec_complete(struct connection_info *);
|
||||
void copy_set_server_options(ServerOptions *, ServerOptions *, int);
|
||||
diff -up openssh-8.0p1/sshd_config.5.sshdinclude openssh-8.0p1/sshd_config.5
|
||||
--- openssh-8.0p1/sshd_config.5.sshdinclude 2021-10-20 15:18:49.754331220 +0200
|
||||
+++ openssh-8.0p1/sshd_config.5 2021-10-20 15:19:41.325781353 +0200
|
||||
@@ -825,7 +825,20 @@ during
|
||||
and use only the system-wide known hosts file
|
||||
.Pa /etc/ssh/known_hosts .
|
||||
The default is
|
||||
-.Cm no .
|
||||
+.Dq no .
|
||||
+.It Cm Include
|
||||
+Include the specified configuration file(s).
|
||||
+Multiple path names may be specified and each pathname may contain
|
||||
+.Xr glob 7
|
||||
+wildcards.
|
||||
+Files without absolute paths are assumed to be in
|
||||
+.Pa /etc/ssh .
|
||||
+A
|
||||
+.Cm Include
|
||||
+directive may appear inside a
|
||||
+.Cm Match
|
||||
+block
|
||||
+to perform conditional inclusion.
|
||||
.It Cm IPQoS
|
||||
Specifies the IPv4 type-of-service or DSCP class for the connection.
|
||||
Accepted values are
|
||||
diff -up openssh-8.0p1/sshd.c.sshdinclude openssh-8.0p1/sshd.c
|
||||
--- openssh-8.0p1/sshd.c.sshdinclude 2021-10-20 15:18:49.752331202 +0200
|
||||
+++ openssh-8.0p1/sshd.c 2021-10-20 15:19:41.325781353 +0200
|
||||
@@ -257,6 +257,9 @@ struct sshauthopt *auth_opts = NULL;
|
||||
/* sshd_config buffer */
|
||||
struct sshbuf *cfg;
|
||||
|
||||
+/* Included files from the configuration file */
|
||||
+struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
|
||||
+
|
||||
/* message to be displayed after login */
|
||||
struct sshbuf *loginmsg;
|
||||
|
||||
@@ -927,30 +930,45 @@ usage(void)
|
||||
static void
|
||||
send_rexec_state(int fd, struct sshbuf *conf)
|
||||
{
|
||||
- struct sshbuf *m;
|
||||
+ struct sshbuf *m = NULL, *inc = NULL;
|
||||
+ struct include_item *item = NULL;
|
||||
int r;
|
||||
|
||||
debug3("%s: entering fd = %d config len %zu", __func__, fd,
|
||||
sshbuf_len(conf));
|
||||
|
||||
+ if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
|
||||
+ fatal("%s: sshbuf_new failed", __func__);
|
||||
+
|
||||
+ /* pack includes into a string */
|
||||
+ TAILQ_FOREACH(item, &includes, entry) {
|
||||
+ if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 ||
|
||||
+ (r = sshbuf_put_cstring(inc, item->filename)) != 0 ||
|
||||
+ (r = sshbuf_put_stringb(inc, item->contents)) != 0)
|
||||
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Protocol from reexec master to child:
|
||||
* string configuration
|
||||
- * string rngseed (only if OpenSSL is not self-seeded)
|
||||
+ * string included_files[] {
|
||||
+ * string selector
|
||||
+ * string filename
|
||||
+ * string contents
|
||||
+ * }
|
||||
+ * string rng_seed (if required)
|
||||
*/
|
||||
- if ((m = sshbuf_new()) == NULL)
|
||||
- fatal("%s: sshbuf_new failed", __func__);
|
||||
- if ((r = sshbuf_put_stringb(m, conf)) != 0)
|
||||
+ if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
|
||||
+ (r = sshbuf_put_stringb(m, inc)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
-
|
||||
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
|
||||
rexec_send_rng_seed(m);
|
||||
#endif
|
||||
-
|
||||
if (ssh_msg_send(fd, 0, m) == -1)
|
||||
fatal("%s: ssh_msg_send failed", __func__);
|
||||
|
||||
sshbuf_free(m);
|
||||
+ sshbuf_free(inc);
|
||||
|
||||
debug3("%s: done", __func__);
|
||||
}
|
||||
@@ -958,14 +976,15 @@ send_rexec_state(int fd, struct sshbuf *
|
||||
static void
|
||||
recv_rexec_state(int fd, struct sshbuf *conf)
|
||||
{
|
||||
- struct sshbuf *m;
|
||||
+ struct sshbuf *m, *inc;
|
||||
u_char *cp, ver;
|
||||
size_t len;
|
||||
int r;
|
||||
+ struct include_item *item;
|
||||
|
||||
debug3("%s: entering fd = %d", __func__, fd);
|
||||
|
||||
- if ((m = sshbuf_new()) == NULL)
|
||||
+ if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if (ssh_msg_recv(fd, m) == -1)
|
||||
fatal("%s: ssh_msg_recv failed", __func__);
|
||||
@@ -973,14 +992,28 @@ recv_rexec_state(int fd, struct sshbuf *
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if (ver != 0)
|
||||
fatal("%s: rexec version mismatch", __func__);
|
||||
- if ((r = sshbuf_get_string(m, &cp, &len)) != 0)
|
||||
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
- if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
|
||||
+ if ((r = sshbuf_get_string(m, &cp, &len)) != 0 ||
|
||||
+ (r = sshbuf_get_stringb(m, inc)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
+
|
||||
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
|
||||
rexec_recv_rng_seed(m);
|
||||
#endif
|
||||
|
||||
+ if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
|
||||
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
+
|
||||
+ while (sshbuf_len(inc) != 0) {
|
||||
+ item = xcalloc(1, sizeof(*item));
|
||||
+ if ((item->contents = sshbuf_new()) == NULL)
|
||||
+ fatal("%s: sshbuf_new failed", __func__);
|
||||
+ if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 ||
|
||||
+ (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 ||
|
||||
+ (r = sshbuf_get_stringb(inc, item->contents)) != 0)
|
||||
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
+ TAILQ_INSERT_TAIL(&includes, item, entry);
|
||||
+ }
|
||||
+
|
||||
free(cp);
|
||||
sshbuf_free(m);
|
||||
|
||||
@@ -1661,7 +1694,7 @@ main(int ac, char **av)
|
||||
case 'o':
|
||||
line = xstrdup(optarg);
|
||||
if (process_server_config_line(&options, line,
|
||||
- "command-line", 0, NULL, NULL) != 0)
|
||||
+ "command-line", 0, NULL, NULL, &includes) != 0)
|
||||
exit(1);
|
||||
free(line);
|
||||
break;
|
||||
@@ -1692,7 +1725,7 @@ main(int ac, char **av)
|
||||
SYSLOG_LEVEL_INFO : options.log_level,
|
||||
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
|
||||
SYSLOG_FACILITY_AUTH : options.log_facility,
|
||||
- log_stderr || !inetd_flag);
|
||||
+ log_stderr || !inetd_flag || debug_flag);
|
||||
|
||||
/*
|
||||
* Unset KRB5CCNAME, otherwise the user's session may inherit it from
|
||||
@@ -1725,12 +1758,11 @@ main(int ac, char **av)
|
||||
*/
|
||||
(void)atomicio(vwrite, startup_pipe, "\0", 1);
|
||||
}
|
||||
- }
|
||||
- else if (strcasecmp(config_file_name, "none") != 0)
|
||||
+ } else if (strcasecmp(config_file_name, "none") != 0)
|
||||
load_server_config(config_file_name, cfg);
|
||||
|
||||
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
|
||||
- cfg, NULL);
|
||||
+ cfg, &includes, NULL);
|
||||
|
||||
/* 'UsePAM no' is not supported in RHEL */
|
||||
if (! options.use_pam)
|
||||
@@ -1946,7 +1978,7 @@ main(int ac, char **av)
|
||||
if (connection_info == NULL)
|
||||
connection_info = get_connection_info(ssh, 0, 0);
|
||||
connection_info->test = 1;
|
||||
- parse_server_match_config(&options, connection_info);
|
||||
+ parse_server_match_config(&options, &includes, connection_info);
|
||||
dump_config(&options);
|
||||
}
|
||||
|
||||
diff -up openssh-8.0p1/sshbuf-getput-basic.c.stringb openssh-8.0p1/sshbuf-getput-basic.c
|
||||
--- openssh-8.0p1/sshbuf-getput-basic.c.stringb 2022-12-21 12:18:43.274799163 +0100
|
||||
+++ openssh-8.0p1/sshbuf-getput-basic.c 2022-12-21 12:19:19.758081516 +0100
|
||||
@@ -371,6 +371,9 @@ sshbuf_put_cstring(struct sshbuf *buf, c
|
||||
int
|
||||
sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v)
|
||||
{
|
||||
+ if (v == NULL)
|
||||
+ return sshbuf_put_string(buf, NULL, 0);
|
||||
+
|
||||
return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v));
|
||||
}
|
||||
|
||||
38
openssh-8.0p1-upstream-ignore-SIGPIPE.patch
Normal file
38
openssh-8.0p1-upstream-ignore-SIGPIPE.patch
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
From d33ff14309e33aa79fdf95e1bc4facafa80b90a9 Mon Sep 17 00:00:00 2001
|
||||
From: Stepan Broz <sbroz@redhat.com>
|
||||
Date: Tue, 25 Jun 2024 17:38:22 +0200
|
||||
Subject: [PATCH] upstream: ignore SIGPIPE earlier in main(), specifically
|
||||
before
|
||||
|
||||
muxclient() which performs operations that could cause one; Reported by Noam
|
||||
Lewis via bz3454, ok dtucker@
|
||||
|
||||
OpenBSD-Commit-ID: 63d8e13276869eebac6d7a05d5a96307f9026e47
|
||||
---
|
||||
ssh.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ssh.c b/ssh.c
|
||||
index 786e26d..e037c66 100644
|
||||
--- a/ssh.c
|
||||
+++ b/ssh.c
|
||||
@@ -1115,6 +1115,8 @@ main(int ac, char **av)
|
||||
}
|
||||
}
|
||||
|
||||
+ signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
|
||||
+
|
||||
/*
|
||||
* Initialize "log" output. Since we are the client all output
|
||||
* goes to stderr unless otherwise specified by -y or -E.
|
||||
@@ -1545,7 +1547,6 @@ main(int ac, char **av)
|
||||
options.num_system_hostfiles);
|
||||
tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
|
||||
|
||||
- signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
|
||||
signal(SIGCHLD, main_sigchld_handler);
|
||||
|
||||
/* Log into the remote system. Never returns if the login fails. */
|
||||
--
|
||||
2.45.2
|
||||
|
||||
30
openssh-8.0p1-x11-without-ipv6.patch
Normal file
30
openssh-8.0p1-x11-without-ipv6.patch
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
diff --git a/channels.c b/channels.c
|
||||
--- a/channels.c
|
||||
+++ b/channels.c
|
||||
@@ -3933,16 +3933,26 @@ x11_create_display_inet(int x11_display_
|
||||
if (ai->ai_family == AF_INET6)
|
||||
sock_set_v6only(sock);
|
||||
if (x11_use_localhost)
|
||||
set_reuseaddr(sock);
|
||||
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
debug2("%s: bind port %d: %.100s", __func__,
|
||||
port, strerror(errno));
|
||||
close(sock);
|
||||
+
|
||||
+ /* do not remove successfully opened
|
||||
+ * sockets if the request failed because
|
||||
+ * the protocol IPv4/6 is not available
|
||||
+ * (e.g. IPv6 may be disabled while being
|
||||
+ * supported)
|
||||
+ */
|
||||
+ if (EADDRNOTAVAIL == errno)
|
||||
+ continue;
|
||||
+
|
||||
for (n = 0; n < num_socks; n++)
|
||||
close(socks[n]);
|
||||
num_socks = 0;
|
||||
break;
|
||||
}
|
||||
socks[num_socks++] = sock;
|
||||
if (num_socks == NUM_SOCKS)
|
||||
break;
|
||||
166
openssh-8.7p1-minimize-sha1-use.patch
Normal file
166
openssh-8.7p1-minimize-sha1-use.patch
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
diff --color -ru a/kex.c b/kex.c
|
||||
--- a/kex.c 2022-06-23 10:25:29.529922670 +0200
|
||||
+++ b/kex.c 2022-06-23 10:26:12.911762100 +0200
|
||||
@@ -906,6 +906,18 @@
|
||||
return (1);
|
||||
}
|
||||
|
||||
+/* returns non-zero if proposal contains any algorithm from algs */
|
||||
+static int
|
||||
+has_any_alg(const char *proposal, const char *algs)
|
||||
+{
|
||||
+ char *cp;
|
||||
+
|
||||
+ if ((cp = match_list(proposal, algs, NULL)) == NULL)
|
||||
+ return 0;
|
||||
+ free(cp);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
kex_choose_conf(struct ssh *ssh)
|
||||
{
|
||||
@@ -941,6 +953,16 @@
|
||||
free(ext);
|
||||
}
|
||||
|
||||
+ /* Check whether client supports rsa-sha2 algorithms */
|
||||
+ if (kex->server && (kex->flags & KEX_INITIAL)) {
|
||||
+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
+ "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com"))
|
||||
+ kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
|
||||
+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
+ "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com"))
|
||||
+ kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
|
||||
+ }
|
||||
+
|
||||
/* Algorithm Negotiation */
|
||||
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
|
||||
sprop[PROPOSAL_KEX_ALGS])) != 0) {
|
||||
diff --color -ru a/kex.h b/kex.h
|
||||
--- a/kex.h 2022-06-23 10:25:29.511922322 +0200
|
||||
+++ b/kex.h 2022-06-23 10:26:12.902761926 +0200
|
||||
@@ -117,6 +117,8 @@
|
||||
|
||||
#define KEX_INIT_SENT 0x0001
|
||||
#define KEX_INITIAL 0x0002
|
||||
+#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */
|
||||
+#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */
|
||||
|
||||
struct sshenc {
|
||||
char *name;
|
||||
diff --color -ru a/serverloop.c b/serverloop.c
|
||||
--- a/serverloop.c 2022-06-23 10:25:29.537922825 +0200
|
||||
+++ b/serverloop.c 2022-06-23 10:26:12.918762235 +0200
|
||||
@@ -736,16 +736,17 @@
|
||||
struct sshbuf *resp = NULL;
|
||||
struct sshbuf *sigbuf = NULL;
|
||||
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
|
||||
- int r, ndx, kexsigtype, use_kexsigtype, success = 0;
|
||||
+ int r, ndx, success = 0;
|
||||
const u_char *blob;
|
||||
+ const char *sigalg, *kex_rsa_sigalg = NULL;
|
||||
u_char *sig = 0;
|
||||
size_t blen, slen;
|
||||
|
||||
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new", __func__);
|
||||
-
|
||||
- kexsigtype = sshkey_type_plain(
|
||||
- sshkey_type_from_name(ssh->kex->hostkey_alg));
|
||||
+ if (sshkey_type_plain(sshkey_type_from_name(
|
||||
+ ssh->kex->hostkey_alg)) == KEY_RSA)
|
||||
+ kex_rsa_sigalg = ssh->kex->hostkey_alg;
|
||||
while (ssh_packet_remaining(ssh) > 0) {
|
||||
sshkey_free(key);
|
||||
key = NULL;
|
||||
@@ -780,16 +781,24 @@
|
||||
* For RSA keys, prefer to use the signature type negotiated
|
||||
* during KEX to the default (SHA1).
|
||||
*/
|
||||
- use_kexsigtype = kexsigtype == KEY_RSA &&
|
||||
- sshkey_type_plain(key->type) == KEY_RSA;
|
||||
+ sigalg = NULL;
|
||||
+ if (sshkey_type_plain(key->type) == KEY_RSA) {
|
||||
+ if (kex_rsa_sigalg != NULL)
|
||||
+ sigalg = kex_rsa_sigalg;
|
||||
+ else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED)
|
||||
+ sigalg = "rsa-sha2-512";
|
||||
+ else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
|
||||
+ sigalg = "rsa-sha2-256";
|
||||
+ }
|
||||
+ debug3("%s: sign %s key (index %d) using sigalg %s", __func__,
|
||||
+ sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
|
||||
if ((r = sshbuf_put_cstring(sigbuf,
|
||||
"hostkeys-prove-00@openssh.com")) != 0 ||
|
||||
(r = sshbuf_put_string(sigbuf,
|
||||
ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
|
||||
(r = sshkey_puts(key, sigbuf)) != 0 ||
|
||||
(r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
|
||||
- sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
|
||||
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
|
||||
+ sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
|
||||
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
|
||||
error("%s: couldn't prepare signature: %s",
|
||||
__func__, ssh_err(r));
|
||||
diff --color -ru a/sshkey.c b/sshkey.c
|
||||
--- a/sshkey.c 2022-06-23 10:25:29.532922728 +0200
|
||||
+++ b/sshkey.c 2022-06-23 10:26:12.914762158 +0200
|
||||
@@ -82,7 +82,6 @@
|
||||
struct sshbuf *buf, enum sshkey_serialize_rep);
|
||||
static int sshkey_from_blob_internal(struct sshbuf *buf,
|
||||
struct sshkey **keyp, int allow_cert);
|
||||
-static int get_sigtype(const u_char *sig, size_t siglen, char **sigtypep);
|
||||
|
||||
/* Supported key types */
|
||||
struct keytype {
|
||||
@@ -2092,7 +2091,8 @@
|
||||
if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
|
||||
sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
|
||||
goto out;
|
||||
- if ((ret = get_sigtype(sig, slen, &key->cert->signature_type)) != 0)
|
||||
+ if ((ret = sshkey_get_sigtype(sig, slen,
|
||||
+ &key->cert->signature_type)) != 0)
|
||||
goto out;
|
||||
|
||||
/* Success */
|
||||
@@ -2394,8 +2394,8 @@
|
||||
return r;
|
||||
}
|
||||
|
||||
-static int
|
||||
-get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
|
||||
+int
|
||||
+sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
|
||||
{
|
||||
int r;
|
||||
struct sshbuf *b = NULL;
|
||||
@@ -2477,7 +2477,7 @@
|
||||
return 0;
|
||||
if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
- if ((r = get_sigtype(sig, siglen, &sigtype)) != 0)
|
||||
+ if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
|
||||
return r;
|
||||
r = strcmp(expected_alg, sigtype) == 0;
|
||||
free(sigtype);
|
||||
@@ -2739,7 +2739,7 @@
|
||||
sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
|
||||
goto out;
|
||||
/* Check and update signature_type against what was actually used */
|
||||
- if ((ret = get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
|
||||
+ if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
|
||||
goto out;
|
||||
if (alg != NULL && strcmp(alg, sigtype) != 0) {
|
||||
ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
|
||||
diff --color -ru a/sshkey.h b/sshkey.h
|
||||
--- a/sshkey.h 2022-06-23 10:25:29.521922515 +0200
|
||||
+++ b/sshkey.h 2022-06-23 10:26:12.907762022 +0200
|
||||
@@ -211,6 +211,7 @@
|
||||
const u_char *, size_t, const char *, u_int);
|
||||
int sshkey_check_sigtype(const u_char *, size_t, const char *);
|
||||
const char *sshkey_sigalg_by_name(const char *);
|
||||
+int sshkey_get_sigtype(const u_char *, size_t, char **);
|
||||
|
||||
/* for debug */
|
||||
void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
|
||||
46
openssh-8.7p1-scp-kill-switch.patch
Normal file
46
openssh-8.7p1-scp-kill-switch.patch
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
diff -up openssh-8.7p1/pathnames.h.kill-scp openssh-8.7p1/pathnames.h
|
||||
--- openssh-8.7p1/pathnames.h.kill-scp 2021-09-16 11:37:57.240171687 +0200
|
||||
+++ openssh-8.7p1/pathnames.h 2021-09-16 11:42:29.183427917 +0200
|
||||
@@ -42,6 +42,7 @@
|
||||
#define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key"
|
||||
#define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key"
|
||||
#define _PATH_DH_MODULI SSHDIR "/moduli"
|
||||
+#define _PATH_SCP_KILL_SWITCH SSHDIR "/disable_scp"
|
||||
|
||||
#ifndef _PATH_SSH_PROGRAM
|
||||
#define _PATH_SSH_PROGRAM "/usr/bin/ssh"
|
||||
diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1
|
||||
--- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200
|
||||
+++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200
|
||||
@@ -278,6 +278,13 @@ to print debugging messages about their
|
||||
This is helpful in
|
||||
debugging connection, authentication, and configuration problems.
|
||||
.El
|
||||
+.Pp
|
||||
+Usage of SCP protocol can be blocked by creating a world-readable
|
||||
+.Ar /etc/ssh/disable_scp
|
||||
+file. If this file exists, when SCP protocol is in use (either remotely or
|
||||
+via the
|
||||
+.Fl O
|
||||
+option), the program will exit.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std scp
|
||||
.Sh SEE ALSO
|
||||
diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c
|
||||
--- openssh-8.7p1/scp.c.kill-scp 2021-09-16 11:42:56.013650519 +0200
|
||||
+++ openssh-8.7p1/scp.c 2021-09-16 11:53:03.249713836 +0200
|
||||
@@ -596,6 +596,14 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
+ {
|
||||
+ FILE *f = fopen(_PATH_SCP_KILL_SWITCH, "r");
|
||||
+ if (f != NULL) {
|
||||
+ fclose(f);
|
||||
+ fatal("SCP protocol is forbidden via %s", _PATH_SCP_KILL_SWITCH);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if ((pwd = getpwuid(userid = getuid())) == NULL)
|
||||
fatal("unknown user %u", (u_int) userid);
|
||||
|
||||
25
openssh-8.7p1-upstream-cve-2021-41617.patch
Normal file
25
openssh-8.7p1-upstream-cve-2021-41617.patch
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
diff --git a/auth.c b/auth.c
|
||||
index b8d1040d..0134d694 100644
|
||||
--- a/auth.c
|
||||
+++ b/auth.c
|
||||
@@ -56,6 +56,7 @@
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
+#include <grp.h>
|
||||
#ifdef HAVE_LOGIN_H
|
||||
#include <login.h>
|
||||
#endif
|
||||
@@ -2695,6 +2696,12 @@ subprocess(const char *tag, const char *command,
|
||||
}
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
+ if (geteuid() == 0 &&
|
||||
+ initgroups(pw->pw_name, pw->pw_gid) == -1) {
|
||||
+ error("%s: initgroups(%s, %u): %s", tag,
|
||||
+ pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
|
||||
+ _exit(1);
|
||||
+ }
|
||||
/* Don't use permanently_set_uid() here to avoid fatal() */
|
||||
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
|
||||
error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,
|
||||
32
openssh-9.1p1-sshbanner.patch
Normal file
32
openssh-9.1p1-sshbanner.patch
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
|
||||
index d29a03b4..d7283136 100644
|
||||
--- a/ssh-keyscan.c
|
||||
+++ b/ssh-keyscan.c
|
||||
@@ -490,6 +490,15 @@ congreet(int s)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Read the server banner as per RFC4253 section 4.2. The "SSH-"
|
||||
+ * protocol identification string may be preceeded by an arbitarily
|
||||
+ * large banner which we must read and ignore. Loop while reading
|
||||
+ * newline-terminated lines until we have one starting with "SSH-".
|
||||
+ * The ID string cannot be longer than 255 characters although the
|
||||
+ * preceeding banner lines may (in which case they'll be discarded
|
||||
+ * in multiple iterations of the outer loop).
|
||||
+ */
|
||||
for (;;) {
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
bufsiz = sizeof(buf);
|
||||
@@ -517,6 +526,11 @@ congreet(int s)
|
||||
conrecycle(s);
|
||||
return;
|
||||
}
|
||||
+ if (cp >= buf + sizeof(buf)) {
|
||||
+ error("%s: greeting exceeds allowable length", c->c_name);
|
||||
+ confree(s);
|
||||
+ return;
|
||||
+ }
|
||||
if (*cp != '\n' && *cp != '\r') {
|
||||
error("%s: bad greeting", c->c_name);
|
||||
confree(s);
|
||||
17
openssh-9.3p1-upstream-cve-2023-38408.patch
Normal file
17
openssh-9.3p1-upstream-cve-2023-38408.patch
Normal file
|
|
@ -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_module, dlerror());
|
||||
goto fail;
|
||||
}
|
||||
- if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) {
|
||||
- error("dlsym(C_GetFunctionList) failed: %s", dlerror());
|
||||
- goto fail;
|
||||
- }
|
||||
+ if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL)
|
||||
+ fatal("dlsym(C_GetFunctionList) failed: %s", dlerror());
|
||||
|
||||
p->module->handle = handle;
|
||||
/* setup the pkcs11 callbacks */
|
||||
33
openssh-9.4p2-limit-delay.patch
Normal file
33
openssh-9.4p2-limit-delay.patch
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
diff -u -p -r1.166 auth2.c
|
||||
--- a/auth2.c 8 Mar 2023 04:43:12 -0000 1.166
|
||||
+++ b/auth2.c 28 Aug 2023 08:32:44 -0000
|
||||
@@ -208,6 +208,7 @@ input_service_request(int type, u_int32_
|
||||
}
|
||||
|
||||
#define MIN_FAIL_DELAY_SECONDS 0.005
|
||||
+#define MAX_FAIL_DELAY_SECONDS 5.0
|
||||
static double
|
||||
user_specific_delay(const char *user)
|
||||
{
|
||||
@@ -233,6 +234,12 @@ ensure_minimum_time_since(double start,
|
||||
struct timespec ts;
|
||||
double elapsed = monotime_double() - start, req = seconds, remain;
|
||||
|
||||
+ if (elapsed > MAX_FAIL_DELAY_SECONDS) {
|
||||
+ debug3("elapsed %0.3lfms exceeded the max delay "
|
||||
+ "requested %0.3lfms)", elapsed*1000, req*1000);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* if we've already passed the requested time, scale up */
|
||||
while ((remain = seconds - elapsed) < 0.0)
|
||||
seconds *= 2;
|
||||
@@ -317,7 +324,7 @@ input_userauth_request(int type, u_int32
|
||||
debug2("input_userauth_request: try method %s", method);
|
||||
authenticated = m->userauth(ssh);
|
||||
}
|
||||
- if (!authctxt->authenticated)
|
||||
+ if (!authctxt->authenticated && strcmp(method, "none") != 0)
|
||||
ensure_minimum_time_since(tstart,
|
||||
user_specific_delay(authctxt->user));
|
||||
userauth_finish(ssh, authenticated, method, NULL);
|
||||
447
openssh-9.6p1-CVE-2023-48795.patch
Normal file
447
openssh-9.6p1-CVE-2023-48795.patch
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
diff --git a/PROTOCOL b/PROTOCOL
|
||||
index d453c779..ded935eb 100644
|
||||
--- a/PROTOCOL
|
||||
+++ b/PROTOCOL
|
||||
@@ -137,6 +137,32 @@ than as a named global or channel request to allow pings with very
|
||||
described at:
|
||||
http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519
|
||||
|
||||
+1.9 transport: strict key exchange extension
|
||||
+
|
||||
+OpenSSH supports a number of transport-layer hardening measures under
|
||||
+a "strict KEX" feature. This feature is signalled similarly to the
|
||||
+RFC8308 ext-info feature: by including a additional algorithm in the
|
||||
+initiial SSH2_MSG_KEXINIT kex_algorithms field. The client may append
|
||||
+"kex-strict-c-v00@openssh.com" to its kex_algorithms and the server
|
||||
+may append "kex-strict-s-v00@openssh.com". These pseudo-algorithms
|
||||
+are only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored
|
||||
+if they are present in subsequent SSH2_MSG_KEXINIT packets.
|
||||
+
|
||||
+When an endpoint that supports this extension observes this algorithm
|
||||
+name in a peer's KEXINIT packet, it MUST make the following changes to
|
||||
+the the protocol:
|
||||
+
|
||||
+a) During initial KEX, terminate the connection if any unexpected or
|
||||
+ out-of-sequence packet is received. This includes terminating the
|
||||
+ connection if the first packet received is not SSH2_MSG_KEXINIT.
|
||||
+ Unexpected packets for the purpose of strict KEX include messages
|
||||
+ that are otherwise valid at any time during the connection such as
|
||||
+ SSH2_MSG_DEBUG and SSH2_MSG_IGNORE.
|
||||
+b) After sending or receiving a SSH2_MSG_NEWKEYS message, reset the
|
||||
+ packet sequence number to zero. This behaviour persists for the
|
||||
+ duration of the connection (i.e. not just the first
|
||||
+ SSH2_MSG_NEWKEYS).
|
||||
+
|
||||
2. Connection protocol changes
|
||||
|
||||
2.1. connection: Channel write close extension "eow@openssh.com"
|
||||
diff --git a/kex.c b/kex.c
|
||||
index aa5e792d..d478ff6e 100644
|
||||
--- a/kex.c
|
||||
+++ b/kex.c
|
||||
@@ -65,7 +65,7 @@
|
||||
#endif
|
||||
|
||||
/* prototype */
|
||||
-static int kex_choose_conf(struct ssh *);
|
||||
+static int kex_choose_conf(struct ssh *, uint32_t seq);
|
||||
static int kex_input_newkeys(int, u_int32_t, struct ssh *);
|
||||
|
||||
static const char *proposal_names[PROPOSAL_MAX] = {
|
||||
@@ -177,6 +177,18 @@ kex_names_valid(const char *names)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* returns non-zero if proposal contains any algorithm from algs */
|
||||
+static int
|
||||
+has_any_alg(const char *proposal, const char *algs)
|
||||
+{
|
||||
+ char *cp;
|
||||
+
|
||||
+ if ((cp = match_list(proposal, algs, NULL)) == NULL)
|
||||
+ return 0;
|
||||
+ free(cp);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Concatenate algorithm names, avoiding duplicates in the process.
|
||||
* Caller must free returned string.
|
||||
@@ -184,7 +196,7 @@ kex_names_valid(const char *names)
|
||||
char *
|
||||
kex_names_cat(const char *a, const char *b)
|
||||
{
|
||||
- char *ret = NULL, *tmp = NULL, *cp, *p, *m;
|
||||
+ char *ret = NULL, *tmp = NULL, *cp, *p;
|
||||
size_t len;
|
||||
|
||||
if (a == NULL || *a == '\0')
|
||||
@@ -201,10 +213,8 @@ kex_names_cat(const char *a, const char *b)
|
||||
}
|
||||
strlcpy(ret, a, len);
|
||||
for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
|
||||
- if ((m = match_list(ret, p, NULL)) != NULL) {
|
||||
- free(m);
|
||||
+ if (has_any_alg(ret, p))
|
||||
continue; /* Algorithm already present */
|
||||
- }
|
||||
if (strlcat(ret, ",", len) >= len ||
|
||||
strlcat(ret, p, len) >= len) {
|
||||
free(tmp);
|
||||
@@ -466,7 +485,12 @@ kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
|
||||
{
|
||||
int r;
|
||||
|
||||
- error("kex protocol error: type %d seq %u", type, seq);
|
||||
+ /* If in strict mode, any unexpected message is an error */
|
||||
+ if ((ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) {
|
||||
+ ssh_packet_disconnect(ssh, "strict KEX violation: "
|
||||
+ "unexpected packet type %u (seqnr %u)", type, seq);
|
||||
+ }
|
||||
+ error("type %u seq %u", type, seq);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, seq)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
@@ -548,6 +572,11 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
|
||||
if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
|
||||
return r;
|
||||
+ if (ninfo >= 1024) {
|
||||
+ error("SSH2_MSG_EXT_INFO with too many entries, expected "
|
||||
+ "<=1024, received %u", ninfo);
|
||||
+ return dispatch_protocol_error(type, seq, ssh);
|
||||
+ }
|
||||
for (i = 0; i < ninfo; i++) {
|
||||
if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
|
||||
return r;
|
||||
@@ -681,7 +705,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
|
||||
if (kex == NULL)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
|
||||
- ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
|
||||
+ ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error);
|
||||
ptr = sshpkt_ptr(ssh, &dlen);
|
||||
if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
|
||||
return r;
|
||||
@@ -717,7 +741,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
|
||||
if (!(kex->flags & KEX_INIT_SENT))
|
||||
if ((r = kex_send_kexinit(ssh)) != 0)
|
||||
return r;
|
||||
- if ((r = kex_choose_conf(ssh)) != 0)
|
||||
+ if ((r = kex_choose_conf(ssh, seq)) != 0)
|
||||
return r;
|
||||
|
||||
if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
|
||||
@@ -981,20 +1005,14 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
|
||||
return (1);
|
||||
}
|
||||
|
||||
-/* returns non-zero if proposal contains any algorithm from algs */
|
||||
static int
|
||||
-has_any_alg(const char *proposal, const char *algs)
|
||||
+kexalgs_contains(char **peer, const char *ext)
|
||||
{
|
||||
- char *cp;
|
||||
-
|
||||
- if ((cp = match_list(proposal, algs, NULL)) == NULL)
|
||||
- return 0;
|
||||
- free(cp);
|
||||
- return 1;
|
||||
+ return has_any_alg(peer[PROPOSAL_KEX_ALGS], ext);
|
||||
}
|
||||
|
||||
static int
|
||||
-kex_choose_conf(struct ssh *ssh)
|
||||
+kex_choose_conf(struct ssh *ssh, uint32_t seq)
|
||||
{
|
||||
struct kex *kex = ssh->kex;
|
||||
struct newkeys *newkeys;
|
||||
@@ -1019,13 +1037,23 @@ kex_choose_conf(struct ssh *ssh)
|
||||
sprop=peer;
|
||||
}
|
||||
|
||||
- /* Check whether client supports ext_info_c */
|
||||
- if (kex->server && (kex->flags & KEX_INITIAL)) {
|
||||
- char *ext;
|
||||
-
|
||||
- ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
|
||||
- kex->ext_info_c = (ext != NULL);
|
||||
- free(ext);
|
||||
+ /* Check whether peer supports ext_info/kex_strict */
|
||||
+ if ((kex->flags & KEX_INITIAL) != 0) {
|
||||
+ if (kex->server) {
|
||||
+ kex->ext_info_c = kexalgs_contains(peer, "ext-info-c");
|
||||
+ kex->kex_strict = kexalgs_contains(peer,
|
||||
+ "kex-strict-c-v00@openssh.com");
|
||||
+ } else {
|
||||
+ kex->kex_strict = kexalgs_contains(peer,
|
||||
+ "kex-strict-s-v00@openssh.com");
|
||||
+ }
|
||||
+ if (kex->kex_strict) {
|
||||
+ debug3("will use strict KEX ordering");
|
||||
+ if (seq != 0)
|
||||
+ ssh_packet_disconnect(ssh,
|
||||
+ "strict KEX violation: "
|
||||
+ "KEXINIT was not the first packet");
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Check whether client supports rsa-sha2 algorithms */
|
||||
diff --git a/kex.h b/kex.h
|
||||
index 5f7ef784..272ebb43 100644
|
||||
--- a/kex.h
|
||||
+++ b/kex.h
|
||||
@@ -149,6 +149,7 @@ struct kex {
|
||||
u_int kex_type;
|
||||
char *server_sig_algs;
|
||||
int ext_info_c;
|
||||
+ int kex_strict;
|
||||
struct sshbuf *my;
|
||||
struct sshbuf *peer;
|
||||
struct sshbuf *client_version;
|
||||
diff --git a/packet.c b/packet.c
|
||||
index 52017def..beb214f9 100644
|
||||
--- a/packet.c
|
||||
+++ b/packet.c
|
||||
@@ -1207,8 +1207,13 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
sshbuf_dump(state->output, stderr);
|
||||
#endif
|
||||
/* increment sequence number for outgoing packets */
|
||||
- if (++state->p_send.seqnr == 0)
|
||||
+ if (++state->p_send.seqnr == 0) {
|
||||
+ if ((ssh->kex->flags & KEX_INITIAL) != 0) {
|
||||
+ ssh_packet_disconnect(ssh, "outgoing sequence number "
|
||||
+ "wrapped during initial key exchange");
|
||||
+ }
|
||||
logit("outgoing seqnr wraps around");
|
||||
+ }
|
||||
if (++state->p_send.packets == 0)
|
||||
if (!(ssh->compat & SSH_BUG_NOREKEY))
|
||||
return SSH_ERR_NEED_REKEY;
|
||||
@@ -1216,6 +1221,11 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
state->p_send.bytes += len;
|
||||
sshbuf_reset(state->outgoing_packet);
|
||||
|
||||
+ if (type == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
|
||||
+ debug("resetting send seqnr %u", state->p_send.seqnr);
|
||||
+ state->p_send.seqnr = 0;
|
||||
+ }
|
||||
+
|
||||
if (type == SSH2_MSG_NEWKEYS)
|
||||
r = ssh_set_newkeys(ssh, MODE_OUT);
|
||||
else if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side)
|
||||
@@ -1344,8 +1354,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
/* Stay in the loop until we have received a complete packet. */
|
||||
for (;;) {
|
||||
/* Try to read a packet from the buffer. */
|
||||
- r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);
|
||||
- if (r != 0)
|
||||
+ if ((r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p)) != 0)
|
||||
break;
|
||||
/* If we got a packet, return it. */
|
||||
if (*typep != SSH_MSG_NONE)
|
||||
@@ -1629,10 +1615,16 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0)
|
||||
goto out;
|
||||
}
|
||||
+
|
||||
if (seqnr_p != NULL)
|
||||
*seqnr_p = state->p_read.seqnr;
|
||||
- if (++state->p_read.seqnr == 0)
|
||||
+ if (++state->p_read.seqnr == 0) {
|
||||
+ if ((ssh->kex->flags & KEX_INITIAL) != 0) {
|
||||
+ ssh_packet_disconnect(ssh, "incoming sequence number "
|
||||
+ "wrapped during initial key exchange");
|
||||
+ }
|
||||
logit("incoming seqnr wraps around");
|
||||
+ }
|
||||
if (++state->p_read.packets == 0)
|
||||
if (!(ssh->compat & SSH_BUG_NOREKEY))
|
||||
return SSH_ERR_NEED_REKEY;
|
||||
@@ -1698,6 +1690,10 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
#endif
|
||||
/* reset for next packet */
|
||||
state->packlen = 0;
|
||||
+ if (*typep == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
|
||||
+ debug("resetting read seqnr %u", state->p_read.seqnr);
|
||||
+ state->p_read.seqnr = 0;
|
||||
+ }
|
||||
|
||||
/* do we need to rekey? */
|
||||
if (ssh_packet_need_rekeying(ssh, 0)) {
|
||||
@@ -1720,10 +1716,39 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
|
||||
if (r != 0)
|
||||
return r;
|
||||
- if (*typep) {
|
||||
- state->keep_alive_timeouts = 0;
|
||||
- DBG(debug("received packet type %d", *typep));
|
||||
+ if (*typep == 0) {
|
||||
+ /* no message ready */
|
||||
+ return 0;
|
||||
}
|
||||
+ state->keep_alive_timeouts = 0;
|
||||
+ DBG(debug("received packet type %d", *typep));
|
||||
+
|
||||
+ /* Always process disconnect messages */
|
||||
+ if (*typep == SSH2_MSG_DISCONNECT) {
|
||||
+ if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
|
||||
+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
|
||||
+ return r;
|
||||
+ /* Ignore normal client exit notifications */
|
||||
+ do_log2(ssh->state->server_side &&
|
||||
+ reason == SSH2_DISCONNECT_BY_APPLICATION ?
|
||||
+ SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
|
||||
+ "Received disconnect from %s port %d:"
|
||||
+ "%u: %.400s", ssh_remote_ipaddr(ssh),
|
||||
+ ssh_remote_port(ssh), reason, msg);
|
||||
+ free(msg);
|
||||
+ return SSH_ERR_DISCONNECTED;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Do not implicitly handle any messages here during initial
|
||||
+ * KEX when in strict mode. They will be need to be allowed
|
||||
+ * explicitly by the KEX dispatch table or they will generate
|
||||
+ * protocol errors.
|
||||
+ */
|
||||
+ if (ssh->kex != NULL &&
|
||||
+ (ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict)
|
||||
+ return 0;
|
||||
+ /* Implicitly handle transport-level messages */
|
||||
switch (*typep) {
|
||||
case SSH2_MSG_IGNORE:
|
||||
debug3("Received SSH2_MSG_IGNORE");
|
||||
@@ -1738,19 +1763,6 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
debug("Remote: %.900s", msg);
|
||||
free(msg);
|
||||
break;
|
||||
- case SSH2_MSG_DISCONNECT:
|
||||
- if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
|
||||
- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
|
||||
- return r;
|
||||
- /* Ignore normal client exit notifications */
|
||||
- do_log2(ssh->state->server_side &&
|
||||
- reason == SSH2_DISCONNECT_BY_APPLICATION ?
|
||||
- SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
|
||||
- "Received disconnect from %s port %d:"
|
||||
- "%u: %.400s", ssh_remote_ipaddr(ssh),
|
||||
- ssh_remote_port(ssh), reason, msg);
|
||||
- free(msg);
|
||||
- return SSH_ERR_DISCONNECTED;
|
||||
case SSH2_MSG_UNIMPLEMENTED:
|
||||
if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
|
||||
return r;
|
||||
@@ -2242,6 +2254,7 @@ kex_to_blob(struct sshbuf *m, struct kex *kex)
|
||||
(r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->hostkey_nid)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->kex_type)) != 0 ||
|
||||
+ (r = sshbuf_put_u32(m, kex->kex_strict)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->my)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->peer)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->client_version)) != 0 ||
|
||||
@@ -2404,6 +2417,7 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
|
||||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_nid)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->kex_type)) != 0 ||
|
||||
+ (r = sshbuf_get_u32(m, &kex->kex_strict)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->my)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->peer)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->client_version)) != 0 ||
|
||||
@@ -2732,6 +2746,7 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...)
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
+ debug2("sending SSH2_MSG_DISCONNECT: %s", buf);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
|
||||
diff --git a/sshconnect2.c b/sshconnect2.c
|
||||
index df6caf81..0cccbcc4 100644
|
||||
--- a/sshconnect2.c
|
||||
+++ b/sshconnect2.c
|
||||
@@ -253,7 +253,8 @@ ssh_kex2(struct ssh *ssh, char *host, st
|
||||
xxx_host = host;
|
||||
xxx_hostaddr = hostaddr;
|
||||
|
||||
- if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
|
||||
+ if ((s = kex_names_cat(options.kex_algorithms,
|
||||
+ "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
|
||||
fatal("%s: kex_names_cat", __func__);
|
||||
myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s);
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
@@ -358,7 +358,6 @@ struct cauthmethod {
|
||||
};
|
||||
|
||||
static int input_userauth_service_accept(int, u_int32_t, struct ssh *);
|
||||
-static int input_userauth_ext_info(int, u_int32_t, struct ssh *);
|
||||
static int input_userauth_success(int, u_int32_t, struct ssh *);
|
||||
static int input_userauth_failure(int, u_int32_t, struct ssh *);
|
||||
static int input_userauth_banner(int, u_int32_t, struct ssh *);
|
||||
@@ -472,7 +471,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
|
||||
|
||||
ssh->authctxt = &authctxt;
|
||||
ssh_dispatch_init(ssh, &input_userauth_error);
|
||||
- ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info);
|
||||
+ ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, kex_input_ext_info);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept);
|
||||
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
|
||||
pubkey_cleanup(ssh);
|
||||
@@ -531,12 +530,6 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
-static int
|
||||
-input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
|
||||
-{
|
||||
- return kex_input_ext_info(type, seqnr, ssh);
|
||||
-}
|
||||
-
|
||||
void
|
||||
userauth(struct ssh *ssh, char *authlist)
|
||||
{
|
||||
@@ -615,6 +608,7 @@ input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
|
||||
free(authctxt->methoddata);
|
||||
authctxt->methoddata = NULL;
|
||||
authctxt->success = 1; /* break out */
|
||||
+ ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, dispatch_protocol_error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff -up openssh-8.7p1/sshd.c.kexstrict openssh-8.7p1/sshd.c
|
||||
--- openssh-8.7p1/sshd.c.kexstrict 2023-11-27 13:19:18.855433602 +0100
|
||||
+++ openssh-8.7p1/sshd.c 2023-11-27 13:28:10.441325314 +0100
|
||||
@@ -2531,10 +2531,14 @@ do_ssh2_kex(struct ssh *ssh)
|
||||
{
|
||||
char *myproposal[PROPOSAL_MAX] = { KEX_SERVER };
|
||||
struct kex *kex;
|
||||
+ char *cp;
|
||||
int r;
|
||||
|
||||
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
|
||||
- options.kex_algorithms);
|
||||
+ if ((cp = kex_names_cat(options.kex_algorithms,
|
||||
+ "kex-strict-s-v00@openssh.com")) == NULL)
|
||||
+ fatal("kex_names_cat");
|
||||
+
|
||||
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(cp);
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(
|
||||
options.ciphers);
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(
|
||||
@@ -2586,7 +2586,7 @@ do_ssh2_kex(struct ssh *ssh)
|
||||
if (gss && orig)
|
||||
xasprintf(&newstr, "%s,%s", gss, orig);
|
||||
else if (gss)
|
||||
- newstr = gss;
|
||||
+ xasprintf(&newstr, "%s,%s", gss, "kex-strict-s-v00@openssh.com");
|
||||
else if (orig)
|
||||
newstr = orig;
|
||||
|
||||
@@ -2650,6 +2654,7 @@ do_ssh2_kex(struct ssh *ssh)
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
#endif
|
||||
+ free(cp);
|
||||
debug("KEX done");
|
||||
}
|
||||
|
||||
57
openssh-9.6p1-CVE-2023-51385.patch
Normal file
57
openssh-9.6p1-CVE-2023-51385.patch
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
diff --git a/ssh.c b/ssh.c
|
||||
index 35c48e62..48d93ddf 100644
|
||||
--- a/ssh.c
|
||||
+++ b/ssh.c
|
||||
@@ -626,6 +626,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo)
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+valid_hostname(const char *s)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (*s == '-')
|
||||
+ return 0;
|
||||
+ for (i = 0; s[i] != 0; i++) {
|
||||
+ if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL ||
|
||||
+ isspace((u_char)s[i]) || iscntrl((u_char)s[i]))
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+valid_ruser(const char *s)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (*s == '-')
|
||||
+ return 0;
|
||||
+ for (i = 0; s[i] != 0; i++) {
|
||||
+ if (strchr("'`\";&<>|(){}", s[i]) != NULL)
|
||||
+ return 0;
|
||||
+ /* Disallow '-' after whitespace */
|
||||
+ if (isspace((u_char)s[i]) && s[i + 1] == '-')
|
||||
+ return 0;
|
||||
+ /* Disallow \ in last position */
|
||||
+ if (s[i] == '\\' && s[i + 1] == '\0')
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Main program for the ssh client.
|
||||
*/
|
||||
@@ -1118,6 +1153,10 @@ main(int ac, char **av)
|
||||
if (!host)
|
||||
usage();
|
||||
|
||||
+ if (!valid_hostname(host))
|
||||
+ fatal("hostname contains invalid characters");
|
||||
+ if (options.user != NULL && !valid_ruser(options.user))
|
||||
+ fatal("remote username contains invalid characters");
|
||||
host_arg = xstrdup(host);
|
||||
|
||||
/* Initialize the command to execute on remote host. */
|
||||
4
sources
4
sources
|
|
@ -1,3 +1,3 @@
|
|||
SHA512 (openssh-7.8p1.tar.gz) = 8e5b0c8682a9243e4e8b7c374ec989dccd1a752eb6f84e593b67141e8b23dcc8b9a7322b1f7525d18e2ce8830a767d0d9793f997486339db201a57986b910705
|
||||
SHA512 (openssh-7.8p1.tar.gz.asc) = 3a7bef84df3c07aa78965a11a6bbd6ca6e5d1e9265ac08871b3e5d304646be651b74f5302a195e86a56e6a83b19d79292e5599c9a9cf6f003a513d4354e8ad2f
|
||||
SHA512 (openssh-8.0p1.tar.gz) = e280fa2d56f550efd37c5d2477670326261aa8b94d991f9eb17aad90e0c6c9c939efa90fe87d33260d0f709485cb05c379f0fd1bd44fc0d5190298b6398c9982
|
||||
SHA512 (openssh-8.0p1.tar.gz.asc) = fe9e7383d9467e869762864f2b719165d9a3f2c5316c07067df1d45fc7819bd2cb8ef758454865595688804a4c160dd3d3aaee4c5f887859555d2c7bb8c4592b
|
||||
SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue