Compare commits

...
Sign in to create a new pull request.

207 commits

Author SHA1 Message Date
Julien Rische
c2ce5811ff krb5 1.21.3-11
- Fix strchr() conformance to C23
2026-01-05 14:29:38 +01:00
Alexander Bokovoy
fe6911cd3d Update prompter patch to the upstream version
Move the prompter patch to a separate one to avoid rebasing the
automated FAST one as it is context-dependent in the documentation area.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2025-10-20 10:34:09 +03:00
Alexander Bokovoy
53c3b9de3c Reject pre-authentication that requries a prompter if no prompter was provided
Resolves: rhbz#2403513

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2025-10-15 08:44:31 +03:00
Alexander Bokovoy
fb94528750 Test automated FAST channel acquisition during TGS-REQ
Upstream PR: https://github.com/krb5/krb5/pull/1447

It can be tested by using fedora-packager-kerberos from Rawhide
against Fedora KDC. If packagers have OTP tokens enabled, kinit will
automatically propose to enter password+OTP token value.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2025-09-26 14:34:06 +03:00
Fedora Release Engineering
a0a34794e3 Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-24 18:57:33 +00:00
Julien Rische
5c0a004494 krb5 1.21.3-6
- Do not block HMAC-MD4/5 in FIPS mode
  Resolves: rhbz#2370259
- PKINIT: implement paChecksum2 from MS-PKCA v20230920
  Resolves: rhbz#2357215
- Disallow RC4 HMAC-MD5 session keys by default (CVE-2025-3576)
  Resolves: rhbz#2359705

Signed-off-by: Julien Rische <jrische@redhat.com>
2025-06-06 13:01:37 +02:00
Julien Rische
f2bc777d63 krb5 1.21.3-5
- Prevent overflow when calculating ulog block size (CVE-2025-24528)
  Resolves: rhbz#2342798
- Support PKCS11 EC client certs in PKINIT
  Resolves: rhbz#2341962
- kdb5_util: fix DB entry flags on modification
  Resolves: rhbz#2336555
- Add ECDH support for PKINIT (RFC5349)
  Resolves: rhbz#2214326
- Remove dependency of krb5-libs on gawk and sed
  Resolves: rhbz#2323859

Signed-off-by: Julien Rische <jrische@redhat.com>
2025-01-29 19:32:00 +01:00
Fedora Release Engineering
099df268ce Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-17 09:48:45 +00:00
Julien Rische
9e0ac6c616 krb5 1.21.3-3
- libkrad: implement support for Message-Authenticator (CVE-2024-3596)
  Resolves: rhbz#2304071
- Fix various issues detected by static analysis
  Resolves: rhbz#2322704
- Remove RSA protocol for PKINIT
  Resolves: rhbz#2322706
- Make TCP waiting time configurable
  Resolves: rhbz#2322711

Signed-off-by: Julien Rische <jrische@redhat.com>
2024-10-30 12:49:36 +01:00
Gordon Messmer
4c1f565dfa Examine the server process GOT for signs of tampering. 2024-08-03 19:35:59 -07:00
Fedora Release Engineering
9767c1c24e Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild 2024-07-18 12:40:10 +00:00
Julien Rische
d71494ca6c krb5 1.21.3-1
- New upstream version (1.21.3)
- CVE-2024-26458: Memory leak in src/lib/rpc/pmap_rmt.c
  Resolves: rhbz#2266732
- CVE-2024-26461: Memory leak in src/lib/gssapi/krb5/k5sealv3.c
  Resolves: rhbz#2266741
- CVE-2024-26462: Memory leak in src/kdc/ndr.c
  Resolves: rhbz#2266743
- Add missing SPDX license identifiers
  Resolves: rhbz#2265333

Signed-off-by: Julien Rische <jrische@redhat.com>
2024-07-09 12:11:50 +02:00
Julien Rische
b45374269b krb5 1.21.2-6
- CVE-2024-37370 CVE-2024-37371: GSS message token handling
  Resolves: rhbz#2294678 rhbz#2294680
- Fix double free in klist's show_ccache()
  Resolves: rhbz#2257301
- Do not include files with "~" termination in krb5-tests

Signed-off-by: Julien Rische <jrische@redhat.com>
2024-07-08 15:09:03 +02:00
Fedora Release Engineering
5cc4a0d8bc Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-25 00:53:41 +00:00
Fedora Release Engineering
87d784ddd7 Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-21 02:56:15 +00:00
Julien Rische
1ed0e3a2d8 krb5 1.21.2-3
- Fix double free in klist's show_ccache()
  Resolves: rhbz#2257301
- Store krb5-tests files in architecture-specific directories
  Resolves: rhbz#2244601

Signed-off-by: Julien Rische <jrische@redhat.com>
2024-01-17 14:06:16 +01:00
Julien Rische
0fe5c327ec Fix memory leaks and use SPDX license expression
- Use SPDX expression for license tag
- Fix unimportant memory leaks
  Resolves: rhbz#2223274

Signed-off-by: Julien Rische <jrische@redhat.com>
2023-10-16 16:10:43 +02:00
Julien Rische
f5676fd233 New upstream version (1.21.2)
- Fix double-free in KDC TGS processing (CVE-2023-39975)
  Resolves: rhbz#2229113
- Make tests compatible with Python 3.12
  Resolves: rhbz#2224013

Signed-off-by: Julien Rische <jrische@redhat.com>
2023-08-16 11:30:37 +02:00
Fedora Release Engineering
ae2cf9bef3 Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-07-20 09:33:35 +00:00
Marek Blaha
a2c04215f0 Replace file dependency by package name
By default, dnf5 does not download the filelists repository metadata
required to resolve file dependencies outside of /usr/(s)bin or /etc.
This causes the krb5-server file to become uninstallable.

$ dnf5 install krb5-server
Repositories loaded.
Failed to resolve the transaction:
Problem: conflicting requests
  - nothing provides /usr/share/dict/words needed by krb5-server-1.21-1.fc39.x86_64

This change aligns with the Fedora packaging guidelines, as stated here:
https://docs.fedoraproject.org/en-US/packaging-guidelines/#_file_and_directory_dependencies

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2216903
2023-06-29 08:32:10 +02:00
Julien Rische
0b340d0ef3 New upstream version (1.21)
Do not disable PKINIT if some of the well-known DH groups are unavailable
  Resolves: rhbz#2214297
Make PKINIT CMS SHA-1 signature verification available in FIPS mode
  Resolves: rhbz#2214300
Allow to set PAC ticket signature as optional
  Resolves: rhbz#2181311
Add support for MS-PAC extended KDC signature (CVE-2022-37967)
  Resolves: rhbz#2166001
Fix syntax error in aclocal.m4
  Resolves: rhbz#2143306

Signed-off-by: Julien Rische <jrische@redhat.com>
2023-06-12 17:29:15 +02:00
Julien Rische
7058594eab Add support for MS-PAC extended KDC signature (CVE-2022-37967)
Resolves: rhbz#2166001
Signed-off-by: Julien Rische <jrische@redhat.com>
2023-01-31 17:56:02 +01:00
Julien Rische
ec957f5711 Do not block KRB5KDF and MD4/5 in FIPS mode
Bypass OpenSSL's restrictions to use KRB5KDF in FIPS mode in case at
least one of AES SHA-1 HMAC encryption types are used.

Use OpenSSL 3.0 library context to access MD4 and MD5 lazily from
legacy provider if RADIUS is being used or RC4 encryption type is
enabled, without affecting global context.

Such exceptions should not be allowed by the default FIPS crypto
policy.

Signed-off-by: Julien Rische <jrische@redhat.com>
2023-01-30 12:52:50 +01:00
Fedora Release Engineering
dca288bae2 Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-01-19 15:08:24 +00:00
Julien Rische
4a4fd39d5e Add AES SHA-2 HMAC family as default KDC etypes
Resolves: rhbz#2114771
Signed-off-by: Julien Rische <jrische@redhat.com>
2023-01-18 16:08:42 +01:00
Julien Rische
4eee9bbb50 Strip debugging data from ksu executable file
Signed-off-by: Julien Rische <jrische@redhat.com>
2023-01-18 16:08:41 +01:00
Julien Rische
f0b4f85e9e Include missing OpenSSL FIPS header
Signed-off-by: Julien Rische <jrische@redhat.com>
2023-01-09 13:28:16 +01:00
Julien Rische
f29ff7186e Make tests compatible with sssd_krb5_locator_plugin.so 2023-01-09 13:28:16 +01:00
Yaakov Selkowitz
ba968605e7 Fix openssl dependencies for RHEL/ELN 2022-12-07 19:18:54 -05:00
Julien Rische
f003c0755c Enable TMT integration with Fedora CI
Signed-off-by: Julien Rische <jrische@redhat.com>
2022-12-06 14:48:31 +01:00
Alexander Bokovoy
a206938c15 Bump KDB version to 9.0
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2022-12-01 17:57:01 +02:00
Julien Rische
95288a2fb9 Use TMT for gating tests
Signed-off-by: Julien Rische <jrische@redhat.com>
2022-12-01 15:16:23 +01:00
Julien Rische
3668746b8f Remove invalid password expiry warning
Resolves: rhbz#2129113
Signed-off-by: Julien Rische <jrische@redhat.com>
2022-11-24 11:35:42 +01:00
Julien Rische
603ad7099e Update error checking for OpenSSL CMS_verify
Resolves: rhbz#2119704
Signed-off-by: Julien Rische <jrische@redhat.com>
2022-11-24 11:35:26 +01:00
Julien Rische
56cee506e7 New upstream version (1.20.1)
Also set "supportedCMSTypes" to SHA-512/256 with RSA encryption

Resolves: rhbz#2124463
Resolves: rhbz#2114766
Signed-off-by: Julien Rische <jrische@redhat.com>
2022-11-24 11:35:10 +01:00
Julien Rische
c13bf943d8 Fix integer overflows in PAC parsing (CVE-2022-42898)
Resolves: rhbz#2143011
Signed-off-by: Julien Rische <jrische@redhat.com>
2022-11-16 10:35:01 +01:00
Andreas Schneider
0c2f5dcbe5 Add missing BR for resolv_wrapper to run t_discover_uri.py 2022-08-03 13:17:09 +02:00
Andreas Schneider
f5aa40a4a2 Do not define netlib, but use autoconf detection for res_* functions
This looks like an ancient patch and is not needed anymore.
2022-08-03 13:17:09 +02:00
Andreas Schneider
440331a1e4 Fix the Source0 and Source1 variables 2022-08-03 13:15:15 +02:00
Andreas Schneider
3907ec760c Use baserelease to set the release number 2022-08-02 12:13:54 +02:00
Fedora Release Engineering
e138eb8125 Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-07-21 16:36:11 +00:00
Julien Rische
601b89387b Read GSS configuration files with mtime 0
There is at least one case (with flatpaks) where configuration files
in the special read-only /etc all have an mtime of 0.  Using an
initial last modified time of 0 in g_initialize.c causes these files
to never be read.

Change the initial high value to the be the "invalid" value
(time_t)-1.  Since the C and POSIX standards do not require time_t to
be signed, special-case the checks in load_if_changed() and
updateMechList() to treat all mod times as newer than -1.

Signed-off-by: Julien Rische <jrische@redhat.com>
2022-06-15 15:38:15 +02:00
Julien Rische
e9188f0caa Allow krad UDP/TCP localhost connection with FIPS
libkrad allows to establish connections only to UNIX socket in FIPS
mode, because MD5 digest is not considered safe enough to be used for
network communication. However, FreeRadius requires connection on TCP or
UDP ports.

This commit allows TCP or UDP connections in FIPS mode if destination is
localhost.

Resolves: rhbz#2082189

Signed-off-by: Julien Rische <jrische@redhat.com>
2022-05-25 11:50:56 +02:00
Julien Rische
c25a51c969 Use p11-kit as default PKCS11 module
Resolves: rhbz#2073274

Signed-off-by: Julien Rische <jrische@redhat.com>
2022-05-02 19:03:37 +02:00
Julien Rische
04513849e3 Try harder to avoid password change replay errors
change_set_password() was changed to prefer TCP.  However, because
UDP_LAST falls back to UDP after one second, we can still get a replay
error due to a dropped packet, before the TCP layer has a chance to
retry.

Instead, try k5_sendto() with NO_UDP, and only fall back to UDP after
TCP fails completely without reaching a server.  In sendto_kdc.c,
implement an ONLY_UDP transport strategy to allow the UDP fallback.

Resolves: rhbz#2076965

Signed-off-by: Julien Rische <jrische@redhat.com>
2022-04-26 13:38:51 +02:00
Alexander Bokovoy
fc958d4773 Fix libkrad client cleanup code
Resolves: rhbz#2072059

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2022-04-05 22:18:53 +03:00
Alexander Bokovoy
29a69aee06 fix dist macro 2022-04-05 16:52:33 +03:00
Alexander Bokovoy
0ceb166d96 Allow use of larger RADIUS attributes in krad library
In kr_attrset_decode(), explicitly treat the length byte as unsigned.
    Otherwise attributes longer than 125 characters will be rejected with
    EBADMSG.

    Add a 253-character-long NAS-Identifier attribute to the tests to make
    sure that attributes with the maximal number of characters are working
    as expected.

    [ghudson@mit.edu: used uint8_t cast per current practices; edited
    commit message]

    ticket: 9036 (new)

From upstream, needed in preparation for OAuth2 support for FreeIPA and
SSSD.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2022-04-05 16:51:11 +03:00
Julien Rische
2ef37ab30d Use SHA-256 instead of SHA-1 for PKINIT CMS digest
CMS digest and signature algorithm for the anonymous PKINIT is changed
from SHA-1 to SHA-256. SHA-1 hasn't been considered secure anymore for
this kind of purposes for some years already.

Resolves: rhbz#2067121

Signed-off-by: Julien Rische <jrische@redhat.com>
2022-03-23 12:28:27 +01:00
Zbigniew Jędrzejewski-Szmek
970430cbff Drop link flags from krb5-config
Introspecing krb5-config shows that all of the flags in LDFLAGS= are
inappropriate for export, so just drop them all.
2022-02-09 10:54:56 +01:00
Zbigniew Jędrzejewski-Szmek
f858c7e550 Drop old trigger scriptlet
1.15.1 was ~2017, so there is no need to support upgrades from such old
systemd. This allows the dependency on grep to be dropped. grep pulls
in pcre, but most other programs in the core group depend on the newer
pcre2, so it's nicer to avoid pulling in pcre in minimal installations.
2022-02-08 14:07:47 +01:00
Alexander Bokovoy
b998554176 Temporarily remove package note to unblock krb5-dependent packages
Resolves: rhbz#2048909

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2022-02-03 12:27:25 +02:00
Fedora Release Engineering
75355e197a - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-01-20 15:08:32 +00:00
Antonio Torres
ad88d4fd50 Add patches to support OpenSSL 3.0.0
Signed-off-by: Antonio Torres <antorres@redhat.com>
2021-12-03 11:25:46 +01:00
Sahana Prasad
70255ea5b0 Rebuilt with OpenSSL 3.0.0 2021-09-14 19:05:45 +02:00
Robbie Harwood
91c904e5df Remove -specs= from krb5-config output 2021-08-24 17:13:22 +00:00
Robbie Harwood
ca196a9d6b Fix KDC null deref on TGS inner body null server (CVE-2021-37750) 2021-08-19 12:29:56 -04:00
Robbie Harwood
03e8c69837 Add sources 2021-07-26 14:50:12 -04:00
Robbie Harwood
c4016b4e4c New upstream version (1.19.2) 2021-07-26 14:49:39 -04:00
Robbie Harwood
2484569caa Fix defcred leak in krb5 gss_inquire_cred() 2021-07-21 12:44:26 -04:00
Robbie Harwood
6a2eeb9666 Fix KDC null deref on bad encrypted challenge (CVE-2021-36222) 2021-07-12 13:11:12 -04:00
Robbie Harwood
af96dc0c6c Fix use-after-free during krad remote_shutdown() 2021-07-01 13:17:47 -04:00
Robbie Harwood
c5044b0741 MEMORY locking fix and static analysis pullup 2021-06-28 17:50:46 -04:00
Robbie Harwood
91bbbda93f Add the backward-compatible parts of openssl3 support 2021-06-21 13:16:44 -04:00
Robbie Harwood
4df0096f20 Fix three canonicalization cases for fallback 2021-06-09 10:55:13 -04:00
Robbie Harwood
65a1e5607c Fix doc build for Sphinx 4.0 2021-06-02 12:09:09 -04:00
Robbie Harwood
72e80d67ef Add all the sssd-kcm workarounds 2021-05-20 17:26:12 -04:00
Robbie Harwood
c4150c67d1 Fix context for previous backport 2021-05-20 13:59:39 -04:00
Robbie Harwood
904d264a41 Add KCM_OP_GET_CRED_LIST and KCM_OP_RETRIEVE support 2021-05-20 13:48:19 -04:00
Robbie Harwood
69e05d5e39 Remove broken gating file
Currently the gating file prevents building:

    rharwood@eesha:~/krb5.fedora/rawhide$ fedpkg build
    Could not execute build: Found a gating.yaml file in your repo with additional Greenwave policies, but it is not valid.
    Please fix the file or skip this check using the option --skip-remote-rules-validation.
    Error response from Greenwave: YAML Parser Error: mapping values are not allowed here
      in "<unicode string>", line 2, column 18:
           product_versions:
                                ^
    rharwood@eesha:~/krb5.fedora/rawhide$

Patches to add it back will be considered if and only if they don't
break the build.
2021-05-04 15:21:05 -04:00
Robbie Harwood
e9fb111a11 Suppress static analyzer warning in FIPS override 2021-05-04 15:02:53 -04:00
Robbie Harwood
1c2362203e Add rpminspect configuration 2021-05-03 17:50:44 -04:00
Robbie Harwood
c183c8de7d Fix the mess the mass rebuild made of Release 2021-03-30 14:36:09 -04:00
Miroslav Vadkerti
7ef4909316 Onboard krb5 to downstream gating
Because krb5 is auto-synced via DistroBaker, we need to add
downstream gating configuration in Fedora.

Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
2021-03-30 14:31:53 -04:00
Robbie Harwood
14c7d0b635 Merge #6 Update tests/inplace-upgrade-sanity-test/runtest.sh 2021-03-30 13:07:35 +00:00
Filip Dvorak
002bf4053e Update tests/inplace-upgrade-sanity-test/Makefile
Added setools-console package into Makefile.
2021-03-30 08:29:53 +00:00
Filip Dvorak
d67d35a3c6 Update tests/inplace-upgrade-sanity-test/runtest.sh 2021-03-29 15:21:43 +00:00
Zbigniew Jędrzejewski-Szmek
cf3e70c97c Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
2021-03-02 16:13:34 +01:00
Robbie Harwood
1c03da79de Further test dependency fixes; no code changes 2021-03-01 16:49:32 -05:00
Robbie Harwood
d20ec5d3bc Make test dependencies contingent on skipcheck; no code changes 2021-03-01 21:27:49 +00:00
Robbie Harwood
ab3f34f0e7 ... including the sources this time 2021-02-18 16:52:28 -05:00
Robbie Harwood
3faaf11da7 New upstream version (1.19.1) 2021-02-18 16:51:47 -05:00
Robbie Harwood
00a0ac8abc Restore krb5_set_default_tgs_ktypes() 2021-02-17 16:12:41 -05:00
Robbie Harwood
d3ac4cf9b0 Hoist the KDC_RUN_DIR check 2021-02-15 15:54:54 -05:00
Robbie Harwood
35a4aa7b99 No code change; just coping with reverted autoconf 2021-02-05 20:39:13 +00:00
Robbie Harwood
90bc2e25b3 Cope with autoconf rollback 2021-02-05 15:33:20 -05:00
Robbie Harwood
d5839d0511 New upstream version (1.19) 2021-02-02 15:32:32 +00:00
Robbie Harwood
105082cb42 Hoist and add an option for disabling %check 2021-02-01 16:21:47 -05:00
Robbie Harwood
0dd40e4ff0 Support host-based GSS initiator names 2021-01-28 13:18:14 -05:00
Robbie Harwood
042ca4af99 Require krb5-pkinit from krb5-{server,workstation} 2021-01-28 16:37:37 +00:00
Robbie Harwood
54bf131a4a Fix up weird mass rebuild versioning 2021-01-28 16:16:22 +00:00
Robbie Harwood
ef09340be0 Add APIs for marshalling credentials 2021-01-28 10:56:02 -05:00
Robbie Harwood
327ebd0b26 Cope with new autotools behavior wrt runstatedir 2021-01-27 14:45:26 -05:00
Fedora Release Engineering
b23f8f6215 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-01-26 16:06:22 +00:00
Robbie Harwood
9fb5239517 New upstream version (1.19-beta2) 2021-01-12 12:45:35 -05:00
Robbie Harwood
0da55d6175 New upstream version (1.19-beta1) 2020-12-16 16:30:40 -05:00
Robbie Harwood
58924baeb4 Fix runstatedir configuration
Why couldn't systemd just leave it alone?

Partially reverts ec1ab43ca2 .
2020-12-16 11:20:57 -05:00
Robbie Harwood
ed80b08062 Add make to BuildRequires
Drop cmake since we don't use it for anything
2020-12-01 14:37:26 -05:00
Robbie Harwood
b783a5421c Document -k option in kvno(1) synopsis 2020-11-24 12:55:33 -05:00
Robbie Harwood
ab7a2a35c2 Upstream executable shared libraries patch 2020-11-20 11:43:18 -05:00
Robbie Harwood
dc8775d11d Fix build failure in -1 2020-11-18 13:33:37 -05:00
Robbie Harwood
5facc9df4d New upstream version (1.18.3) 2020-11-18 18:16:20 +00:00
Robbie Harwood
015255764a Sigh, date fix 2020-11-17 12:50:36 -05:00
Robbie Harwood
ec1ab43ca2 Migrate /var/run to /run, an exercise in pointlessness
Resolves: #1898410
2020-11-17 12:27:42 -05:00
Robbie Harwood
d2da394f67 Add recursion limit for ASN.1 indefinite lengths (CVE-2020-28196) 2020-11-05 12:09:39 -05:00
Robbie Harwood
bfdc7c0b7b Fix minor static analysis defects 2020-10-23 10:25:37 -04:00
Robbie Harwood
fced14e78a Fix build of previous 2020-10-21 11:49:22 -04:00
Robbie Harwood
7c8b50fca5 Cross-realm s4u fixes for samba (#1836630) 2020-10-21 11:24:24 -04:00
Tomas Mraz
da77b5dcf8 Drop unnecessary conflict with openssl-libs >= 3.0.0
The requirement unnecessarily prevents temporary coexistence of
krb5-libs with new openssl library where the old openssl library
is coming from openssl1.1 compat package.
2020-10-19 11:25:53 +02:00
Robbie Harwood
96c0dcc1c7 Unify kvno option documentation 2020-10-15 16:18:06 -04:00
Robbie Harwood
501e298072 Add md5 override to krad 2020-10-02 16:36:12 -04:00
Robbie Harwood
c06ba2920a Use systemctl reload to HUP the KDC during logrotate
Resolves: #1877692
2020-09-10 14:22:32 +00:00
Robbie Harwood
d7334ebf68 Fix input length checking in SPNEGO DER decoding 2020-09-09 17:47:18 -04:00
Robbie Harwood
1003328588 Mark crypto-polices snippet as missingok
Resolves: #1868379
2020-08-28 12:23:29 -04:00
Robbie Harwood
cd0b1d6ba6 Temporarily dns_canonicalize_hostname=fallback changes
Hopefully unbreak IPA while we debug further
2020-08-13 09:50:45 -04:00
Robbie Harwood
c59e4a1c67 Expand dns_canonicalize_hostname=fallback support 2020-08-07 19:03:02 -04:00
Robbie Harwood
2091f29399 Fix leak in KERB_AP_OPTIONS_CBT server support 2020-08-04 14:24:08 -04:00
Robbie Harwood
4530bb6de9 Revert qualify_shortname removal 2020-08-03 15:39:37 -04:00
Robbie Harwood
8be5252136 Disable tests on s390x
Resolves: #1863952
2020-08-03 15:36:24 -04:00
Fedora Release Engineering
d0cfa344c7 - Second attempt - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-08-01 03:47:16 +00:00
Robbie Harwood
710f626f12 Revert qualify_shortname changes 2020-07-31 13:31:53 -04:00
Fedora Release Engineering
d314641a26 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-07-28 03:39:56 +00:00
Robbie Harwood
86ecb1b3d2 Ignore bad enctypes in krb5_string_to_keysalts()
Allow gss_unwrap_iov() of unpadded RC4 tokens
2020-07-22 17:28:11 -04:00
Robbie Harwood
b1b925635d Ignore bad enctypes in krb5_string_to_keysalts() 2020-07-22 15:20:11 -04:00
Tom Stellard
da1e8dbb3f Use make macros
https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
2020-07-21 22:06:50 +00:00
Robbie Harwood
f15271f04d Set qualify_shortname empty in default configuration
Resolves: #1852041
2020-07-08 16:10:07 -04:00
Robbie Harwood
80e06352b8 Use two queues for concurrent t_otp.py daemons 2020-06-15 17:27:59 -04:00
Robbie Harwood
e326a52474 Match Heimdal behavior for channel bindings 2020-06-15 16:57:30 -04:00
Robbie Harwood
feaafc07b2 Fix test suite by removing wrapper workarounds 2020-06-08 22:00:22 +00:00
Robbie Harwood
3c4e18f2f3 Omit PA_FOR_USER if we can't compute its checksum 2020-06-08 16:01:55 -04:00
Robbie Harwood
49849de329 Replace gssrpc tests with a Python script 2020-05-30 12:38:04 -04:00
Robbie Harwood
883355750a Default dns_canonicalize_hostname to "fallback" 2020-05-30 12:01:58 -04:00
Robbie Harwood
331a9df349 dns_canonicalize_hostname = fallback 2020-05-26 21:47:51 +00:00
Robbie Harwood
dec02b8411 Pass channel bindings through SPNEGO 2020-05-26 14:34:53 -04:00
Robbie Harwood
102adf5edf New upstream release (1.18.2) 2020-05-22 14:26:04 -04:00
Robbie Harwood
d370e2a431 Fix SPNEGO acceptor mech filtering 2020-05-22 13:28:09 -04:00
Robbie Harwood
0963a62bc3 Fix typo ("in in") in the ksu man page 2020-05-18 14:02:44 -04:00
Robbie Harwood
a9ccd6fd57 Omit KDC indicator check for S4U2Self requests 2020-05-08 14:14:22 -04:00
Robbie Harwood
19d5d2e504 Pass gss_localname() through SPNEGO 2020-04-28 13:12:21 -04:00
Robbie Harwood
46d8c677ae It usually helps if I commit the sources file 2020-04-14 15:50:03 -04:00
Robbie Harwood
7fca7fd076 New upstream version (1.18.1) 2020-04-14 15:45:43 -04:00
Robbie Harwood
66ec722479 Make ksu honor KRB5CCNAME again 2020-04-07 15:51:54 -04:00
Robbie Harwood
9f3201c4bc Do expiration warnings for all init_creds APIs 2020-04-02 14:03:07 -04:00
Robbie Harwood
c262ec69f6 Correctly import "service@" GSS host-based name 2020-04-01 14:24:49 -04:00
Robbie Harwood
4e7e5fe69b Eliminate redundant PKINIT responder invocation 2020-03-26 16:01:18 -04:00
Robbie Harwood
dd7e9481aa Add finalization safety check to com_err 2020-03-26 10:20:02 -04:00
Robbie Harwood
5c9732a545 Add maximum openssl version in preparation for openssl 3 2020-03-20 16:16:55 +00:00
Robbie Harwood
bea8330f52 Document client keytab usage 2020-03-17 15:26:56 -04:00
Robbie Harwood
bef2ba57a2 Update for new rpmlint shenanigans 2020-03-09 15:26:46 -04:00
Robbie Harwood
f6c62d5e63 Refresh manually acquired creds from client keytab 2020-03-03 12:34:50 -05:00
Robbie Harwood
812c07a94f Allow deletion of require_auth with LDAP KDB 2020-02-28 13:35:47 -05:00
Robbie Harwood
0ecf7a0e65 Allow certauth modules to set hw-authent flag 2020-02-27 16:13:51 -05:00
Robbie Harwood
3b6955d99e Fix AS-REQ checking of KDB-modified indicators 2020-02-21 13:16:49 -05:00
Robbie Harwood
48a220a102 Fix missing dist 2020-02-12 17:47:03 -05:00
Robbie Harwood
f287f939a9 New upstream version (1.18) 2020-02-12 22:29:13 +00:00
Robbie Harwood
dd3e136188 Don't assume OpenSSL failures are memory errors 2020-02-07 10:59:57 -05:00
Robbie Harwood
edfb00e001 Put KDB authdata first 2020-02-06 10:17:38 -05:00
Robbie Harwood
8fb4697062 New upstream beta release - 1.18-beta2
Adjust naming convention for downstream patches
2020-01-31 20:31:53 +00:00
Fedora Release Engineering
b3d5b8f719 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-01-29 07:50:49 +00:00
Robbie Harwood
7f642b1512 New upstream beta release - 1.18-beta1 2020-01-13 18:19:19 -05:00
Robbie Harwood
84aac1fa6d Fix LDAP policy enforcement of pw_expiration
Fix handling of invalid CAMMAC service verifier
2020-01-08 14:07:00 -05:00
Robbie Harwood
2496b50d00 Fix xdr_bytes() strict-aliasing violations 2020-01-06 16:36:41 -05:00
Robbie Harwood
fd463aed6a Don't warn in kadmin when no policy is specified
Do not always canonicalize enterprise principals
2020-01-03 11:36:21 -05:00
Robbie Harwood
d6ef09022c Enable the LMDB backend for the KDB 2019-12-13 19:11:07 +00:00
Robbie Harwood
9d642021d7 New upstream version - 1.17.1
Stop building and packaging PDFs
2019-12-12 18:42:51 +00:00
Robbie Harwood
4aee4bdd71 Qualify short hostnames when not using DNS 2019-12-06 13:44:42 -05:00
Robbie Harwood
02c0c74c74 Various gssalloc fixes 2019-11-27 12:36:19 -05:00
Robbie Harwood
76d9979dc3 Turns out openssl has an epoch 2019-11-21 22:06:25 +00:00
Robbie Harwood
4c128ec39a Fix runtime openssl version to actually propogate 2019-11-20 23:03:40 +00:00
Robbie Harwood
b9ea889e2a Add runtime openssl version requirement too 2019-11-20 21:13:58 +00:00
Robbie Harwood
4b8056ef08 Fix kadmin addprinc -randkey -kvno 2019-11-20 14:16:04 -05:00
Robbie Harwood
1404656ded Use OpenSSL's backported KDFs
Restore MD4 in FIPS mode (for samba)
2019-11-19 14:45:23 -05:00
Robbie Harwood
cbf35c8b1f Add default_principal_flags to example kdc.conf 2019-11-08 20:45:40 +00:00
Robbie Harwood
9ce53b906d Log unknown enctypes as unsupported in KDC 2019-10-02 11:19:07 -04:00
Robbie Harwood
1a6673d2ee Fix KDC crash when logging PKINIT enctypes (CVE-2019-14844) 2019-09-25 13:15:11 -04:00
Robbie Harwood
bff738a25d Static analyzer appeasement 2019-09-12 10:15:52 -04:00
Robbie Harwood
6ea5e5fa9a Simplify krb5_dbe_def_search_enctype() 2019-08-27 11:24:25 -04:00
Robbie Harwood
2dabf02464 Update FIPS patches to remove SPAKE 2019-08-22 15:54:34 -04:00
Robbie Harwood
4906d9dae9 Support building in COPR now that %{copr_username} is gone 2019-08-16 12:24:27 -04:00
Robbie Harwood
cdaea01dc8 Fix KCM client time offset propagation 2019-08-15 16:32:06 -04:00
Robbie Harwood
6fb26c9d3d Initialize life/rlife in kdcpolicy interface 2019-08-09 16:05:18 -04:00
Robbie Harwood
e73c24bb36 Fix memory leaks in soft-pkcs11 code 2019-08-06 09:46:36 -04:00
Robbie Harwood
f4c04f8cde Add soft-pkcs11 and use it for testing 2019-07-30 08:56:06 -04:00
Fedora Release Engineering
52c0e4ab88 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2019-07-25 12:06:52 +00:00
Robbie Harwood
7c5b49f828 Filter enctypes in gss_set_allowable_enctypes() 2019-07-18 12:49:23 -04:00
Robbie Harwood
4c8ed38666 Don't error on invalid enctypes in keytab
Resolves: #1724380
2019-07-15 13:07:54 -04:00
Robbie Harwood
a0277fd396 Remove now-unused checksum functions 2019-07-02 11:42:28 -04:00
Robbie Harwood
490a817464 Fix typo in 3des commit 2019-06-26 18:23:02 -04:00
Robbie Harwood
7bee5f19e1 Remove PKINIT draft9 support (compat with EOL, pre-2008 Windows) 2019-06-26 18:07:12 -04:00
Robbie Harwood
2843572c2f Remove strerror() calls from k5_get_error() 2019-06-10 12:41:26 -04:00
Robbie Harwood
6d60b0827f Remove 3des from kdc.conf example 2019-06-07 08:52:53 -04:00
Robbie Harwood
1cae0b7e96 Remove 3DES support 2019-06-03 17:33:31 -04:00
Robbie Harwood
19e2656c15 Remove 3des support 2019-06-03 17:25:49 -04:00
Robbie Harwood
48af99c1f7 Remove krb5int_c_combine_keys() and no-flags SAM-2 preauth 2019-05-30 13:32:37 -04:00
Robbie Harwood
3f80a77313 Remove support for single-DES and CRC 2019-05-28 15:22:45 -04:00
Robbie Harwood
f50ceacadf Add missing newlines to deprecation warnings
Switch to upstream's ksu path patch
2019-05-22 10:59:16 -04:00
Robbie Harwood
79613952e3 Update default krb5kdc mkey manual-entry enctype
Also update account lockout patch to upstream version
2019-05-21 12:59:56 -04:00
Robbie Harwood
39ba823db6 Test & docs fixes in preparation for DES removal 2019-05-20 16:49:04 -04:00
Robbie Harwood
f91545040c Drop krb5_realm_compare() etc. NULL check patches 2019-05-15 17:01:26 -04:00
Robbie Harwood
bebe7bd29f Re-provide krb5-kdb-version in -devel as well (IPA wants it) 2019-05-15 15:16:18 +00:00
Robbie Harwood
aa55266a84 (Patch consolidation; hopefully no changes) 2019-05-14 12:34:12 -04:00
Robbie Harwood
4b3d9079ae Remove checksum type profile variables 2019-05-14 11:07:43 -04:00
Robbie Harwood
0b0d802a54 Pull in 2019-05-02 static analysis updates 2019-05-10 13:50:56 -04:00
Robbie Harwood
d1b5e24f4c Drop --with-pkinit-crypto-impl 2019-05-06 14:38:08 -04:00
Robbie Harwood
85664dde3d Move krb5-kdb-version provide into krb5-server for freeipa 2019-05-03 18:36:31 +00:00
Robbie Harwood
4c5654d0fb Use secure_getenv() where appropriate 2019-05-01 12:47:31 -04:00
Robbie Harwood
cdfd42332f Get that squeaky rpmlint clean 2019-04-24 15:51:18 -04:00
110 changed files with 31958 additions and 16526 deletions

1
.fmf/version Normal file
View file

@ -0,0 +1 @@
1

125
.gitignore vendored
View file

@ -1,49 +1,50 @@
krb5-1.3.4.tar.gz
krb5-1.3.5.tar.gz
krb5-1.3.5.tar.gz.asc
krb5-1.3.6.tar.gz
krb5-1.3.6.tar.gz.asc
krb5-1.4.tar.gz
krb5-1.4.tar.gz.asc
krb5-1.4.1.tar.gz
krb5-1.4.1.tar.gz.asc
krb5-1.4.2.tar.gz
krb5-1.4.2.tar.gz.asc
krb5-1.4.3.tar.gz
krb5-1.4.3.tar.gz.asc
krb5-1.5.tar.gz
krb5-1.5.tar.gz.asc
krb5-1.6.tar.gz
krb5-1.6.tar.gz.asc
krb5-1.6-pdf.tar.gz
krb5-1.6.1.tar.gz
krb5-1.6.1.tar.gz.asc
krb5-1.6.1-pdf.tar.gz
krb5-1.6.2.tar.gz
krb5-1.6.2.tar.gz.asc
krb5-1.6.2-pdf.tar.gz
krb5-1.6.3.tar.gz
krb5-1.6.3.tar.gz.asc
krb5-1.6.3-pdf.tar.gz
krb5-1.7.tar.gz
krb5-1.7.tar.gz.asc
krb5-1.7-pdf.tar.gz
krb5-1.7.1.tar.gz
krb5-1.7.1.tar.gz.asc
krb5-1.7.1-pdf.tar.gz
krb5-1.8.tar.gz
krb5-1.8.tar.gz.asc
krb5-appl-1.0.tar.gz
krb5-appl-1.0.tar.gz.asc
krb5-1.8-pdf.tar.gz
krb5-1.8.1.tar.gz
krb5-1.8.1.tar.gz.asc
krb5-1.8.1-pdf.tar.gz
krb5-1.8.2.tar.gz.asc
krb5-1.8.2-pdf.tar.gz
krb5-1.8.3.tar.gz
krb5-1.8.3.tar.gz.asc
krb5-1.8.3-pdf.tar.gz
/results_krb5
/krb5-1.3.4.tar.gz
/krb5-1.3.5.tar.gz
/krb5-1.3.5.tar.gz.asc
/krb5-1.3.6.tar.gz
/krb5-1.3.6.tar.gz.asc
/krb5-1.4.tar.gz
/krb5-1.4.tar.gz.asc
/krb5-1.4.1.tar.gz
/krb5-1.4.1.tar.gz.asc
/krb5-1.4.2.tar.gz
/krb5-1.4.2.tar.gz.asc
/krb5-1.4.3.tar.gz
/krb5-1.4.3.tar.gz.asc
/krb5-1.5.tar.gz
/krb5-1.5.tar.gz.asc
/krb5-1.6.tar.gz
/krb5-1.6.tar.gz.asc
/krb5-1.6-pdf.tar.gz
/krb5-1.6.1.tar.gz
/krb5-1.6.1.tar.gz.asc
/krb5-1.6.1-pdf.tar.gz
/krb5-1.6.2.tar.gz
/krb5-1.6.2.tar.gz.asc
/krb5-1.6.2-pdf.tar.gz
/krb5-1.6.3.tar.gz
/krb5-1.6.3.tar.gz.asc
/krb5-1.6.3-pdf.tar.gz
/krb5-1.7.tar.gz
/krb5-1.7.tar.gz.asc
/krb5-1.7-pdf.tar.gz
/krb5-1.7.1.tar.gz
/krb5-1.7.1.tar.gz.asc
/krb5-1.7.1-pdf.tar.gz
/krb5-1.8.tar.gz
/krb5-1.8.tar.gz.asc
/krb5-appl-1.0.tar.gz
/krb5-appl-1.0.tar.gz.asc
/krb5-1.8-pdf.tar.gz
/krb5-1.8.1.tar.gz
/krb5-1.8.1.tar.gz.asc
/krb5-1.8.1-pdf.tar.gz
/krb5-1.8.2.tar.gz.asc
/krb5-1.8.2-pdf.tar.gz
/krb5-1.8.3.tar.gz
/krb5-1.8.3.tar.gz.asc
/krb5-1.8.3-pdf.tar.gz
/krb5-1.9-beta2.tar.gz
/krb5-1.9-beta2.tar.gz.asc
/krb5-1.9-beta2-pdf.tar.bz2
@ -175,3 +176,35 @@ krb5-1.8.3-pdf.tar.gz
/krb5-1.17-pdfs.tar
/krb5-1.17.tar.gz
/krb5-1.17.tar.gz.asc
/krb5-1.17.1.tar.gz
/krb5-1.17.1.tar.gz.asc
/krb5-1.18-beta1.tar.gz
/krb5-1.18-beta1.tar.gz.asc
/krb5-1.18-beta2.tar.gz
/krb5-1.18-beta2.tar.gz.asc
/krb5-1.18.tar.gz
/krb5-1.18.tar.gz.asc
/krb5-1.18.1.tar.gz
/krb5-1.18.1.tar.gz.asc
/krb5-1.18.2.tar.gz
/krb5-1.18.2.tar.gz.asc
/krb5-1.18.3.tar.gz
/krb5-1.18.3.tar.gz.asc
/krb5-1.19-beta1.tar.gz
/krb5-1.19-beta1.tar.gz.asc
/krb5-1.19-beta2.tar.gz
/krb5-1.19-beta2.tar.gz.asc
/krb5-1.19.tar.gz
/krb5-1.19.tar.gz.asc
/krb5-1.19.1.tar.gz
/krb5-1.19.1.tar.gz.asc
/krb5-1.19.2.tar.gz
/krb5-1.19.2.tar.gz.asc
/krb5-1.20.1.tar.gz
/krb5-1.20.1.tar.gz.asc
/krb5-1.21.tar.gz
/krb5-1.21.tar.gz.asc
/krb5-1.21.2.tar.gz
/krb5-1.21.2.tar.gz.asc
/krb5-1.21.3.tar.gz
/krb5-1.21.3.tar.gz.asc

View file

@ -0,0 +1,310 @@
From 6f7fd964539dfe4a885068f43a91db9738661870 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Tue, 9 Jul 2024 11:15:33 +0200
Subject: [PATCH] [downstream] Revert "Don't issue session keys with
deprecated enctypes"
This reverts commit 1b57a4d134bbd0e7c52d5885a92eccc815726463.
---
doc/admin/conf_files/krb5_conf.rst | 12 ------------
doc/admin/enctypes.rst | 23 +++-------------------
src/include/k5-int.h | 4 ----
src/kdc/kdc_util.c | 10 ----------
src/lib/krb5/krb/get_in_tkt.c | 31 +++++++++++-------------------
src/lib/krb5/krb/init_ctx.c | 10 ----------
src/tests/gssapi/t_enctypes.py | 3 +--
src/tests/t_etype_info.py | 2 +-
src/tests/t_sesskeynego.py | 28 ++-------------------------
src/util/k5test.py | 4 ++--
10 files changed, 20 insertions(+), 107 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index ecdf917501..f22d5db11b 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -95,18 +95,6 @@ Additionally, krb5.conf may include any of the relations described in
The libdefaults section may contain any of the following relations:
-**allow_des3**
- Permit the KDC to issue tickets with des3-cbc-sha1 session keys.
- In future releases, this flag will allow des3-cbc-sha1 to be used
- at all. The default value for this tag is false. (Added in
- release 1.21.)
-
-**allow_rc4**
- Permit the KDC to issue tickets with arcfour-hmac session keys.
- In future releases, this flag will allow arcfour-hmac to be used
- at all. The default value for this tag is false. (Added in
- release 1.21.)
-
**allow_weak_crypto**
If this flag is set to false, then weak encryption types (as noted
in :ref:`Encryption_types` in :ref:`kdc.conf(5)`) will be filtered
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
index dce19ad43e..694922c0d9 100644
--- a/doc/admin/enctypes.rst
+++ b/doc/admin/enctypes.rst
@@ -48,15 +48,12 @@ Session key selection
The KDC chooses the session key enctype by taking the intersection of
its **permitted_enctypes** list, the list of long-term keys for the
most recent kvno of the service, and the client's requested list of
-enctypes. Starting in krb5-1.21, all services are assumed to support
-aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session
-keys will not be issued by default.
+enctypes.
Starting in krb5-1.11, it is possible to set a string attribute on a
service principal to control what session key enctypes the KDC may
-issue for service tickets for that principal, overriding the service's
-long-term keys and the assumption of aes256-cts-hmac-sha1-96 support.
-See :ref:`set_string` in :ref:`kadmin(1)` for details.
+issue for service tickets for that principal. See :ref:`set_string`
+in :ref:`kadmin(1)` for details.
Choosing enctypes for a service
@@ -90,20 +87,6 @@ affect how enctypes are chosen.
acceptable risk for your environment and the weak enctypes are
required for backward compatibility.
-**allow_des3**
- was added in release 1.21 and defaults to *false*. Unless this
- flag is set to *true*, the KDC will not issue tickets with
- des3-cbc-sha1 session keys. In a future release, this flag will
- control whether des3-cbc-sha1 is permitted in similar fashion to
- weak enctypes.
-
-**allow_rc4**
- was added in release 1.21 and defaults to *false*. Unless this
- flag is set to *true*, the KDC will not issue tickets with
- arcfour-hmac session keys. In a future release, this flag will
- control whether arcfour-hmac is permitted in similar fashion to
- weak enctypes.
-
**permitted_enctypes**
controls the set of enctypes that a service will permit for
session keys and for ticket and authenticator encryption. The KDC
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 2f7791b775..1d1c8293f4 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -180,8 +180,6 @@ typedef unsigned char u_char;
* matches the variable name. Keep these alphabetized. */
#define KRB5_CONF_ACL_FILE "acl_file"
#define KRB5_CONF_ADMIN_SERVER "admin_server"
-#define KRB5_CONF_ALLOW_DES3 "allow_des3"
-#define KRB5_CONF_ALLOW_RC4 "allow_rc4"
#define KRB5_CONF_ALLOW_WEAK_CRYPTO "allow_weak_crypto"
#define KRB5_CONF_AUTH_TO_LOCAL "auth_to_local"
#define KRB5_CONF_AUTH_TO_LOCAL_NAMES "auth_to_local_names"
@@ -1240,8 +1238,6 @@ struct _krb5_context {
struct _kdb_log_context *kdblog_context;
krb5_boolean allow_weak_crypto;
- krb5_boolean allow_des3;
- krb5_boolean allow_rc4;
krb5_boolean ignore_acceptor_hostname;
krb5_boolean enforce_ok_as_delegate;
enum dns_canonhost dns_canonicalize_hostname;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index e54cc751f9..75e04b73db 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1088,16 +1088,6 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
if (!krb5_is_permitted_enctype(context, ktype[i]))
continue;
- /*
- * Prevent these deprecated enctypes from being used as session keys
- * unless they are explicitly allowed. In the future they will be more
- * comprehensively disabled and eventually removed.
- */
- if (ktype[i] == ENCTYPE_DES3_CBC_SHA1 && !context->allow_des3)
- continue;
- if (ktype[i] == ENCTYPE_ARCFOUR_HMAC && !context->allow_rc4)
- continue;
-
if (dbentry_supports_enctype(context, server, ktype[i]))
return ktype[i];
}
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index ea089f0fcc..1b420a3ac2 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1582,31 +1582,22 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
(*prompter)(context, data, 0, banner, 0, 0);
}
-/* Display a warning via the prompter if a deprecated enctype was used for
- * either the reply key or the session key. */
+/* Display a warning via the prompter if des3-cbc-sha1 was used for either the
+ * reply key or the session key. */
static void
-warn_deprecated(krb5_context context, krb5_init_creds_context ctx,
- krb5_enctype as_key_enctype)
+warn_des3(krb5_context context, krb5_init_creds_context ctx,
+ krb5_enctype as_key_enctype)
{
- krb5_enctype etype;
- char encbuf[128], banner[256];
+ const char *banner;
- if (ctx->prompter == NULL)
- return;
-
- if (krb5int_c_deprecated_enctype(as_key_enctype))
- etype = as_key_enctype;
- else if (krb5int_c_deprecated_enctype(ctx->cred.keyblock.enctype))
- etype = ctx->cred.keyblock.enctype;
- else
+ if (as_key_enctype != ENCTYPE_DES3_CBC_SHA1 &&
+ ctx->cred.keyblock.enctype != ENCTYPE_DES3_CBC_SHA1)
return;
-
- if (krb5_enctype_to_name(etype, FALSE, encbuf, sizeof(encbuf)) != 0)
+ if (ctx->prompter == NULL)
return;
- snprintf(banner, sizeof(banner),
- _("Warning: encryption type %s used for authentication is "
- "deprecated and will be disabled"), encbuf);
+ banner = _("Warning: encryption type des3-cbc-sha1 used for "
+ "authentication is weak and will be disabled");
/* PROMPTER_INVOCATION */
(*ctx->prompter)(context, ctx->prompter_data, NULL, banner, 0, NULL);
}
@@ -1857,7 +1848,7 @@ init_creds_step_reply(krb5_context context,
ctx->complete = TRUE;
warn_pw_expiry(context, ctx->opt, ctx->prompter, ctx->prompter_data,
ctx->in_tkt_service, ctx->reply);
- warn_deprecated(context, ctx, encrypting_key.enctype);
+ warn_des3(context, ctx, encrypting_key.enctype);
cleanup:
krb5_free_pa_data(context, kdc_padata);
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index a6c2bbeb54..87b486c53f 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -221,16 +221,6 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
goto cleanup;
ctx->allow_weak_crypto = tmp;
- retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp);
- if (retval)
- goto cleanup;
- ctx->allow_des3 = tmp;
-
- retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp);
- if (retval)
- goto cleanup;
- ctx->allow_rc4 = tmp;
-
retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp);
if (retval)
goto cleanup;
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index f5f11842e2..7494d7fcdb 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -18,8 +18,7 @@ d_rc4 = 'DEPRECATED:arcfour-hmac'
# These tests make assumptions about the default enctype lists, so set
# them explicitly rather than relying on the library defaults.
supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
-conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4',
- 'allow_des3': 'true', 'allow_rc4': 'true'},
+conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4'},
'realms': {'$realm': {'supported_enctypes': supp}}}
realm = K5Realm(krb5_conf=conf)
shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
index 38cf96ca8f..c982508d8b 100644
--- a/src/tests/t_etype_info.py
+++ b/src/tests/t_etype_info.py
@@ -1,7 +1,7 @@
from k5test import *
supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac'
-conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'},
+conf = {'libdefaults': {'allow_weak_crypto': 'true'},
'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
index 5a213617b5..9024aee838 100755
--- a/src/tests/t_sesskeynego.py
+++ b/src/tests/t_sesskeynego.py
@@ -25,8 +25,6 @@ conf3 = {'libdefaults': {
'default_tkt_enctypes': 'aes128-cts',
'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
-conf5 = {'libdefaults': {'allow_rc4': 'true'}}
-conf6 = {'libdefaults': {'allow_des3': 'true'}}
# Test with client request and session_enctypes preferring aes128, but
# aes256 long-term key.
realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
@@ -56,12 +54,10 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
'aes128-cts,aes256-cts'])
test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
-# 3b: Skip RC4 (as the KDC does not allow it for session keys by
-# default) and negotiate aes128-cts session key, with only an aes256
-# long-term service key.
+# 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term.
realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
'rc4-hmac,aes128-cts,aes256-cts'])
-test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
+test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
realm.stop()
# 4: Check that permitted_enctypes is a default for session key enctypes.
@@ -71,24 +67,4 @@ realm.run([kvno, 'user'],
expected_trace=('etypes requested in TGS request: aes256-cts',))
realm.stop()
-# 5: allow_rc4 permits negotiation of rc4-hmac session key.
-realm = K5Realm(krb5_conf=conf5, create_host=False, get_creds=False)
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
-realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac'])
-test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
-realm.stop()
-
-# 6: allow_des3 permits negotiation of des3-cbc-sha1 session key.
-realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False)
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
-realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1'])
-test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96')
-realm.stop()
-
-# 7: default config negotiates aes256-sha1 session key for RC4-only service.
-realm = K5Realm(create_host=False, get_creds=False)
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server'])
-test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'DEPRECATED:arcfour-hmac')
-realm.stop()
-
success('sesskeynego')
diff --git a/src/util/k5test.py b/src/util/k5test.py
index 8e5f5ba8e9..2a86c5cdfc 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -1340,14 +1340,14 @@ _passes = [
# Exercise the DES3 enctype.
('des3', None,
- {'libdefaults': {'permitted_enctypes': 'des3 aes256-sha1'}},
+ {'libdefaults': {'permitted_enctypes': 'des3'}},
{'realms': {'$realm': {
'supported_enctypes': 'des3-cbc-sha1:normal',
'master_key_type': 'des3-cbc-sha1'}}}),
# Exercise the arcfour enctype.
('arcfour', None,
- {'libdefaults': {'permitted_enctypes': 'rc4 aes256-sha1'}},
+ {'libdefaults': {'permitted_enctypes': 'rc4'}},
{'realms': {'$realm': {
'supported_enctypes': 'arcfour-hmac:normal',
'master_key_type': 'arcfour-hmac'}}}),
--
2.45.1

View file

@ -1,7 +1,7 @@
From c8f2e321b2d8471feee69bbca3179e675228bd8a Mon Sep 17 00:00:00 2001
From de4205c45e310ceaaa7cd7958af7293322fa43a6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:29:58 -0400
Subject: [PATCH] krb5-1.12.1-pam.patch
Subject: [PATCH] [downstream] ksu pam integration
Modify ksu so that it performs account and session management on behalf of
the target user account, mimicking the action of regular su. The default
@ -16,25 +16,28 @@ When enabled, ksu gains a dependency on libpam.
Originally RT#5939, though it's changed since then to perform the account
and session management before dropping privileges, and to apply on top of
changes we're proposing for how it handles cache collections.
Last-updated: krb5-1.18-beta1
---
src/aclocal.m4 | 67 +++++++
src/aclocal.m4 | 69 +++++++
src/clients/ksu/Makefile.in | 8 +-
src/clients/ksu/main.c | 88 +++++++-
src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++
src/clients/ksu/pam.h | 57 ++++++
src/configure.in | 2 +
6 files changed, 608 insertions(+), 3 deletions(-)
src/configure.ac | 2 +
6 files changed, 610 insertions(+), 3 deletions(-)
create mode 100644 src/clients/ksu/pam.c
create mode 100644 src/clients/ksu/pam.h
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 3752d9bd5..340546d80 100644
index 3d66a876b3..ce3c5a9bac 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1697,3 +1697,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
]))
@@ -1458,3 +1458,72 @@ if test "$with_ldap" = yes; then
OPENLDAP_PLUGIN=yes
fi
])dnl
dnl
+dnl
+dnl
+dnl Use PAM instead of local crypt() compare for checking local passwords,
+dnl and perform PAM account, session management, and password-changing where
@ -102,12 +105,13 @@ index 3752d9bd5..340546d80 100644
+AC_SUBST(PAM_MAN)
+AC_SUBST(NON_PAM_MAN)
+])dnl
+
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
index b2fcbf240..5755bb58a 100644
index 8b4edce4d8..9d58f29b5d 100644
--- a/src/clients/ksu/Makefile.in
+++ b/src/clients/ksu/Makefile.in
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S)..
DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"'
KSU_LIBS=@KSU_LIBS@
+PAM_LIBS=@PAM_LIBS@
@ -141,11 +145,11 @@ index b2fcbf240..5755bb58a 100644
clean:
$(RM) ksu
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index d9596d948..ec06788bc 100644
index af12861729..931f054041 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -26,6 +26,7 @@
* KSU was writen by: Ari Medvinsky, ari@isi.edu
* KSU was written by: Ari Medvinsky, ari@isi.edu
*/
+#include "autoconf.h"
@ -171,7 +175,7 @@ index d9596d948..ec06788bc 100644
/***********/
#define KS_TEMPORARY_CACHE "MEMORY:_ksu"
@@ -528,6 +534,23 @@ main (argc, argv)
@@ -536,6 +542,23 @@ main (argc, argv)
prog_name,target_user,client_name,
source_user,ontty());
@ -195,7 +199,7 @@ index d9596d948..ec06788bc 100644
/* Run authorization as target.*/
if (krb5_seteuid(target_uid)) {
com_err(prog_name, errno, _("while switching to target for "
@@ -588,6 +611,24 @@ main (argc, argv)
@@ -596,6 +619,24 @@ main (argc, argv)
exit(1);
}
@ -220,7 +224,7 @@ index d9596d948..ec06788bc 100644
}
if( some_rest_copy){
@@ -645,6 +686,30 @@ main (argc, argv)
@@ -653,6 +694,30 @@ main (argc, argv)
exit(1);
}
@ -251,7 +255,7 @@ index d9596d948..ec06788bc 100644
/* set permissions */
if (setgid(target_pwd->pw_gid) < 0) {
perror("ksu: setgid");
@@ -742,7 +807,7 @@ main (argc, argv)
@@ -750,7 +815,7 @@ main (argc, argv)
fprintf(stderr, "program to be execed %s\n",params[0]);
}
@ -260,7 +264,7 @@ index d9596d948..ec06788bc 100644
execv(params[0], params);
com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
sweep_up(ksu_context, cc_target);
@@ -772,16 +837,35 @@ main (argc, argv)
@@ -780,16 +845,35 @@ main (argc, argv)
if (ret_pid == -1) {
com_err(prog_name, errno, _("while calling waitpid"));
}
@ -299,7 +303,7 @@ index d9596d948..ec06788bc 100644
}
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c
new file mode 100644
index 000000000..cbfe48704
index 0000000000..cbfe487047
--- /dev/null
+++ b/src/clients/ksu/pam.c
@@ -0,0 +1,389 @@
@ -694,7 +698,7 @@ index 000000000..cbfe48704
+#endif
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h
new file mode 100644
index 000000000..0ab76569c
index 0000000000..0ab76569cb
--- /dev/null
+++ b/src/clients/ksu/pam.h
@@ -0,0 +1,57 @@
@ -755,11 +759,11 @@ index 000000000..0ab76569c
+int appl_pam_cred_init(void);
+void appl_pam_cleanup(void);
+#endif
diff --git a/src/configure.in b/src/configure.in
index 61ef738dc..e9a12ac16 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1352,6 +1352,8 @@ AC_SUBST([VERTO_VERSION])
diff --git a/src/configure.ac b/src/configure.ac
index 77be7a2025..587221936e 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1399,6 +1399,8 @@ AC_SUBST([VERTO_VERSION])
AC_PATH_PROG(GROFF, groff)
@ -768,3 +772,6 @@ index 61ef738dc..e9a12ac16 100644
# Make localedir work in autoconf 2.5x.
if test "${localedir+set}" != set; then
localedir='$(datadir)/locale'
--
2.45.1

View file

@ -1,7 +1,7 @@
From e1c4f8894d22da9c157bfcf31e28f9ceaeebe39e Mon Sep 17 00:00:00 2001
From 30ff501e4b519396f5aea25e24919be817863e7c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:30:53 -0400
Subject: [PATCH] krb5-1.17-beta1-selinux-label.patch
Subject: [PATCH] [downstream] SELinux integration
SELinux bases access to files on the domain of the requesting process,
the operation being performed, and the context applied to the file.
@ -35,11 +35,15 @@ stomp all over us.
The selabel APIs for looking up the context should be thread-safe (per
Red Hat #273081), so switching to using them instead of matchpathcon(),
which we used earlier, is some improvement.
Last-updated: krb5-1.20.1
[jrische@redhat.com: Replace deprecated security_context_t by char *:
- src/util/support/selinux.c]
---
src/aclocal.m4 | 49 +++
src/aclocal.m4 | 48 +++
src/build-tools/krb5-config.in | 3 +-
src/config/pre.in | 3 +-
src/configure.in | 2 +
src/configure.ac | 2 +
src/include/k5-int.h | 1 +
src/include/k5-label.h | 32 ++
src/include/krb5/krb5.hin | 6 +
@ -51,7 +55,6 @@ which we used earlier, is some improvement.
src/lib/krb5/ccache/cc_dir.c | 26 +-
src/lib/krb5/keytab/kt_file.c | 4 +-
src/lib/krb5/os/trace.c | 2 +-
src/lib/krb5/rcache/rc_dfl.c | 13 +
src/plugins/kdb/db2/adb_openclose.c | 2 +-
src/plugins/kdb/db2/kdb_db2.c | 4 +-
src/plugins/kdb/db2/libdb2/btree/bt_open.c | 3 +-
@ -60,16 +63,16 @@ which we used earlier, is some improvement.
.../kdb/ldap/ldap_util/kdb5_ldap_services.c | 11 +-
src/util/profile/prof_file.c | 3 +-
src/util/support/Makefile.in | 3 +-
src/util/support/selinux.c | 406 ++++++++++++++++++
25 files changed, 587 insertions(+), 21 deletions(-)
src/util/support/selinux.c | 405 ++++++++++++++++++
24 files changed, 572 insertions(+), 21 deletions(-)
create mode 100644 src/include/k5-label.h
create mode 100644 src/util/support/selinux.c
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 340546d80..a7afec09e 100644
index ce3c5a9bac..3331970930 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -89,6 +89,7 @@ AC_SUBST_FILE(libnodeps_frag)
@@ -85,6 +85,7 @@ AC_SUBST_FILE(libnodeps_frag)
dnl
KRB5_AC_PRAGMA_WEAK_REF
WITH_LDAP
@ -77,7 +80,7 @@ index 340546d80..a7afec09e 100644
KRB5_LIB_PARAMS
KRB5_AC_INITFINI
KRB5_AC_ENABLE_THREADS
@@ -1764,3 +1765,51 @@ AC_SUBST(PAM_LIBS)
@@ -1526,4 +1527,51 @@ AC_SUBST(PAM_LIBS)
AC_SUBST(PAM_MAN)
AC_SUBST(NON_PAM_MAN)
])dnl
@ -100,7 +103,7 @@ index 340546d80..a7afec09e 100644
+ AC_MSG_ERROR([Unable to locate selinux/selinux.h.])
+ fi
+ fi
+
+ LIBS=
+ unset ac_cv_func_setfscreatecon
+ AC_CHECK_FUNCS(setfscreatecon selabel_open)
@ -130,10 +133,10 @@ index 340546d80..a7afec09e 100644
+AC_SUBST(SELINUX_LIBS)
+])dnl
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
index f6184da3f..c17cb5eb5 100755
index 8e6eb86601..7677f37359 100755
--- a/src/build-tools/krb5-config.in
+++ b/src/build-tools/krb5-config.in
@@ -41,6 +41,7 @@ DL_LIB='@DL_LIB@'
@@ -40,6 +40,7 @@ DL_LIB='@DL_LIB@'
DEFCCNAME='@DEFCCNAME@'
DEFKTNAME='@DEFKTNAME@'
DEFCKTNAME='@DEFCKTNAME@'
@ -141,7 +144,7 @@ index f6184da3f..c17cb5eb5 100755
LIBS='@LIBS@'
GEN_LIB=@GEN_LIB@
@@ -255,7 +256,7 @@ if test -n "$do_libs"; then
@@ -253,7 +254,7 @@ if test -n "$do_libs"; then
fi
# If we ever support a flag to generate output suitable for static
@ -151,7 +154,7 @@ index f6184da3f..c17cb5eb5 100755
echo $lib_flags
diff --git a/src/config/pre.in b/src/config/pre.in
index ce87e21ca..917357df9 100644
index a0c60c70b3..7eaa2f351c 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
@ -162,7 +165,7 @@ index ce87e21ca..917357df9 100644
INSTALL=@INSTALL@
INSTALL_STRIP=
@@ -402,7 +403,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
@@ -379,7 +380,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
# HESIOD_LIBS is -lhesiod...
HESIOD_LIBS = @HESIOD_LIBS@
@ -171,11 +174,11 @@ index ce87e21ca..917357df9 100644
KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS)
GSS_LIBS = $(GSS_KRB5_LIB)
# needs fixing if ever used on macOS!
diff --git a/src/configure.in b/src/configure.in
index e9a12ac16..93aec682e 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1354,6 +1354,8 @@ AC_PATH_PROG(GROFF, groff)
diff --git a/src/configure.ac b/src/configure.ac
index 587221936e..69be9030f8 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1401,6 +1401,8 @@ AC_PATH_PROG(GROFF, groff)
KRB5_WITH_PAM
@ -185,7 +188,7 @@ index e9a12ac16..93aec682e 100644
if test "${localedir+set}" != set; then
localedir='$(datadir)/locale'
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 652242207..8f9329c59 100644
index 1d1c8293f4..768110e5ef 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -128,6 +128,7 @@ typedef unsigned char u_char;
@ -198,7 +201,7 @@ index 652242207..8f9329c59 100644
#define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */
diff --git a/src/include/k5-label.h b/src/include/k5-label.h
new file mode 100644
index 000000000..dfaaa847c
index 0000000000..dfaaa847cb
--- /dev/null
+++ b/src/include/k5-label.h
@@ -0,0 +1,32 @@
@ -235,10 +238,10 @@ index 000000000..dfaaa847c
+#endif
+#endif
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index c40a6cca8..3ff86d7ff 100644
index 4e09ed345d..09f800be52 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -87,6 +87,12 @@
@@ -83,6 +83,12 @@
#define THREEPARAMOPEN(x,y,z) open(x,y,z)
#endif
@ -252,7 +255,7 @@ index c40a6cca8..3ff86d7ff 100644
#include <stdlib.h>
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index c9574c6e1..8301a33d0 100644
index a89b5144f6..4d6cc0bdf9 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname)
@ -287,10 +290,10 @@ index c9574c6e1..8301a33d0 100644
com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
goto cleanup;
diff --git a/src/kdc/main.c b/src/kdc/main.c
index 408c723f5..663fd6303 100644
index bfdfef5c48..b43fe9a082 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -858,7 +858,7 @@ write_pid_file(const char *path)
@@ -844,7 +844,7 @@ write_pid_file(const char *path)
FILE *file;
unsigned long pid;
@ -300,7 +303,7 @@ index 408c723f5..663fd6303 100644
return errno;
pid = (unsigned long) getpid();
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
index 68323dd0f..4cc035dc6 100644
index aa3c81ea30..cb9785aaeb 100644
--- a/src/kprop/kpropd.c
+++ b/src/kprop/kpropd.c
@@ -488,6 +488,9 @@ doit(int fd)
@ -330,10 +333,10 @@ index 68323dd0f..4cc035dc6 100644
KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK);
if (retval) {
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
index c6885edf2..9aec3c05e 100644
index e14da53790..b879a4049b 100644
--- a/src/lib/kadm5/logger.c
+++ b/src/lib/kadm5/logger.c
@@ -309,7 +309,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
@@ -310,7 +310,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
*/
append = (cp[4] == ':') ? O_APPEND : 0;
if (append || cp[4] == '=') {
@ -342,7 +345,7 @@ index c6885edf2..9aec3c05e 100644
S_IRUSR | S_IWUSR | S_IRGRP);
if (fd != -1)
f = fdopen(fd, append ? "a" : "w");
@@ -776,7 +776,7 @@ krb5_klog_reopen(krb5_context kcontext)
@@ -777,7 +777,7 @@ krb5_klog_reopen(krb5_context kcontext)
* In case the old logfile did not get moved out of the
* way, open for append to prevent squashing the old logs.
*/
@ -352,7 +355,7 @@ index c6885edf2..9aec3c05e 100644
set_cloexec_file(f);
log_control.log_entries[lindex].lfu_filep = f;
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
index 2659a2501..e9b95fce5 100644
index 2659a25018..e9b95fce59 100644
--- a/src/lib/kdb/kdb_log.c
+++ b/src/lib/kdb/kdb_log.c
@@ -480,7 +480,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
@ -365,7 +368,7 @@ index 2659a2501..e9b95fce5 100644
retval = errno;
goto cleanup;
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
index bba64e516..73f0fe62d 100644
index 1da40b51d0..f3ab7340a6 100644
--- a/src/lib/krb5/ccache/cc_dir.c
+++ b/src/lib/krb5/ccache/cc_dir.c
@@ -183,10 +183,19 @@ write_primary_file(const char *primary_path, const char *contents)
@ -415,10 +418,10 @@ index bba64e516..73f0fe62d 100644
_("Credential cache directory %s does not exist"),
dirname);
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
index 89cb68680..21c80d419 100644
index e510211fc5..f3ea28c8ec 100644
--- a/src/lib/krb5/keytab/kt_file.c
+++ b/src/lib/krb5/keytab/kt_file.c
@@ -1024,14 +1024,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
@@ -735,14 +735,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
KTCHECKLOCK(id);
errno = 0;
@ -436,10 +439,10 @@ index 89cb68680..21c80d419 100644
goto report_errno;
writevno = 1;
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index 4fff8f38c..40a9e7b10 100644
index 4cbbbb270a..c4058ddc96 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -458,7 +458,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
@@ -460,7 +460,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
fd = malloc(sizeof(*fd));
if (fd == NULL)
return ENOMEM;
@ -448,40 +451,8 @@ index 4fff8f38c..40a9e7b10 100644
if (*fd == -1) {
free(fd);
return errno;
diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
index 1e0cb22c9..f5e93b1ab 100644
--- a/src/lib/krb5/rcache/rc_dfl.c
+++ b/src/lib/krb5/rcache/rc_dfl.c
@@ -793,6 +793,9 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
krb5_error_code retval = 0;
krb5_rcache tmp;
krb5_deltat lifespan = t->lifespan; /* save original lifespan */
+#ifdef USE_SELINUX
+ void *selabel;
+#endif
if (! t->recovering) {
name = t->name;
@@ -814,7 +817,17 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
retval = krb5_rc_resolve(context, tmp, 0);
if (retval)
goto cleanup;
+#ifdef USE_SELINUX
+ if (t->d.fn != NULL)
+ selabel = krb5int_push_fscreatecon_for(t->d.fn);
+ else
+ selabel = NULL;
+#endif
retval = krb5_rc_initialize(context, tmp, lifespan);
+#ifdef USE_SELINUX
+ if (selabel != NULL)
+ krb5int_pop_fscreatecon(selabel);
+#endif
if (retval)
goto cleanup;
for (q = t->a; q; q = q->na) {
diff --git a/src/plugins/kdb/db2/adb_openclose.c b/src/plugins/kdb/db2/adb_openclose.c
index 7db30a33b..2b9d01921 100644
index 9a506e9d44..f92ab47143 100644
--- a/src/plugins/kdb/db2/adb_openclose.c
+++ b/src/plugins/kdb/db2/adb_openclose.c
@@ -152,7 +152,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename,
@ -494,7 +465,7 @@ index 7db30a33b..2b9d01921 100644
* maybe someone took away write permission so we could only
* get shared locks?
diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
index 5106a5c99..e481e8121 100644
index 2c163d91cc..9a344a603e 100644
--- a/src/plugins/kdb/db2/kdb_db2.c
+++ b/src/plugins/kdb/db2/kdb_db2.c
@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc)
@ -509,7 +480,7 @@ index 5106a5c99..e481e8121 100644
retval = errno;
goto cleanup;
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
index 2977b17f3..d5809a5a9 100644
index 2977b17f3a..d5809a5a93 100644
--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c
+++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8.11 (Berkeley) 11/2/95";
@ -530,7 +501,7 @@ index 2977b17f3..d5809a5a9 100644
} else {
diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c
index 862dbb164..686a960c9 100644
index 862dbb1640..686a960c96 100644
--- a/src/plugins/kdb/db2/libdb2/hash/hash.c
+++ b/src/plugins/kdb/db2/libdb2/hash/hash.c
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 (Berkeley) 11/7/95";
@ -551,7 +522,7 @@ index 862dbb164..686a960c9 100644
(void)fcntl(hashp->fp, F_SETFD, 1);
}
diff --git a/src/plugins/kdb/db2/libdb2/recno/rec_open.c b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
index d8b26e701..b0daa7c02 100644
index d8b26e7011..b0daa7c021 100644
--- a/src/plugins/kdb/db2/libdb2/recno/rec_open.c
+++ b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c 8.12 (Berkeley) 11/18/94";
@ -573,10 +544,10 @@ index d8b26e701..b0daa7c02 100644
if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
index 1ed72afe9..ce038fc3d 100644
index e87688d666..30f7c00ab5 100644
--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
@@ -194,7 +194,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
@@ -190,7 +190,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
/* set password in the file */
old_mode = umask(0177);
@ -585,7 +556,7 @@ index 1ed72afe9..ce038fc3d 100644
if (pfile == NULL) {
com_err(me, errno, _("Failed to open file %s: %s"), file_name,
strerror (errno));
@@ -235,6 +235,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
@@ -231,6 +231,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
* Delete the existing entry and add the new entry
*/
FILE *newfile;
@ -595,7 +566,7 @@ index 1ed72afe9..ce038fc3d 100644
mode_t omask;
@@ -246,7 +249,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
@@ -242,7 +245,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
}
omask = umask(077);
@ -610,7 +581,7 @@ index 1ed72afe9..ce038fc3d 100644
if (newfile == NULL) {
com_err(me, errno, _("Error creating file %s"), tmp_file);
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
index 24e41fb80..0dcb6b543 100644
index aa951df05f..79f9500f69 100644
--- a/src/util/profile/prof_file.c
+++ b/src/util/profile/prof_file.c
@@ -33,6 +33,7 @@
@ -631,10 +602,10 @@ index 24e41fb80..0dcb6b543 100644
retval = errno;
if (retval == 0)
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index db7b030b8..321672bcb 100644
index 86d5a950a6..1052d53a1e 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -69,6 +69,7 @@ IPC_SYMS= \
@@ -74,6 +74,7 @@ IPC_SYMS= \
STLIBOBJS= \
threads.o \
@ -642,7 +613,7 @@ index db7b030b8..321672bcb 100644
init-addrinfo.o \
plugins.o \
errors.o \
@@ -160,7 +161,7 @@ SRCS=\
@@ -168,7 +169,7 @@ SRCS=\
SHLIB_EXPDEPS =
# Add -lm if dumping thread stats, for sqrt.
@ -653,10 +624,10 @@ index db7b030b8..321672bcb 100644
diff --git a/src/util/support/selinux.c b/src/util/support/selinux.c
new file mode 100644
index 000000000..6d41f3244
index 0000000000..807d039da3
--- /dev/null
+++ b/src/util/support/selinux.c
@@ -0,0 +1,406 @@
@@ -0,0 +1,405 @@
+/*
+ * Copyright 2007,2008,2009,2011,2012,2013,2016 Red Hat, Inc. All Rights Reserved.
+ *
@ -755,17 +726,16 @@ index 000000000..6d41f3244
+ }
+}
+
+static security_context_t
+static char *
+push_fscreatecon(const char *pathname, mode_t mode)
+{
+ security_context_t previous, configuredsc, currentsc, derivedsc;
+ char *previous, *configuredsc, *currentsc, *genpath;
+ const char *derivedsc, *fullpath, *currentuser;
+ context_t current, derived;
+ const char *fullpath, *currentuser;
+ char *genpath;
+
+ previous = configuredsc = currentsc = derivedsc = NULL;
+ previous = configuredsc = currentsc = genpath = NULL;
+ derivedsc = NULL;
+ current = derived = NULL;
+ genpath = NULL;
+
+ fullpath = pathname;
+
@ -893,7 +863,7 @@ index 000000000..6d41f3244
+}
+
+static void
+pop_fscreatecon(security_context_t previous)
+pop_fscreatecon(char *previous)
+{
+ if (!is_selinux_enabled()) {
+ return;
@ -947,7 +917,7 @@ index 000000000..6d41f3244
+{
+ FILE *fp;
+ int errno_save;
+ security_context_t ctx;
+ char *ctx;
+
+ if ((strcmp(mode, "r") == 0) ||
+ (strcmp(mode, "rb") == 0)) {
@ -973,7 +943,7 @@ index 000000000..6d41f3244
+{
+ int fd;
+ int errno_save;
+ security_context_t ctx;
+ char *ctx;
+
+ k5_once(&labeled_once, label_mutex_init);
+ k5_mutex_lock(&labeled_mutex);
@ -994,7 +964,7 @@ index 000000000..6d41f3244
+{
+ int ret;
+ int errno_save;
+ security_context_t ctx;
+ char *ctx;
+
+ k5_once(&labeled_once, label_mutex_init);
+ k5_mutex_lock(&labeled_mutex);
@ -1015,7 +985,7 @@ index 000000000..6d41f3244
+{
+ int ret;
+ int errno_save;
+ security_context_t ctx;
+ char *ctx;
+
+ k5_once(&labeled_once, label_mutex_init);
+ k5_mutex_lock(&labeled_mutex);
@ -1036,7 +1006,7 @@ index 000000000..6d41f3244
+{
+ int fd;
+ int errno_save;
+ security_context_t ctx;
+ char *ctx;
+ mode_t mode;
+ va_list ap;
+
@ -1063,3 +1033,6 @@ index 000000000..6d41f3244
+}
+
+#endif /* USE_SELINUX */
--
2.45.1

View file

@ -1,18 +1,20 @@
From 8ee5efa6aec5d02e25081b6dc809cef668ce45ea Mon Sep 17 00:00:00 2001
From 393830d96000ed692aa9a99ef87187d6f2863931 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:25 -0400
Subject: [PATCH] krb5-1.9-debuginfo.patch
Subject: [PATCH] [downstream] fix debuginfo with y.tab.c
We want to keep these y.tab.c files around because the debuginfo points to
them. It would be more elegant at the end to use symbolic links, but that
could mess up people working in the tree on other things.
Last-updated: krb5-1.9
---
src/kadmin/cli/Makefile.in | 5 +++++
src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in
index adfea6e2b..d1327e400 100644
index adfea6e2b5..d1327e400b 100644
--- a/src/kadmin/cli/Makefile.in
+++ b/src/kadmin/cli/Makefile.in
@@ -37,3 +37,8 @@ clean-unix::
@ -25,7 +27,7 @@ index adfea6e2b..d1327e400 100644
+ $(YACC.y) $<
+ $(CP) y.tab.c $@
diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in
index 8669c2436..a22f23c02 100644
index 8669c2436c..a22f23c02c 100644
--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in
+++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE)
@ -37,3 +39,6 @@ index 8669c2436..a22f23c02 100644
install:
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
--
2.45.1

File diff suppressed because it is too large Load diff

View file

@ -1,32 +1,218 @@
From 105bd2c8be23ab94ba6e0601ee8e531f013389d6 Mon Sep 17 00:00:00 2001
From 7b6453903c248a761d3ceb538dfacebbf3d3a9ff Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 31 Jul 2018 13:47:26 -0400
Subject: [PATCH] krb5-1.17 In FIPS mode, add plaintext fallback for RC4 usages
and taint
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] [downstream] FIPS with PRNG and RADIUS and MD4
NB: Use openssl's PRNG in FIPS mode and taint within krad.
A lot of the FIPS error conditions from OpenSSL are incredibly
mysterious (at best, things return NULL unexpectedly; at worst,
internal assertions are tripped; most of the time, you just get
ENOMEM). In order to cope with this, we need to have some level of
awareness of what we can and can't safely call.
This will slow down some calls slightly (FIPS_mode() takes multiple
locks), but not for any ciphers we care about - which is to say that
AES is fine. Shame about SPAKE though.
post6 restores MD4 (and therefore keygen-only RC4).
post7 restores MD5 and adds radius_md5_fips_override.
post8 silences a static analyzer warning.
Last-updated: krb5-1.20
---
src/lib/krad/attr.c | 45 +++++++++++++++++++++++++++++-----------
src/lib/krad/attrset.c | 5 +++--
src/lib/krad/internal.h | 13 ++++++++++--
src/lib/krad/packet.c | 22 +++++++++++---------
src/lib/krad/remote.c | 10 +++++++--
src/lib/krad/t_attr.c | 3 ++-
src/lib/krad/t_attrset.c | 4 +++-
7 files changed, 72 insertions(+), 30 deletions(-)
doc/admin/conf_files/krb5_conf.rst | 6 +++
src/lib/crypto/krb/prng.c | 15 +++++-
.../crypto/openssl/enc_provider/camellia.c | 6 +++
src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++++-
.../crypto/openssl/hash_provider/hash_evp.c | 12 +++++
src/lib/crypto/openssl/hmac.c | 6 ++-
src/lib/krad/attr.c | 46 ++++++++++++++-----
src/lib/krad/attrset.c | 5 +-
src/lib/krad/internal.h | 28 ++++++++++-
src/lib/krad/packet.c | 22 +++++----
src/lib/krad/remote.c | 10 +++-
src/lib/krad/t_attr.c | 3 +-
src/lib/krad/t_attrset.c | 4 +-
src/plugins/preauth/spake/spake_client.c | 6 +++
src/plugins/preauth/spake/spake_kdc.c | 6 +++
15 files changed, 155 insertions(+), 33 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index f22d5db11b..a33711d918 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -330,6 +330,12 @@ The libdefaults section may contain any of the following relations:
qualification of shortnames, set this relation to the empty string
with ``qualify_shortname = ""``. (New in release 1.18.)
+**radius_md5_fips_override**
+ Downstream-only option to enable use of MD5 in RADIUS
+ communication (libkrad). This allows for local (or protected
+ tunnel) communication with a RADIUS server that doesn't use krad
+ (e.g., freeradius) while in FIPS mode.
+
**rdns**
If this flag is true, reverse name lookup will be used in addition
to forward name lookup to canonicalizing hostnames for use in
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index d6b79e2dea..9e80a03d21 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -26,6 +26,12 @@
#include "crypto_int.h"
+#include <openssl/rand.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+#include <openssl/crypto.h>
+#endif
+
krb5_error_code KRB5_CALLCONV
krb5_c_random_seed(krb5_context context, krb5_data *data)
{
@@ -96,9 +102,16 @@ cleanup:
static krb5_boolean
get_os_entropy(unsigned char *buf, size_t len)
{
-#if defined(__linux__) && defined(SYS_getrandom)
int r;
+ /* A wild FIPS mode appeared! */
+ if (FIPS_mode()) {
+ /* The return codes on this API are not good */
+ r = RAND_bytes(buf, len);
+ return r == 1;
+ }
+
+#if defined(__linux__) && defined(SYS_getrandom)
while (len > 0) {
/*
* Pull from the /dev/urandom pool, but require it to have been seeded.
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 01920e6ce1..d9f327add6 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -387,6 +387,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
struct iov_cursor cursor;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
if (output->length < CAMELLIA_BLOCK_SIZE)
return KRB5_BAD_MSIZE;
@@ -418,6 +421,9 @@ static krb5_error_code
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
krb5_data *state)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
state->length = 16;
state->data = (void *) malloc(16);
if (state->data == NULL)
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index 448d563348..ce63cb5f1b 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -69,6 +69,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx = NULL;
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
arcstate = (state != NULL) ? (void *)state->data : NULL;
if (arcstate != NULL) {
ctx = arcstate->ctx;
@@ -116,7 +119,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
static void
k5_arcfour_free_state(krb5_data *state)
{
- struct arcfour_state *arcstate = (void *)state->data;
+ struct arcfour_state *arcstate;
+
+ if (FIPS_mode())
+ return;
+
+ arcstate = (void *) state->data;
EVP_CIPHER_CTX_free(arcstate->ctx);
free(arcstate);
@@ -128,6 +136,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
{
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
/*
* The cipher state here is a saved pointer to a struct arcfour_state
* object, rather than a flat byte array as in most enc providers. The
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index f2fbffdb29..11659908bb 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -60,6 +60,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
if (ctx == NULL)
return ENOMEM;
+ if (type == EVP_md4() || type == EVP_md5()) {
+ /* See comments below in hash_md4() and hash_md5(). */
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ }
+
ok = EVP_DigestInit_ex(ctx, type, NULL);
for (i = 0; i < num_data; i++) {
if (!SIGN_IOV(&data[i]))
@@ -78,6 +83,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
static krb5_error_code
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ /*
+ * MD4 is needed in FIPS mode to perform key generation for RC4 keys used
+ * by IPA. These keys are only used along a (separately) secured channel
+ * for legacy reasons when performing trusts to Active Directory.
+ */
return hash_evp(EVP_md4(), data, num_data, output);
}
@@ -90,6 +100,8 @@ const struct krb5_hash_provider krb5int_hash_md4 = {
static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ /* MD5 is needed in FIPS mode for communication with RADIUS servers. This
+ * is gated in libkrad by libdefaults->radius_md5_fips_override. */
return hash_evp(EVP_md5(), data, num_data, output);
}
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index bf12b8d6a0..f21e268f7f 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -111,7 +111,11 @@ map_digest(const struct krb5_hash_provider *hash)
return EVP_sha256();
else if (hash == &krb5int_hash_sha384)
return EVP_sha384();
- else if (hash == &krb5int_hash_md5)
+
+ if (FIPS_mode())
+ return NULL;
+
+ if (hash == &krb5int_hash_md5)
return EVP_md5();
else if (hash == &krb5int_hash_md4)
return EVP_md4();
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
index 9c13d9d75..275327e67 100644
index 9c13d9d755..42d354a3b5 100644
--- a/src/lib/krad/attr.c
+++ b/src/lib/krad/attr.c
@@ -30,6 +30,7 @@
#include <k5-int.h>
#include "internal.h"
+#include <openssl/crypto.h>
#include <string.h>
/* RFC 2865 */
@@ -38,7 +39,8 @@
@@ -38,7 +38,8 @@
typedef krb5_error_code
(*attribute_transform_fn)(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
@ -36,7 +222,7 @@ index 9c13d9d75..275327e67 100644
typedef struct {
const char *name;
@@ -51,12 +53,14 @@ typedef struct {
@@ -51,12 +52,14 @@ typedef struct {
static krb5_error_code
user_password_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
@ -53,7 +239,7 @@ index 9c13d9d75..275327e67 100644
static const attribute_record attributes[UCHAR_MAX] = {
{"User-Name", 1, MAX_ATTRSIZE, NULL, NULL},
@@ -128,7 +132,8 @@ static const attribute_record attributes[UCHAR_MAX] = {
@@ -128,7 +131,8 @@ static const attribute_record attributes[UCHAR_MAX] = {
static krb5_error_code
user_password_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
@ -63,20 +249,21 @@ index 9c13d9d75..275327e67 100644
{
const unsigned char *indx;
krb5_error_code retval;
@@ -154,8 +159,14 @@ user_password_encode(krb5_context ctx, const char *secret,
@@ -154,8 +158,15 @@ user_password_encode(krb5_context ctx, const char *secret,
for (blck = 0, indx = auth; blck * BLOCKSIZE < len; blck++) {
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
- &sum);
+ if (FIPS_mode()) {
+ if (kr_use_fips(ctx)) {
+ /* Skip encryption here. Taint so that we won't pass it out of
+ * the machine by accident. */
+ *is_fips = TRUE;
+ sum.contents = calloc(1, BLOCKSIZE);
+ } else
+ } else {
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
+ &sum);
+ }
if (retval != 0) {
zap(tmp.data, tmp.length);
zap(outbuf, len);
@ -90,24 +277,25 @@ index 9c13d9d75..275327e67 100644
{
const unsigned char *indx;
krb5_error_code retval;
@@ -204,8 +216,14 @@ user_password_decode(krb5_context ctx, const char *secret,
@@ -204,8 +216,15 @@ user_password_decode(krb5_context ctx, const char *secret,
for (blck = 0, indx = auth; blck * BLOCKSIZE < in->length; blck++) {
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
- &tmp, &sum);
+ if (FIPS_mode()) {
+ if (kr_use_fips(ctx)) {
+ /* Skip encryption here. Taint so that we won't pass it out of
+ * the machine by accident. */
+ *is_fips = TRUE;
+ sum.contents = calloc(1, BLOCKSIZE);
+ } else
+ } else {
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
+ &tmp, &sum);
+ }
if (retval != 0) {
zap(tmp.data, tmp.length);
zap(outbuf, in->length);
@@ -248,7 +266,7 @@ krb5_error_code
@@ -248,7 +267,7 @@ krb5_error_code
kr_attr_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, krad_attr type,
const krb5_data *in, unsigned char outbuf[MAX_ATTRSIZE],
@ -116,7 +304,7 @@ index 9c13d9d75..275327e67 100644
{
krb5_error_code retval;
@@ -265,7 +283,8 @@ kr_attr_encode(krb5_context ctx, const char *secret,
@@ -265,7 +284,8 @@ kr_attr_encode(krb5_context ctx, const char *secret,
return 0;
}
@ -126,7 +314,7 @@ index 9c13d9d75..275327e67 100644
}
krb5_error_code
@@ -274,6 +293,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
@@ -274,6 +294,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
{
krb5_error_code retval;
@ -134,7 +322,7 @@ index 9c13d9d75..275327e67 100644
retval = kr_attr_valid(type, in);
if (retval != 0)
@@ -288,7 +308,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
@@ -288,7 +309,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
return 0;
}
@ -145,7 +333,7 @@ index 9c13d9d75..275327e67 100644
krad_attr
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
index 03c613716..d89982a13 100644
index f309f1581c..6ec031e320 100644
--- a/src/lib/krad/attrset.c
+++ b/src/lib/krad/attrset.c
@@ -167,7 +167,8 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
@ -168,10 +356,19 @@ index 03c613716..d89982a13 100644
return retval;
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
index 996a89372..a53ce31ce 100644
index 7619563fc5..e123763954 100644
--- a/src/lib/krad/internal.h
+++ b/src/lib/krad/internal.h
@@ -49,6 +49,13 @@
@@ -39,6 +39,8 @@
#include <sys/socket.h>
#include <netdb.h>
+#include <openssl/crypto.h>
+
#ifndef UCHAR_MAX
#define UCHAR_MAX 255
#endif
@@ -49,6 +51,13 @@
typedef struct krad_remote_st krad_remote;
@ -185,7 +382,7 @@ index 996a89372..a53ce31ce 100644
/* Validate constraints of an attribute. */
krb5_error_code
kr_attr_valid(krad_attr type, const krb5_data *data);
@@ -57,7 +64,8 @@ kr_attr_valid(krad_attr type, const krb5_data *data);
@@ -57,7 +66,8 @@ kr_attr_valid(krad_attr type, const krb5_data *data);
krb5_error_code
kr_attr_encode(krb5_context ctx, const char *secret, const unsigned char *auth,
krad_attr type, const krb5_data *in,
@ -195,7 +392,7 @@ index 996a89372..a53ce31ce 100644
/* Decode an attribute. */
krb5_error_code
@@ -69,7 +77,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
@@ -69,7 +79,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
krb5_error_code
kr_attrset_encode(const krad_attrset *set, const char *secret,
const unsigned char *auth,
@ -205,19 +402,29 @@ index 996a89372..a53ce31ce 100644
/* Decode attributes from a buffer. */
krb5_error_code
@@ -156,4 +167,17 @@ gai_error_code(int err)
}
}
+static inline krb5_boolean
+kr_use_fips(krb5_context ctx)
+{
+ int val = 0;
+
+ if (!FIPS_mode())
+ return 0;
+
+ (void)profile_get_boolean(ctx->profile, "libdefaults",
+ "radius_md5_fips_override", NULL, 0, &val);
+ return !val;
+}
+
#endif /* INTERNAL_H_ */
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
index c597174b6..794ac84c4 100644
index c597174b65..fc2d248001 100644
--- a/src/lib/krad/packet.c
+++ b/src/lib/krad/packet.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <arpa/inet.h>
+#include <openssl/crypto.h>
typedef unsigned char uchar;
@@ -53,12 +54,6 @@ typedef unsigned char uchar;
@@ -53,12 +53,6 @@ typedef unsigned char uchar;
#define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH))
#define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR))
@ -230,19 +437,20 @@ index c597174b6..794ac84c4 100644
typedef struct {
uchar x[(UCHAR_MAX + 1) / 8];
} idmap;
@@ -187,8 +182,13 @@ auth_generate_response(krb5_context ctx, const char *secret,
@@ -187,8 +181,14 @@ auth_generate_response(krb5_context ctx, const char *secret,
memcpy(data.data + response->pkt.length, secret, strlen(secret));
/* Hash it. */
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
- &hash);
+ if (FIPS_mode()) {
+ if (kr_use_fips(ctx)) {
+ /* This checksum does very little security-wise anyway, so don't
+ * taint. */
+ hash.contents = calloc(1, AUTH_FIELD_SIZE);
+ } else
+ } else {
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
+ &hash);
+ }
free(data.data);
if (retval != 0)
return retval;
@ -274,7 +482,7 @@ index c597174b6..794ac84c4 100644
}
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
index 437f7e91a..0f90443ce 100644
index 06ae751bc8..929f1cef67 100644
--- a/src/lib/krad/remote.c
+++ b/src/lib/krad/remote.c
@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr)
@ -295,7 +503,7 @@ index 437f7e91a..0f90443ce 100644
request_finish(r, 0, rsp);
break;
}
@@ -455,6 +455,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
@@ -460,6 +460,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
(krad_packet_iter_cb)iterator, &r, &tmp);
if (retval != 0)
goto error;
@ -309,7 +517,7 @@ index 437f7e91a..0f90443ce 100644
K5_TAILQ_FOREACH(r, &rr->list, list) {
if (r->request == tmp) {
diff --git a/src/lib/krad/t_attr.c b/src/lib/krad/t_attr.c
index eb2a780c8..4d285ad9d 100644
index eb2a780c89..4d285ad9de 100644
--- a/src/lib/krad/t_attr.c
+++ b/src/lib/krad/t_attr.c
@@ -50,6 +50,7 @@ main()
@ -330,7 +538,7 @@ index eb2a780c8..4d285ad9d 100644
insist(len == sizeof(encoded));
insist(memcmp(outbuf, encoded, len) == 0);
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
index 7928335ca..0f9576253 100644
index 7928335ca4..0f95762534 100644
--- a/src/lib/krad/t_attrset.c
+++ b/src/lib/krad/t_attrset.c
@@ -49,6 +49,7 @@ main()
@ -351,3 +559,54 @@ index 7928335ca..0f9576253 100644
krad_attrset_free(set);
/* Manually encode User-Name. */
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
index 00734a13b5..a3ce22b70f 100644
--- a/src/plugins/preauth/spake/spake_client.c
+++ b/src/plugins/preauth/spake/spake_client.c
@@ -38,6 +38,8 @@
#include "groups.h"
#include <krb5/clpreauth_plugin.h>
+#include <openssl/crypto.h>
+
typedef struct reqstate_st {
krb5_pa_spake *msg; /* set in prep_questions, used in process */
krb5_keyblock *initial_key;
@@ -375,6 +377,10 @@ clpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
if (maj_ver != 1)
return KRB5_PLUGIN_VER_NOTSUPP;
+
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
vt = (krb5_clpreauth_vtable)vtable;
vt->name = "spake";
vt->pa_type_list = pa_types;
diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
index 1a772d450f..232e78bc05 100644
--- a/src/plugins/preauth/spake/spake_kdc.c
+++ b/src/plugins/preauth/spake/spake_kdc.c
@@ -41,6 +41,8 @@
#include <krb5/kdcpreauth_plugin.h>
+#include <openssl/crypto.h>
+
/*
* The SPAKE kdcpreauth module uses a secure cookie containing the following
* concatenated fields (all integer fields are big-endian):
@@ -551,6 +553,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
if (maj_ver != 1)
return KRB5_PLUGIN_VER_NOTSUPP;
+
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
vt = (krb5_kdcpreauth_vtable)vtable;
vt->name = "spake";
vt->pa_type_list = pa_types;
--
2.45.1

View file

@ -0,0 +1,82 @@
From 707fa7bd2be6327343dc8fc5c20dc77645524518 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Thu, 5 May 2022 17:15:12 +0200
Subject: [PATCH] [downstream] Allow krad UDP/TCP localhost connection
with FIPS
libkrad allows to establish connections only to UNIX socket in FIPS
mode, because MD5 digest is not considered safe enough to be used for
network communication. However, FreeRadius requires connection on TCP or
UDP ports.
This commit allows TCP or UDP connections in FIPS mode if destination is
localhost.
Resolves: rhbz#2082189
---
src/lib/krad/remote.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
index 929f1cef67..063f17a613 100644
--- a/src/lib/krad/remote.c
+++ b/src/lib/krad/remote.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <unistd.h>
+#include <stdbool.h>
#include <sys/un.h>
@@ -74,6 +75,35 @@ on_io(verto_ctx *ctx, verto_ev *ev);
static void
on_timeout(verto_ctx *ctx, verto_ev *ev);
+static in_addr_t get_in_addr(struct addrinfo *info)
+{ return ((struct sockaddr_in *)(info->ai_addr))->sin_addr.s_addr; }
+
+static struct in6_addr *get_in6_addr(struct addrinfo *info)
+{ return &(((struct sockaddr_in6 *)(info->ai_addr))->sin6_addr); }
+
+static bool is_inet_localhost(struct addrinfo *info)
+{
+ struct addrinfo *p;
+
+ for (p = info; p; p = p->ai_next) {
+ switch (p->ai_family) {
+ case AF_INET:
+ if (IN_LOOPBACKNET != (get_in_addr(p) & IN_CLASSA_NET
+ >> IN_CLASSA_NSHIFT))
+ return false;
+ break;
+ case AF_INET6:
+ if (!IN6_IS_ADDR_LOOPBACK(get_in6_addr(p)))
+ return false;
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
/* Iterate over the set of outstanding packets. */
static const krad_packet *
iterator(request **out)
@@ -460,8 +490,9 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
(krad_packet_iter_cb)iterator, &r, &tmp);
if (retval != 0)
goto error;
- else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL &&
- rr->info->ai_family != AF_UNIX) {
+ else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL
+ && rr->info->ai_family != AF_UNIX
+ && !is_inet_localhost(rr->info)) {
/* This would expose cleartext passwords, so abort. */
retval = ESOCKTNOSUPPORT;
goto error;
--
2.45.1

View file

@ -0,0 +1,41 @@
From 1da88bea558348be2974470774aa688f8be634c0 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Wed, 7 Dec 2022 13:22:42 +0100
Subject: [PATCH] [downstream] Make tests compatible with
sssd_krb5_locator_plugin.so
The sssd_krb5_locator_plugin.so plugin provided by sssd-client conflicts
with the upstream test t_discover_uri.py. The test has to be modified in
order to avoid false positive.
---
src/lib/krb5/os/t_discover_uri.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/lib/krb5/os/t_discover_uri.py b/src/lib/krb5/os/t_discover_uri.py
index 87bac17929..26bc95a8dc 100644
--- a/src/lib/krb5/os/t_discover_uri.py
+++ b/src/lib/krb5/os/t_discover_uri.py
@@ -1,3 +1,4 @@
+from os.path import exists
from k5test import *
entries = ('URI _kerberos.TEST krb5srv::kkdcp:https://kdc1 1 1\n',
@@ -37,8 +38,14 @@ realm.env['RESOLV_WRAPPER_HOSTS'] = hosts_filename
out = realm.run(['./t_locate_kdc', 'TEST'], env=realm.env)
l = out.splitlines()
+if (exists('/usr/lib/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')
+ or exists('/usr/lib64/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')):
+ line_range = range(6, 14)
+else:
+ line_range = range(4, 12)
+
j = 0
-for i in range(4, 12):
+for i in line_range:
if l[i].strip() != expected[j]:
fail('URI answers do not match')
j += 1
--
2.45.1

View file

@ -0,0 +1,120 @@
From 775ed8588cc21385fb16a4cec4a861f0d578ce04 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Thu, 5 Jan 2023 20:06:47 +0100
Subject: [PATCH] [downstream] Include missing OpenSSL FIPS header
The inclusion of openssl/fips.h, which provides the declaration of
FIPS_mode(), was removed from openssl/crypto.h. As a consequence, this
header file has to be included explicitly in krb5 code.
---
src/lib/crypto/krb/prng.c | 4 +++-
src/lib/crypto/openssl/enc_provider/camellia.c | 1 +
src/lib/crypto/openssl/enc_provider/rc4.c | 4 ++++
src/lib/crypto/openssl/hmac.c | 1 +
src/lib/krad/internal.h | 4 ++++
src/plugins/preauth/spake/spake_client.c | 4 ++++
src/plugins/preauth/spake/spake_kdc.c | 4 ++++
7 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index 9e80a03d21..ae37c77518 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -28,7 +28,9 @@
#include <openssl/rand.h>
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/fips.h>
+#else
#include <openssl/crypto.h>
#endif
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index d9f327add6..3dd3b0624f 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -32,6 +32,7 @@
#include <openssl/camellia.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/core_names.h>
+#include <openssl/fips.h>
#else
#include <openssl/modes.h>
#endif
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index ce63cb5f1b..6a83f10d27 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -38,6 +38,10 @@
#include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/fips.h>
+#endif
+
/*
* The loopback field is a pointer to the structure. If the application copies
* the state (not a valid operation, but one which happens to works with some
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index f21e268f7f..25a419d73a 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -59,6 +59,7 @@
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/params.h>
#include <openssl/core_names.h>
+#include <openssl/fips.h>
#else
#include <openssl/hmac.h>
#endif
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
index e123763954..a17b6f39b1 100644
--- a/src/lib/krad/internal.h
+++ b/src/lib/krad/internal.h
@@ -41,6 +41,10 @@
#include <openssl/crypto.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/fips.h>
+#endif
+
#ifndef UCHAR_MAX
#define UCHAR_MAX 255
#endif
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
index a3ce22b70f..13c699071f 100644
--- a/src/plugins/preauth/spake/spake_client.c
+++ b/src/plugins/preauth/spake/spake_client.c
@@ -40,6 +40,10 @@
#include <openssl/crypto.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/fips.h>
+#endif
+
typedef struct reqstate_st {
krb5_pa_spake *msg; /* set in prep_questions, used in process */
krb5_keyblock *initial_key;
diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
index 232e78bc05..3394f8a58e 100644
--- a/src/plugins/preauth/spake/spake_kdc.c
+++ b/src/plugins/preauth/spake/spake_kdc.c
@@ -43,6 +43,10 @@
#include <openssl/crypto.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/fips.h>
+#endif
+
/*
* The SPAKE kdcpreauth module uses a secure cookie containing the following
* concatenated fields (all integer fields are big-endian):
--
2.45.1

View file

@ -0,0 +1,31 @@
From 4fd20741afcf76085ea62eb015cd589bb9392a7b Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Mon, 9 Jan 2023 22:39:52 +0100
Subject: [PATCH] [downstream] Do not set root as ksu file owner
Upstream Makefile uses the install command to set root as owner of the
ksu executable file. However, this is no longer supported on latest
versions of the Mock build environment.
In case of ksu, the owner, group, and mode are already set using %attr()
in the specfile.
---
src/config/pre.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/config/pre.in b/src/config/pre.in
index 7eaa2f351c..e9ae71471e 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
INSTALL_SCRIPT=@INSTALL_PROGRAM@
INSTALL_DATA=@INSTALL_DATA@
INSTALL_SHLIB=@INSTALL_SHLIB@
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
+INSTALL_SETUID=$(INSTALL)
## This is needed because autoconf will sometimes define @exec_prefix@ to be
## ${prefix}.
prefix=@prefix@
--
2.45.1

View file

@ -0,0 +1,165 @@
From 16f90c007036789d8d9343e8a0cbabfd21853b5a Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Thu, 19 Jan 2023 19:22:27 +0100
Subject: [PATCH] [downstream] Allow KRB5KDF, MD5, and MD4 in FIPS mode
OpenSSL's restrictions to use KRB5KDF, MD5, and MD4 in FIPS mode are
bypassed in case AES SHA-1 HMAC or RC4 encryption types are allowed by
the crypto policy.
---
.../crypto/openssl/hash_provider/hash_evp.c | 97 +++++++++++++++++--
src/lib/crypto/openssl/kdf.c | 2 +-
2 files changed, 89 insertions(+), 10 deletions(-)
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index 11659908bb..eb2e693e9f 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -44,6 +44,49 @@
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#endif
+#include <openssl/provider.h>
+#include <openssl/fips.h>
+#include <threads.h>
+
+typedef struct ossl_lib_md_context {
+ OSSL_LIB_CTX *libctx;
+ OSSL_PROVIDER *default_provider;
+ OSSL_PROVIDER *legacy_provider;
+} ossl_md_context_t;
+
+static thread_local ossl_md_context_t *ossl_md_ctx = NULL;
+
+static krb5_error_code
+init_ossl_md_ctx(ossl_md_context_t *ctx, const char *algo)
+{
+ ctx->libctx = OSSL_LIB_CTX_new();
+ if (!ctx->libctx)
+ return KRB5_CRYPTO_INTERNAL;
+
+ /* Load both legacy and default provider as both may be needed. */
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
+
+ if (!(ctx->default_provider && ctx->legacy_provider))
+ return KRB5_CRYPTO_INTERNAL;
+
+ return 0;
+}
+
+static void
+deinit_ossl_ctx(ossl_md_context_t *ctx)
+{
+ if (ctx->legacy_provider)
+ OSSL_PROVIDER_unload(ctx->legacy_provider);
+
+ if (ctx->default_provider)
+ OSSL_PROVIDER_unload(ctx->default_provider);
+
+ if (ctx->libctx)
+ OSSL_LIB_CTX_free(ctx->libctx);
+}
+
+
static krb5_error_code
hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
krb5_data *output)
@@ -60,11 +103,6 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
if (ctx == NULL)
return ENOMEM;
- if (type == EVP_md4() || type == EVP_md5()) {
- /* See comments below in hash_md4() and hash_md5(). */
- EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- }
-
ok = EVP_DigestInit_ex(ctx, type, NULL);
for (i = 0; i < num_data; i++) {
if (!SIGN_IOV(&data[i]))
@@ -77,6 +115,43 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
return ok ? 0 : KRB5_CRYPTO_INTERNAL;
}
+static krb5_error_code
+hash_legacy_evp(const char *algo, const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ krb5_error_code err;
+ EVP_MD *md = NULL;
+
+ if (!ossl_md_ctx) {
+ ossl_md_ctx = malloc(sizeof(ossl_md_context_t));
+ if (!ossl_md_ctx) {
+ err = ENOMEM;
+ goto end;
+ }
+
+ err = init_ossl_md_ctx(ossl_md_ctx, algo);
+ if (err) {
+ deinit_ossl_ctx(ossl_md_ctx);
+ free(ossl_md_ctx);
+ ossl_md_ctx = NULL;
+ goto end;
+ }
+ }
+
+ md = EVP_MD_fetch(ossl_md_ctx->libctx, algo, NULL);
+ if (!md) {
+ err = KRB5_CRYPTO_INTERNAL;
+ goto end;
+ }
+
+ err = hash_evp(md, data, num_data, output);
+
+end:
+ if (md)
+ EVP_MD_free(md);
+
+ return err;
+}
#endif
#ifdef K5_OPENSSL_MD4
@@ -88,7 +163,8 @@ hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
* by IPA. These keys are only used along a (separately) secured channel
* for legacy reasons when performing trusts to Active Directory.
*/
- return hash_evp(EVP_md4(), data, num_data, output);
+ return FIPS_mode() ? hash_legacy_evp("MD4", data, num_data, output)
+ : hash_evp(EVP_md4(), data, num_data, output);
}
const struct krb5_hash_provider krb5int_hash_md4 = {
@@ -100,9 +176,12 @@ const struct krb5_hash_provider krb5int_hash_md4 = {
static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
- /* MD5 is needed in FIPS mode for communication with RADIUS servers. This
- * is gated in libkrad by libdefaults->radius_md5_fips_override. */
- return hash_evp(EVP_md5(), data, num_data, output);
+ /*
+ * MD5 is needed in FIPS mode for communication with RADIUS servers. This
+ * is gated in libkrad by libdefaults->radius_md5_fips_override.
+ */
+ return FIPS_mode() ? hash_legacy_evp("MD5", data, num_data, output)
+ : hash_evp(EVP_md5(), data, num_data, output);
}
const struct krb5_hash_provider krb5int_hash_md5 = {
diff --git a/src/lib/crypto/openssl/kdf.c b/src/lib/crypto/openssl/kdf.c
index 5a43c3d9eb..8528ddc4a9 100644
--- a/src/lib/crypto/openssl/kdf.c
+++ b/src/lib/crypto/openssl/kdf.c
@@ -198,7 +198,7 @@ k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key,
goto done;
}
- kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL);
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips");
if (kdf == NULL) {
ret = KRB5_CRYPTO_INTERNAL;
goto done;
--
2.45.1

View file

@ -0,0 +1,280 @@
From 23b58199db429603802e338db530677b61561335 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Wed, 15 Mar 2023 15:56:34 +0100
Subject: [PATCH] [downstream] Allow to set PAC ticket signature as
optional
MS-PAC states that "The ticket signature SHOULD be included in tickets
that are not encrypted to the krbtgt account". However, the
implementation of krb5_kdc_verify_ticket() will require the ticket
signature to be present in case the target of the request is a service
principal.
In gradual upgrade environments, it results in S4U2Proxy requests
against a 1.20 KDC using a service ticket generated by an older version
KDC to fail.
This commit adds a krb5_kdc_verify_ticket_ext() function with an extra
switch parameter to tolerate the absence of ticket signature in this
scenario. If the ticket signature is present, it has to be valid,
regardless of this parameter.
This parameter is set based on the "optional_pac_tkt_chksum" string
attribute of the TGT KDB entry.
---
doc/admin/admin_commands/kadmin_local.rst | 6 ++++
doc/appdev/refs/api/index.rst | 1 +
src/include/kdb.h | 1 +
src/include/krb5/krb5.hin | 40 +++++++++++++++++++++++
src/kdc/kdc_util.c | 32 ++++++++++++++----
src/lib/krb5/krb/pac.c | 31 +++++++++++++++---
src/lib/krb5/libkrb5.exports | 1 +
src/man/kadmin.man | 6 ++++
8 files changed, 108 insertions(+), 10 deletions(-)
diff --git a/doc/admin/admin_commands/kadmin_local.rst b/doc/admin/admin_commands/kadmin_local.rst
index 2435b3c361..58ac79549f 100644
--- a/doc/admin/admin_commands/kadmin_local.rst
+++ b/doc/admin/admin_commands/kadmin_local.rst
@@ -658,6 +658,12 @@ KDC:
Directory realm when using aes-sha2 keys on the local krbtgt
entry.
+**optional_pac_tkt_chksum**
+ Boolean value defining the behavior of the KDC in case an expected
+ ticket checksum signed with one of this principal keys is not
+ present in the PAC. This is typically the case for TGS or
+ cross-realm TGS principals when processing S4U2Proxy requests.
+
This command requires the **modify** privilege.
Alias: **setstr**
diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst
index d12be47c3c..9b95ebd0f9 100644
--- a/doc/appdev/refs/api/index.rst
+++ b/doc/appdev/refs/api/index.rst
@@ -225,6 +225,7 @@ Rarely used public interfaces
krb5_is_referral_realm.rst
krb5_kdc_sign_ticket.rst
krb5_kdc_verify_ticket.rst
+ krb5_kdc_verify_ticket_ext.rst
krb5_kt_add_entry.rst
krb5_kt_end_seq_get.rst
krb5_kt_get_entry.rst
diff --git a/src/include/kdb.h b/src/include/kdb.h
index 745b24f351..6075349e5e 100644
--- a/src/include/kdb.h
+++ b/src/include/kdb.h
@@ -136,6 +136,7 @@
#define KRB5_KDB_SK_PAC_PRIVSVR_ENCTYPE "pac_privsvr_enctype"
#define KRB5_KDB_SK_SESSION_ENCTYPES "session_enctypes"
#define KRB5_KDB_SK_REQUIRE_AUTH "require_auth"
+#define KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM "optional_pac_tkt_chksum"
#if !defined(_WIN32)
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index c5a625db8f..2d9b64dc85 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -8329,6 +8329,46 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
const krb5_keyblock *server,
const krb5_keyblock *privsvr, krb5_pac *pac_out);
+/**
+ * Verify a PAC, possibly including ticket signature
+ *
+ * @param [in] context Library context
+ * @param [in] enc_tkt Ticket enc-part, possibly containing a PAC
+ * @param [in] server_princ Canonicalized name of ticket server
+ * @param [in] server Key to validate server checksum (or NULL)
+ * @param [in] privsvr Key to validate KDC checksum (or NULL)
+ * @paran [in] optional_tkt_chksum Whether to require a ticket checksum
+ * @param [out] pac_out Verified PAC (NULL if no PAC included)
+ *
+ * This function is an extension of krb5_kdc_verify_ticket(), adding the @a
+ * optional_tkt_chksum parameter allowing to tolerate the absence of the PAC
+ * ticket signature.
+ *
+ * If a PAC is present in @a enc_tkt, verify its signatures. If @a privsvr is
+ * not NULL and @a server_princ is not a krbtgt or kadmin/changepw service and
+ * @a optional_tkt_chksum is FALSE, require a ticket signature over @a enc_tkt
+ * in addition to the KDC signature. Place the verified PAC in @a pac_out. If
+ * an invalid PAC signature is found, return an error matching the Windows KDC
+ * protocol code for that condition as closely as possible.
+ *
+ * If no PAC is present in @a enc_tkt, set @a pac_out to NULL and return
+ * successfully.
+ *
+ * @note This function does not validate the PAC_CLIENT_INFO buffer. If a
+ * specific value is expected, the caller can make a separate call to
+ * krb5_pac_verify_ext() with a principal but no keys.
+ *
+ * @retval 0 Success; otherwise - Kerberos error codes
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_kdc_verify_ticket_ext(krb5_context context,
+ const krb5_enc_tkt_part *enc_tkt,
+ krb5_const_principal server_princ,
+ const krb5_keyblock *server,
+ const krb5_keyblock *privsvr,
+ krb5_boolean optional_tkt_chksum,
+ krb5_pac *pac_out);
+
/** @deprecated Use krb5_kdc_sign_ticket() instead. */
krb5_error_code KRB5_CALLCONV
krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index fe4e48209a..93415ba862 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -560,16 +560,36 @@ cleanup:
static krb5_error_code
try_verify_pac(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
krb5_db_entry *server, krb5_keyblock *server_key,
- const krb5_keyblock *tgt_key, krb5_pac *pac_out)
+ krb5_db_entry *tgt, const krb5_keyblock *tgt_key,
+ krb5_pac *pac_out)
{
krb5_error_code ret;
+ krb5_boolean optional_tkt_chksum;
+ char *str = NULL;
krb5_keyblock *privsvr_key;
ret = pac_privsvr_key(context, server, tgt_key, &privsvr_key);
if (ret)
return ret;
- ret = krb5_kdc_verify_ticket(context, enc_tkt, server->princ, server_key,
- privsvr_key, pac_out);
+
+ /* Check if the absence of ticket signature is tolerated for this realm */
+ ret = krb5_dbe_get_string(context, tgt,
+ KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM, &str);
+ /* TODO: should be using _krb5_conf_boolean(), but os-proto.h is not
+ * available here.
+ */
+ optional_tkt_chksum = !ret && str && (strncasecmp(str, "true", 4) == 0
+ || strncasecmp(str, "t", 1) == 0
+ || strncasecmp(str, "yes", 3) == 0
+ || strncasecmp(str, "y", 1) == 0
+ || strncasecmp(str, "1", 1) == 0
+ || strncasecmp(str, "on", 2) == 0);
+
+ krb5_dbe_free_string(context, str);
+
+ ret = krb5_kdc_verify_ticket_ext(context, enc_tkt, server->princ,
+ server_key, privsvr_key,
+ optional_tkt_chksum, pac_out);
krb5_free_keyblock(context, privsvr_key);
return ret;
}
@@ -599,7 +619,7 @@ get_verified_pac(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
server_key, NULL, pac_out);
}
- ret = try_verify_pac(context, enc_tkt, server, server_key, tgt_key,
+ ret = try_verify_pac(context, enc_tkt, server, server_key, tgt, tgt_key,
pac_out);
if (ret != KRB5KRB_AP_ERR_MODIFIED && ret != KRB5_BAD_ENCTYPE)
return ret;
@@ -613,8 +633,8 @@ get_verified_pac(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
ret = krb5_dbe_decrypt_key_data(context, NULL, kd, &old_key, NULL);
if (ret)
return ret;
- ret = try_verify_pac(context, enc_tkt, server, server_key, &old_key,
- pac_out);
+ ret = try_verify_pac(context, enc_tkt, server, server_key, tgt,
+ &old_key, pac_out);
krb5_free_keyblock_contents(context, &old_key);
if (!ret)
return 0;
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
index 5d1fdf1ba0..0c0e2ada68 100644
--- a/src/lib/krb5/krb/pac.c
+++ b/src/lib/krb5/krb/pac.c
@@ -594,6 +594,19 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
krb5_const_principal server_princ,
const krb5_keyblock *server,
const krb5_keyblock *privsvr, krb5_pac *pac_out)
+{
+ return krb5_kdc_verify_ticket_ext(context, enc_tkt, server_princ, server,
+ privsvr, FALSE, pac_out);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_kdc_verify_ticket_ext(krb5_context context,
+ const krb5_enc_tkt_part *enc_tkt,
+ krb5_const_principal server_princ,
+ const krb5_keyblock *server,
+ const krb5_keyblock *privsvr,
+ krb5_boolean optional_tkt_chksum,
+ krb5_pac *pac_out)
{
krb5_error_code ret;
krb5_pac pac = NULL;
@@ -602,7 +615,7 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
krb5_authdata *orig, **ifrel = NULL, **recoded_ifrel = NULL;
uint8_t z = 0;
krb5_authdata zpac = { KV5M_AUTHDATA, KRB5_AUTHDATA_WIN2K_PAC, 1, &z };
- krb5_boolean is_service_tkt;
+ krb5_boolean is_service_tkt, has_tkt_chksum = FALSE;
size_t i, j;
*pac_out = NULL;
@@ -667,11 +680,21 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
ret = verify_checksum(context, pac, KRB5_PAC_TICKET_CHECKSUM, privsvr,
KRB5_KEYUSAGE_APP_DATA_CKSUM, recoded_tkt);
- if (ret)
- goto cleanup;
+ if (ret) {
+ if (!optional_tkt_chksum)
+ goto cleanup;
+ else if (ret != ENOENT)
+ goto cleanup;
+ /* Otherwise ticket signature is absent but optional. Proceed... */
+ } else {
+ has_tkt_chksum = TRUE;
+ }
}
+ /* Else, we make the assumption the ticket signature is absent in case this
+ * is not a service ticket.
+ */
- ret = verify_pac_checksums(context, pac, is_service_tkt, server, privsvr);
+ ret = verify_pac_checksums(context, pac, has_tkt_chksum, server, privsvr);
if (ret)
goto cleanup;
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
index 4c50e935a2..d4b0455c8c 100644
--- a/src/lib/krb5/libkrb5.exports
+++ b/src/lib/krb5/libkrb5.exports
@@ -463,6 +463,7 @@ krb5_is_thread_safe
krb5_kdc_rep_decrypt_proc
krb5_kdc_sign_ticket
krb5_kdc_verify_ticket
+krb5_kdc_verify_ticket_ext
krb5_kt_add_entry
krb5_kt_client_default
krb5_kt_close
diff --git a/src/man/kadmin.man b/src/man/kadmin.man
index 8413e70ccd..f68eb0569d 100644
--- a/src/man/kadmin.man
+++ b/src/man/kadmin.man
@@ -724,6 +724,12 @@ encryption type. It may be necessary to set this value to
"aes256\-sha1" on the cross\-realm krbtgt entry for an Active
Directory realm when using aes\-sha2 keys on the local krbtgt
entry.
+.TP
+\fBoptional_pac_tkt_chksum\fP
+Boolean value defining the behavior of the KDC in case an expected ticket
+checksum signed with one of this principal keys is not present in the PAC. This
+is typically the case for TGS or cross-realm TGS principals when processing
+S4U2Proxy requests.
.UNINDENT
.sp
This command requires the \fBmodify\fP privilege.
--
2.45.1

View file

@ -0,0 +1,47 @@
From 31b9debcf2cbd558f8f315fefb69fc8206b115b4 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Tue, 23 May 2023 12:19:54 +0200
Subject: [PATCH] [downstream] Make PKINIT CMS SHA-1 signature
verification available in FIPS mode
We recommend using the SHA1 crypto-module in order to allow the
verification of SHA-1 signature for CMS messages. However, this module
does not work in FIPS mode, because the SHA-1 algorithm is absent from
the OpenSSL FIPS provider.
This commit enables the signature verification process to fetch the
algorithm from a non-FIPS OpenSSL provider.
Support for SHA-1 CMS signature is still required, especially in order
to interoperate with Active Directory. At least it is until elliptic
curve cryptography is implemented for PKINIT in MIT krb5.
---
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index cb9c79626c..17dd18e37d 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -1844,8 +1844,17 @@ cms_signeddata_verify(krb5_context context,
if (oid == NULL)
goto cleanup;
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ /* Do not use FIPS provider (even in FIPS mode) because it keeps from
+ * allowing SHA-1 signature verification using the SHA1 crypto-module
+ */
+ cms = CMS_ContentInfo_new_ex(NULL, "-fips");
+ if (!cms)
+ goto cleanup;
+#endif
+
/* decode received CMS message */
- if ((cms = d2i_CMS_ContentInfo(NULL, &p, (int)signed_data_len)) == NULL) {
+ if (!d2i_CMS_ContentInfo(&cms, &p, (int)signed_data_len)) {
retval = oerr(context, 0, _("Failed to decode CMS message"));
goto cleanup;
}
--
2.45.1

View file

@ -0,0 +1,218 @@
From c24c9faf859ddc04910a6bc591d8ddb2ada93e80 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 30 May 2023 01:21:48 -0400
Subject: [PATCH] Enable PKINIT if at least one group is available
OpenSSL may no longer allow decoding of non-well-known Diffie-Hellman
group parameters as EVP_PKEY objects in FIPS mode. However, OpenSSL
does not know about MODP group 2 (1024-bit), which is considered as a
custom group. As a consequence, the PKINIT kdcpreauth module fails to
load in FIPS mode.
Allow initialization of PKINIT plugin if at least one of the MODP
well-known group parameters successfully decodes.
[ghudson@mit.edu: minor commit message and code edits]
ticket: 9096 (new)
(cherry picked from commit 509d8db922e9ad6f108883838473b6178f89874a)
---
src/plugins/preauth/pkinit/pkinit_clnt.c | 2 +-
src/plugins/preauth/pkinit/pkinit_crypto.h | 3 +-
.../preauth/pkinit/pkinit_crypto_openssl.c | 76 +++++++++++--------
src/plugins/preauth/pkinit/pkinit_srv.c | 2 +-
src/plugins/preauth/pkinit/pkinit_trace.h | 3 +
5 files changed, 51 insertions(+), 35 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index 725d5bc438..ea9ba454df 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -1378,7 +1378,7 @@ pkinit_client_plugin_init(krb5_context context,
if (retval)
goto errout;
- retval = pkinit_init_plg_crypto(&ctx->cryptoctx);
+ retval = pkinit_init_plg_crypto(context, &ctx->cryptoctx);
if (retval)
goto errout;
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
index 9fa315d7a0..8bdbea8e95 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
@@ -103,7 +103,8 @@ typedef struct _pkinit_cert_matching_data {
/*
* Functions to initialize and cleanup crypto contexts
*/
-krb5_error_code pkinit_init_plg_crypto(pkinit_plg_crypto_context *);
+krb5_error_code pkinit_init_plg_crypto(krb5_context,
+ pkinit_plg_crypto_context *);
void pkinit_fini_plg_crypto(pkinit_plg_crypto_context);
krb5_error_code pkinit_init_req_crypto(pkinit_req_crypto_context *);
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 17dd18e37d..8cdc40bfb4 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -47,7 +47,8 @@
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
-static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context );
+static krb5_error_code pkinit_init_dh_params(krb5_context,
+ pkinit_plg_crypto_context);
static void pkinit_fini_dh_params(pkinit_plg_crypto_context );
static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx);
@@ -951,7 +952,8 @@ oerr_cert(krb5_context context, krb5_error_code code, X509_STORE_CTX *certctx,
}
krb5_error_code
-pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx)
+pkinit_init_plg_crypto(krb5_context context,
+ pkinit_plg_crypto_context *cryptoctx)
{
krb5_error_code retval = ENOMEM;
pkinit_plg_crypto_context ctx = NULL;
@@ -969,7 +971,7 @@ pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx)
if (retval)
goto out;
- retval = pkinit_init_dh_params(ctx);
+ retval = pkinit_init_dh_params(context, ctx);
if (retval)
goto out;
@@ -1278,30 +1280,36 @@ pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
ASN1_OBJECT_free(ctx->id_kp_serverAuth);
}
-static krb5_error_code
-pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
+static int
+try_import_group(krb5_context context, const krb5_data *params,
+ const char *name, EVP_PKEY **pkey_out)
{
- krb5_error_code retval = ENOMEM;
-
- plgctx->dh_1024 = decode_dh_params(&oakley_1024);
- if (plgctx->dh_1024 == NULL)
- goto cleanup;
-
- plgctx->dh_2048 = decode_dh_params(&oakley_2048);
- if (plgctx->dh_2048 == NULL)
- goto cleanup;
+ *pkey_out = decode_dh_params(params);
+ if (*pkey_out == NULL)
+ TRACE_PKINIT_DH_GROUP_UNAVAILABLE(context, name);
+ return (*pkey_out != NULL) ? 1 : 0;
+}
- plgctx->dh_4096 = decode_dh_params(&oakley_4096);
- if (plgctx->dh_4096 == NULL)
- goto cleanup;
+static krb5_error_code
+pkinit_init_dh_params(krb5_context context, pkinit_plg_crypto_context plgctx)
+{
+ int n = 0;
- retval = 0;
+ n += try_import_group(context, &oakley_1024, "MODP 2 (1024-bit)",
+ &plgctx->dh_1024);
+ n += try_import_group(context, &oakley_2048, "MODP 14 (2048-bit)",
+ &plgctx->dh_2048);
+ n += try_import_group(context, &oakley_4096, "MODP 16 (4096-bit)",
+ &plgctx->dh_4096);
-cleanup:
- if (retval)
+ if (n == 0) {
pkinit_fini_dh_params(plgctx);
+ k5_setmsg(context, ENOMEM,
+ _("PKINIT cannot initialize any key exchange groups"));
+ return ENOMEM;
+ }
- return retval;
+ return 0;
}
static void
@@ -2912,11 +2920,11 @@ client_create_dh(krb5_context context,
if (cryptoctx->received_params != NULL)
params = cryptoctx->received_params;
- else if (dh_size == 1024)
+ else if (plg_cryptoctx->dh_1024 != NULL && dh_size == 1024)
params = plg_cryptoctx->dh_1024;
- else if (dh_size == 2048)
+ else if (plg_cryptoctx->dh_2048 != NULL && dh_size == 2048)
params = plg_cryptoctx->dh_2048;
- else if (dh_size == 4096)
+ else if (plg_cryptoctx->dh_4096 != NULL && dh_size == 4096)
params = plg_cryptoctx->dh_4096;
else
goto cleanup;
@@ -3212,19 +3220,23 @@ pkinit_create_td_dh_parameters(krb5_context context,
krb5_algorithm_identifier alg_4096 = { dh_oid, oakley_4096 };
krb5_algorithm_identifier *alglist[4];
- if (opts->dh_min_bits > 4096) {
- ret = KRB5KRB_ERR_GENERIC;
- goto cleanup;
- }
-
i = 0;
- if (opts->dh_min_bits <= 2048)
+ if (plg_cryptoctx->dh_2048 != NULL && opts->dh_min_bits <= 2048)
alglist[i++] = &alg_2048;
- alglist[i++] = &alg_4096;
- if (opts->dh_min_bits <= 1024)
+ if (plg_cryptoctx->dh_4096 != NULL && opts->dh_min_bits <= 4096)
+ alglist[i++] = &alg_4096;
+ if (plg_cryptoctx->dh_1024 != NULL && opts->dh_min_bits <= 1024)
alglist[i++] = &alg_1024;
alglist[i] = NULL;
+ if (i == 0) {
+ ret = KRB5KRB_ERR_GENERIC;
+ k5_setmsg(context, ret,
+ _("OpenSSL has no supported key exchange groups for "
+ "pkinit_dh_min_bits=%d"), opts->dh_min_bits);
+ goto cleanup;
+ }
+
ret = k5int_encode_krb5_td_dh_parameters(alglist, &der_alglist);
if (ret)
goto cleanup;
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index 1b3bf6d4d0..768a4e559f 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -1222,7 +1222,7 @@ pkinit_server_plugin_init_realm(krb5_context context, const char *realmname,
goto errout;
plgctx->realmname_len = strlen(plgctx->realmname);
- retval = pkinit_init_plg_crypto(&plgctx->cryptoctx);
+ retval = pkinit_init_plg_crypto(context, &plgctx->cryptoctx);
if (retval)
goto errout;
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
index 259e95c6c2..5ee39c085c 100644
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
@@ -90,6 +90,9 @@
#define TRACE_PKINIT_CLIENT_TRYAGAIN(c) \
TRACE(c, "PKINIT client trying again with KDC-provided parameters")
+#define TRACE_PKINIT_DH_GROUP_UNAVAILABLE(c, name) \
+ TRACE(c, "PKINIT key exchange group {str} unsupported", name)
+
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \
TRACE(c, "PKINIT OpenSSL error: {str}", msg)
--
2.45.1

View file

@ -0,0 +1,64 @@
From e92365b510a2407eaceaec90836f5c713403d75f Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Wed, 19 Jul 2023 13:43:17 +0200
Subject: [PATCH] Replace ssl.wrap_socket() for tests
The ssl.wrap_socket() function was deprecated in Python 3.7 and is
removed in Python 3.12. The ssl.SSLContext.wrap_socket() method
replaces it.
Bump the required Python version for tests to 3.4 for
ssl.create_default_context().
[ghudson@mit.edu: changed minimum Python version]
(cherry picked from commit 0ceab6c363e65fb21d3312a663f2b9b569ecc415)
---
src/configure.ac | 9 ++++-----
src/util/wsgiref-kdcproxy.py | 4 +++-
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/configure.ac b/src/configure.ac
index 2561e917a2..487f393146 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1157,10 +1157,9 @@ AC_SUBST(PKINIT)
# for lib/apputils
AC_REPLACE_FUNCS(daemon)
-# For Python tests. Python version 3.2.4 is required as prior
-# versions do not accept string input to subprocess.Popen.communicate
-# when universal_newlines is set.
-PYTHON_MINVERSION=3.2.4
+# For Python tests. Python version 3.4 is required for
+# ssl.create_default_context().
+PYTHON_MINVERSION=3.4
AC_SUBST(PYTHON_MINVERSION)
AC_CHECK_PROG(PYTHON,python3,python3)
if test x"$PYTHON" = x; then
@@ -1168,7 +1167,7 @@ if test x"$PYTHON" = x; then
fi
HAVE_PYTHON=no
if test x"$PYTHON" != x; then
- wantver="(sys.hexversion >= 0x30204F0)"
+ wantver="(sys.hexversion >= 0x30400F0)"
if "$PYTHON" -c "import sys; sys.exit(not $wantver and 1 or 0)"; then
HAVE_PYTHON=yes
fi
diff --git a/src/util/wsgiref-kdcproxy.py b/src/util/wsgiref-kdcproxy.py
index 58759696b6..d1d10d733c 100755
--- a/src/util/wsgiref-kdcproxy.py
+++ b/src/util/wsgiref-kdcproxy.py
@@ -14,6 +14,8 @@ else:
pem = '*'
server = make_server('localhost', port, kdcproxy.Application())
-server.socket = ssl.wrap_socket(server.socket, certfile=pem, server_side=True)
+sslctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
+sslctx.load_cert_chain(certfile=pem)
+server.socket = sslctx.wrap_socket(server.socket, server_side=True)
os.write(sys.stdout.fileno(), b'proxy server ready\n')
server.serve_forever()
--
2.45.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,206 @@
From ee66c1feedb57ce06ce51aaa823f9a61f564c58e Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 5 Mar 2024 19:53:07 -0500
Subject: [PATCH] Fix two unlikely memory leaks
In gss_krb5int_make_seal_token_v3(), one of the bounds checks (which
could probably never be triggered) leaks plain.data. Fix this leak
and use current practices for cleanup throughout the function.
In xmt_rmtcallres() (unused within the tree and likely elsewhere),
store port_ptr into crp->port_ptr as soon as it is allocated;
otherwise it could leak if the subsequent xdr_u_int32() operation
fails.
(cherry picked from commit c5f9c816107f70139de11b38aa02db2f1774ee0d)
---
src/lib/gssapi/krb5/k5sealv3.c | 56 +++++++++++++++-------------------
src/lib/rpc/pmap_rmt.c | 10 +++---
2 files changed, 29 insertions(+), 37 deletions(-)
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
index 1fcbdfbb87..d3210c1107 100644
--- a/src/lib/gssapi/krb5/k5sealv3.c
+++ b/src/lib/gssapi/krb5/k5sealv3.c
@@ -65,7 +65,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
int conf_req_flag, int toktype)
{
size_t bufsize = 16;
- unsigned char *outbuf = 0;
+ unsigned char *outbuf = NULL;
krb5_error_code err;
int key_usage;
unsigned char acceptor_flag;
@@ -75,9 +75,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
#endif
size_t ec;
unsigned short tok_id;
- krb5_checksum sum;
+ krb5_checksum sum = { 0 };
krb5_key key;
krb5_cksumtype cksumtype;
+ krb5_data plain = empty_data();
+
+ token->value = NULL;
+ token->length = 0;
acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR;
key_usage = (toktype == KG_TOK_WRAP_MSG
@@ -107,14 +111,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
#endif
if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) {
- krb5_data plain;
krb5_enc_data cipher;
size_t ec_max;
size_t encrypt_size;
/* 300: Adds some slop. */
- if (SIZE_MAX - 300 < message->length)
- return ENOMEM;
+ if (SIZE_MAX - 300 < message->length) {
+ err = ENOMEM;
+ goto cleanup;
+ }
ec_max = SIZE_MAX - message->length - 300;
if (ec_max > 0xffff)
ec_max = 0xffff;
@@ -126,20 +131,20 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
#endif
err = alloc_data(&plain, message->length + 16 + ec);
if (err)
- return err;
+ goto cleanup;
/* Get size of ciphertext. */
encrypt_size = krb5_encrypt_size(plain.length, key->keyblock.enctype);
if (encrypt_size > SIZE_MAX / 2) {
err = ENOMEM;
- goto error;
+ goto cleanup;
}
bufsize = 16 + encrypt_size;
/* Allocate space for header plus encrypted data. */
outbuf = gssalloc_malloc(bufsize);
if (outbuf == NULL) {
- free(plain.data);
- return ENOMEM;
+ err = ENOMEM;
+ goto cleanup;
}
/* TOK_ID */
@@ -164,11 +169,8 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
cipher.ciphertext.length = bufsize - 16;
cipher.enctype = key->keyblock.enctype;
err = krb5_k_encrypt(context, key, key_usage, 0, &plain, &cipher);
- zap(plain.data, plain.length);
- free(plain.data);
- plain.data = 0;
if (err)
- goto error;
+ goto cleanup;
/* Now that we know we're returning a valid token.... */
ctx->seq_send++;
@@ -181,7 +183,6 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
/* If the rotate fails, don't worry about it. */
#endif
} else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) {
- krb5_data plain;
size_t cksumsize;
/* Here, message is the application-supplied data; message2 is
@@ -193,21 +194,19 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
wrap_with_checksum:
err = alloc_data(&plain, message->length + 16);
if (err)
- return err;
+ goto cleanup;
err = krb5_c_checksum_length(context, cksumtype, &cksumsize);
if (err)
- goto error;
+ goto cleanup;
assert(cksumsize <= 0xffff);
bufsize = 16 + message2->length + cksumsize;
outbuf = gssalloc_malloc(bufsize);
if (outbuf == NULL) {
- free(plain.data);
- plain.data = 0;
err = ENOMEM;
- goto error;
+ goto cleanup;
}
/* TOK_ID */
@@ -239,23 +238,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
if (message2->length)
memcpy(outbuf + 16, message2->value, message2->length);
- sum.contents = outbuf + 16 + message2->length;
- sum.length = cksumsize;
-
err = krb5_k_make_checksum(context, cksumtype, key,
key_usage, &plain, &sum);
- zap(plain.data, plain.length);
- free(plain.data);
- plain.data = 0;
if (err) {
zap(outbuf,bufsize);
- goto error;
+ goto cleanup;
}
if (sum.length != cksumsize)
abort();
memcpy(outbuf + 16 + message2->length, sum.contents, cksumsize);
- krb5_free_checksum_contents(context, &sum);
- sum.contents = 0;
/* Now that we know we're actually generating the token... */
ctx->seq_send++;
@@ -285,12 +276,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
token->value = outbuf;
token->length = bufsize;
- return 0;
+ outbuf = NULL;
+ err = 0;
-error:
+cleanup:
+ krb5_free_checksum_contents(context, &sum);
+ zapfree(plain.data, plain.length);
gssalloc_free(outbuf);
- token->value = NULL;
- token->length = 0;
return err;
}
diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c
index 434e4eea65..f55ca46c60 100644
--- a/src/lib/rpc/pmap_rmt.c
+++ b/src/lib/rpc/pmap_rmt.c
@@ -161,12 +161,12 @@ xdr_rmtcallres(
caddr_t port_ptr;
port_ptr = (caddr_t)(void *)crp->port_ptr;
- if (xdr_reference(xdrs, &port_ptr, sizeof (uint32_t),
- (xdrproc_t)xdr_u_int32) &&
- xdr_u_int32(xdrs, &crp->resultslen)) {
- crp->port_ptr = (uint32_t *)(void *)port_ptr;
+ if (!xdr_reference(xdrs, &port_ptr, sizeof (uint32_t),
+ (xdrproc_t)xdr_u_int32))
+ return (FALSE);
+ crp->port_ptr = (uint32_t *)(void *)port_ptr;
+ if (xdr_u_int32(xdrs, &crp->resultslen))
return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
- }
return (FALSE);
}
--
2.45.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,71 @@
From 05bb6d9c729a3c6a4ba35270368bc0f6e1875ad0 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Mon, 8 Jan 2024 16:52:27 +0100
Subject: [PATCH] Remove klist's defname global variable
Addition of a "cleanup" section in kinit's show_ccache() function as
part of commit 6c5471176f5266564fbc8a7e02f03b4b042202f8 introduced a
double-free bug, because defname is a global variable. After the
first call, successive calls may take place with a dangling pointer in
defname, which will be freed if krb5_cc_get_principal() fails.
Convert "defname" to a local variable initialized at the beginning of
show_ccache().
[ghudson@mit.edu: edited commit message]
(cherry picked from commit 5b00197227231943bd2305328c8260dd0b0dbcf0)
---
src/clients/klist/klist.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index b5ae96a843..b5808e5c93 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -53,7 +53,6 @@ int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
int show_etype = 0, show_addresses = 0, no_resolve = 0, print_version = 0;
int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0;
int show_config = 0;
-char *defname;
char *progname;
krb5_timestamp now;
unsigned int timestamp_width;
@@ -62,7 +61,7 @@ krb5_context context;
static krb5_boolean is_local_tgt(krb5_principal princ, krb5_data *realm);
static char *etype_string(krb5_enctype );
-static void show_credential(krb5_creds *);
+static void show_credential(krb5_creds *, const char *);
static void list_all_ccaches(void);
static int list_ccache(krb5_ccache);
@@ -473,6 +472,7 @@ show_ccache(krb5_ccache cache)
krb5_creds creds;
krb5_principal princ = NULL;
krb5_error_code ret;
+ char *defname = NULL;
int status = 1;
ret = krb5_cc_get_principal(context, cache, &princ);
@@ -503,7 +503,7 @@ show_ccache(krb5_ccache cache)
}
while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) {
if (show_config || !krb5_is_config_principal(context, creds.server))
- show_credential(&creds);
+ show_credential(&creds, defname);
krb5_free_cred_contents(context, &creds);
}
if (ret == KRB5_CC_END) {
@@ -676,7 +676,7 @@ print_config_data(int col, krb5_data *data)
}
static void
-show_credential(krb5_creds *cred)
+show_credential(krb5_creds *cred, const char *defname)
{
krb5_error_code ret;
krb5_ticket *tkt = NULL;
--
2.45.1

View file

@ -0,0 +1,34 @@
From d7bcca2a215de880f4419afc450a96a747d48560 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 27 Oct 2023 00:44:53 -0400
Subject: [PATCH] End connection on KDC_ERR_SVC_UNAVAILABLE
In sendto_kdc.c:service_fds(), if a message handler indicates that a
message should be discarded, kill the connection so we don't continue
waiting on it for more data.
ticket: 7899
(cherry picked from commit ca80f64c786341d5871ae1de18142e62af64f7b9)
---
src/lib/krb5/os/sendto_kdc.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 0f4bf23a95..262edf09b4 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -1440,7 +1440,10 @@ service_fds(krb5_context context, struct select_state *selstate,
if (msg_handler != NULL) {
krb5_data reply = make_data(state->in.buf, state->in.pos);
- stop = (msg_handler(context, &reply, msg_handler_data) != 0);
+ if (!msg_handler(context, &reply, msg_handler_data)) {
+ kill_conn(context, state, selstate);
+ stop = 0;
+ }
}
if (stop) {
--
2.46.0

View file

@ -0,0 +1,226 @@
From a07b3ae29fd972c40e30b95f6bcc8fb3ed4d9991 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 26 Oct 2023 14:20:34 -0400
Subject: [PATCH] Add request_timeout configuration parameter
Add a parameter to limit the total amount of time taken for a KDC or
password change request.
ticket: 9106 (new)
(cherry picked from commit 802318cda963456b3ed7856c836e89da891483be)
---
doc/admin/conf_files/krb5_conf.rst | 9 ++++++
src/include/k5-int.h | 2 ++
src/lib/krb5/krb/init_ctx.c | 14 +++++++-
src/lib/krb5/os/sendto_kdc.c | 51 ++++++++++++++++++++----------
4 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index a33711d918..65fb592d98 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -356,6 +356,15 @@ The libdefaults section may contain any of the following relations:
(:ref:`duration` string.) Sets the default renewable lifetime
for initial ticket requests. The default value is 0.
+**request_timeout**
+ (:ref:`duration` string.) Sets the maximum total time for KDC or
+ password change requests. This timeout does not affect the
+ intervals between requests, so setting a low timeout may result in
+ fewer requests being attempted and/or some servers not being
+ contacted. A value of 0 indicates no specific maximum, in which
+ case requests will time out if no server responds after several
+ tries. The default value is 0. (New in release 1.22.)
+
**spake_preauth_groups**
A whitespace or comma-separated list of words which specifies the
groups allowed for SPAKE preauthentication. The possible values
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index b3e07945c1..69d6a6f569 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -296,6 +296,7 @@ typedef unsigned char u_char;
#define KRB5_CONF_SPAKE_PREAUTH_INDICATOR "spake_preauth_indicator"
#define KRB5_CONF_SPAKE_PREAUTH_KDC_CHALLENGE "spake_preauth_kdc_challenge"
#define KRB5_CONF_SPAKE_PREAUTH_GROUPS "spake_preauth_groups"
+#define KRB5_CONF_REQUEST_TIMEOUT "request_timeout"
#define KRB5_CONF_TICKET_LIFETIME "ticket_lifetime"
#define KRB5_CONF_UDP_PREFERENCE_LIMIT "udp_preference_limit"
#define KRB5_CONF_UNLOCKITER "unlockiter"
@@ -1200,6 +1201,7 @@ struct _krb5_context {
kdb5_dal_handle *dal_handle;
/* allowable clock skew */
krb5_deltat clockskew;
+ krb5_deltat req_timeout;
krb5_flags kdc_default_options;
krb5_flags library_options;
krb5_boolean profile_secure;
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 2b5abcd817..582a2945ff 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -157,7 +157,7 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
krb5_context ctx = 0;
krb5_error_code retval;
int tmp;
- char *plugin_dir = NULL;
+ char *plugin_dir = NULL, *timeout_str = NULL;
/* Verify some assumptions. If the assumptions hold and the
compiler is optimizing, this should result in no code being
@@ -240,6 +240,17 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
get_integer(ctx, KRB5_CONF_CLOCKSKEW, DEFAULT_CLOCKSKEW, &tmp);
ctx->clockskew = tmp;
+ retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS,
+ KRB5_CONF_REQUEST_TIMEOUT, NULL, NULL,
+ &timeout_str);
+ if (retval)
+ goto cleanup;
+ if (timeout_str != NULL) {
+ retval = krb5_string_to_deltat(timeout_str, &ctx->req_timeout);
+ if (retval)
+ goto cleanup;
+ }
+
get_integer(ctx, KRB5_CONF_KDC_DEFAULT_OPTIONS, KDC_OPT_RENEWABLE_OK,
&tmp);
ctx->kdc_default_options = tmp;
@@ -281,6 +292,7 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
cleanup:
profile_release_string(plugin_dir);
+ profile_release_string(timeout_str);
krb5_free_context(ctx);
return retval;
}
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 262edf09b4..98247a1089 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -1395,34 +1395,41 @@ get_endtime(time_ms endtime, struct conn_state *conns)
static krb5_boolean
service_fds(krb5_context context, struct select_state *selstate,
- time_ms interval, struct conn_state *conns,
+ time_ms interval, time_ms timeout, struct conn_state *conns,
struct select_state *seltemp, const krb5_data *realm,
int (*msg_handler)(krb5_context, const krb5_data *, void *),
void *msg_handler_data, struct conn_state **winner_out)
{
int e, selret = 0;
- time_ms endtime;
+ time_ms curtime, interval_end, endtime;
struct conn_state *state;
*winner_out = NULL;
- e = get_curtime_ms(&endtime);
+ e = get_curtime_ms(&curtime);
if (e)
return TRUE;
- endtime += interval;
+ interval_end = curtime + interval;
e = 0;
while (selstate->nfds > 0) {
- e = cm_select_or_poll(selstate, get_endtime(endtime, conns),
- seltemp, &selret);
+ endtime = get_endtime(interval_end, conns);
+ /* Don't wait longer than the whole request should last. */
+ if (timeout && endtime > timeout)
+ endtime = timeout;
+ e = cm_select_or_poll(selstate, endtime, seltemp, &selret);
if (e == EINTR)
continue;
if (e != 0)
break;
- if (selret == 0)
- /* Timeout, return to caller. */
+ if (selret == 0) {
+ /* We timed out. Stop if we hit the overall request timeout. */
+ if (timeout && (get_curtime_ms(&curtime) || curtime >= timeout))
+ return TRUE;
+ /* Otherwise return to the caller to send the next request. */
return FALSE;
+ }
/* Got something on a socket, process it. */
for (state = conns; state != NULL; state = state->next) {
@@ -1495,7 +1502,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
void *msg_handler_data)
{
int pass;
- time_ms delay;
+ time_ms delay, timeout = 0;
krb5_error_code retval;
struct conn_state *conns = NULL, *state, **tailptr, *next, *winner;
size_t s;
@@ -1505,6 +1512,13 @@ k5_sendto(krb5_context context, const krb5_data *message,
*reply = empty_data();
+ if (context->req_timeout) {
+ retval = get_curtime_ms(&timeout);
+ if (retval)
+ return retval;
+ timeout += 1000 * context->req_timeout;
+ }
+
/* One for use here, listing all our fds in use, and one for
* temporary use in service_fds, for the fds of interest. */
sel_state = malloc(2 * sizeof(*sel_state));
@@ -1532,8 +1546,9 @@ k5_sendto(krb5_context context, const krb5_data *message,
if (maybe_send(context, state, message, sel_state, realm,
callback_info))
continue;
- done = service_fds(context, sel_state, 1000, conns, seltemp,
- realm, msg_handler, msg_handler_data, &winner);
+ done = service_fds(context, sel_state, 1000, timeout, conns,
+ seltemp, realm, msg_handler, msg_handler_data,
+ &winner);
}
}
@@ -1545,13 +1560,13 @@ k5_sendto(krb5_context context, const krb5_data *message,
if (maybe_send(context, state, message, sel_state, realm,
callback_info))
continue;
- done = service_fds(context, sel_state, 1000, conns, seltemp,
+ done = service_fds(context, sel_state, 1000, timeout, conns, seltemp,
realm, msg_handler, msg_handler_data, &winner);
}
/* Wait for two seconds at the end of the first pass. */
if (!done) {
- done = service_fds(context, sel_state, 2000, conns, seltemp,
+ done = service_fds(context, sel_state, 2000, timeout, conns, seltemp,
realm, msg_handler, msg_handler_data, &winner);
}
@@ -1562,15 +1577,17 @@ k5_sendto(krb5_context context, const krb5_data *message,
if (maybe_send(context, state, message, sel_state, realm,
callback_info))
continue;
- done = service_fds(context, sel_state, 1000, conns, seltemp,
- realm, msg_handler, msg_handler_data, &winner);
+ done = service_fds(context, sel_state, 1000, timeout, conns,
+ seltemp, realm, msg_handler, msg_handler_data,
+ &winner);
if (sel_state->nfds == 0)
break;
}
/* Wait for the delay backoff at the end of this pass. */
if (!done) {
- done = service_fds(context, sel_state, delay, conns, seltemp,
- realm, msg_handler, msg_handler_data, &winner);
+ done = service_fds(context, sel_state, delay, timeout, conns,
+ seltemp, realm, msg_handler, msg_handler_data,
+ &winner);
}
if (sel_state->nfds == 0)
break;
--
2.46.0

View file

@ -0,0 +1,138 @@
From 1da153d97d7fb30a44fca35f9b71b8f4ed5385b9 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 26 Oct 2023 16:26:42 -0400
Subject: [PATCH] Wait indefinitely on KDC TCP connections
When making a KDC or password change request, wait indefinitely
(limited only by request_timeout if set) once a KDC has accepted a TCP
connection.
ticket: 9105 (new)
(cherry picked from commit 6436a3808061da787a43c6810f5f0370cdfb6e36)
---
doc/admin/conf_files/krb5_conf.rst | 2 +-
src/lib/krb5/os/sendto_kdc.c | 50 ++++++++++++++++--------------
2 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 65fb592d98..b7284c47df 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -357,7 +357,7 @@ The libdefaults section may contain any of the following relations:
for initial ticket requests. The default value is 0.
**request_timeout**
- (:ref:`duration` string.) Sets the maximum total time for KDC or
+ (:ref:`duration` string.) Sets the maximum total time for KDC and
password change requests. This timeout does not affect the
intervals between requests, so setting a low timeout may result in
fewer requests being attempted and/or some servers not being
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 98247a1089..924f5b2d26 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -134,7 +134,6 @@ struct conn_state {
krb5_data callback_buffer;
size_t server_index;
struct conn_state *next;
- time_ms endtime;
krb5_boolean defer;
struct {
const char *uri_path;
@@ -344,15 +343,19 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime,
struct select_state *out, int *sret)
{
#ifndef USE_POLL
- struct timeval tv;
+ struct timeval tv, *tvp;
#endif
krb5_error_code retval;
time_ms curtime, interval;
- retval = get_curtime_ms(&curtime);
- if (retval != 0)
- return retval;
- interval = (curtime < endtime) ? endtime - curtime : 0;
+ if (endtime != 0) {
+ retval = get_curtime_ms(&curtime);
+ if (retval != 0)
+ return retval;
+ interval = (curtime < endtime) ? endtime - curtime : 0;
+ } else {
+ interval = -1;
+ }
/* We don't need a separate copy of the selstate for poll, but use one for
* consistency with how we use select. */
@@ -361,9 +364,14 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime,
#ifdef USE_POLL
*sret = poll(out->fds, out->nfds, interval);
#else
- tv.tv_sec = interval / 1000;
- tv.tv_usec = interval % 1000 * 1000;
- *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, &tv);
+ if (interval != -1) {
+ tv.tv_sec = interval / 1000;
+ tv.tv_usec = interval % 1000 * 1000;
+ tvp = &tv;
+ } else {
+ tvp = NULL;
+ }
+ *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, tvp);
#endif
return (*sret < 0) ? SOCKET_ERRNO : 0;
@@ -1099,11 +1107,6 @@ service_tcp_connect(krb5_context context, const krb5_data *realm,
}
conn->state = WRITING;
-
- /* Record this connection's timeout for service_fds. */
- if (get_curtime_ms(&conn->endtime) == 0)
- conn->endtime += 10000;
-
return conn->service_write(context, realm, conn, selstate);
}
@@ -1378,19 +1381,18 @@ kill_conn:
return FALSE;
}
-/* Return the maximum of endtime and the endtime fields of all currently active
- * TCP connections. */
-static time_ms
-get_endtime(time_ms endtime, struct conn_state *conns)
+/* Return true if conns contains any states with connected TCP sockets. */
+static krb5_boolean
+any_tcp_connections(struct conn_state *conns)
{
struct conn_state *state;
for (state = conns; state != NULL; state = state->next) {
- if ((state->state == READING || state->state == WRITING) &&
- state->endtime > endtime)
- endtime = state->endtime;
+ if (state->addr.transport != UDP &&
+ (state->state == READING || state->state == WRITING))
+ return TRUE;
}
- return endtime;
+ return FALSE;
}
static krb5_boolean
@@ -1413,9 +1415,9 @@ service_fds(krb5_context context, struct select_state *selstate,
e = 0;
while (selstate->nfds > 0) {
- endtime = get_endtime(interval_end, conns);
+ endtime = any_tcp_connections(conns) ? 0 : interval_end;
/* Don't wait longer than the whole request should last. */
- if (timeout && endtime > timeout)
+ if (timeout && (!endtime || endtime > timeout))
endtime = timeout;
e = cm_select_or_poll(selstate, endtime, seltemp, &selret);
if (e == EINTR)
--
2.46.0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,265 @@
From 3999883b9745bfd7065d41ff05b19e56bcb2e791 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Fri, 6 Sep 2024 17:18:11 +0200
Subject: [PATCH] Fix various issues detected by static analysis
In klists's show_credential(), ensure that the column counter doesn't
decrease if printf() fails.
In process_k5beta7_princ(), bounds-check the e_length field.
In ndr_enc_delegation_info(), initialize b so it is always valid for
the cleanup handler.
In krb5_dbe_def_decrypt_key_data(), change the flow control so ret is
always set by the end of the function. Return KRB5_KDB_INVALIDKEYSIZE
if there isn't enough data in the first key_data_contents field or if
the serialized key length is invalid.
In svcauth_gss_validate(), expand rpchdr to accomodate the header plus
MAX_AUTH_BYTES.
In svcudp_reply(), change slen to unsigned to match the return type of
XDR_GETPOS() and eliminate an unnecessary check for slen >= 0.
In krb5int_pthread_loaded()(), remove pthread_equal() from the weak
symbol checks. It is implemented as an inline function in some glibc
versions, which makes the comparison "&pthread_equal == 0" always
false.
[ghudson@mit.edu: further modified krb5_dbe_def_decrypt_key_data() for
clarity; added detail to commit message]
(cherry picked from commit a96541981ee34c8642ddeb6101b98e883e41c6e5)
---
src/clients/klist/klist.c | 12 ++++-----
src/kadmin/dbutil/dump.c | 5 ++++
src/kdc/ndr.c | 2 +-
src/lib/kdb/decrypt_key.c | 54 ++++++++++++++++++++------------------
src/lib/rpc/svc_auth_gss.c | 5 +++-
src/lib/rpc/svc_udp.c | 13 ++++-----
src/util/support/threads.c | 2 --
7 files changed, 51 insertions(+), 42 deletions(-)
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index b5808e5c93..ba9539fd23 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -681,7 +681,7 @@ show_credential(krb5_creds *cred, const char *defname)
krb5_error_code ret;
krb5_ticket *tkt = NULL;
char *name = NULL, *sname = NULL, *tktsname, *flags;
- int extra_field = 0, ccol = 0, i;
+ int extra_field = 0, ccol = 0, i, r;
krb5_boolean is_config = krb5_is_config_principal(context, cred->server);
ret = krb5_unparse_name(context, cred->client, &name);
@@ -711,11 +711,11 @@ show_credential(krb5_creds *cred, const char *defname)
fputs("config: ", stdout);
ccol = 8;
for (i = 1; i < cred->server->length; i++) {
- ccol += printf("%s%.*s%s",
- i > 1 ? "(" : "",
- (int)cred->server->data[i].length,
- cred->server->data[i].data,
- i > 1 ? ")" : "");
+ r = printf("%s%.*s%s", i > 1 ? "(" : "",
+ (int)cred->server->data[i].length,
+ cred->server->data[i].data, i > 1 ? ")" : "");
+ if (r >= 0)
+ ccol += r;
}
fputs(" = ", stdout);
ccol += 3;
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index 4d6cc0bdf9..feb053d834 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -704,6 +704,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
dbentry->len = u1;
dbentry->n_key_data = u4;
+
+ if (u5 > UINT16_MAX) {
+ load_err(fname, *linenop, _("invalid principal extra data size"));
+ goto fail;
+ }
dbentry->e_length = u5;
if (kp != NULL) {
diff --git a/src/kdc/ndr.c b/src/kdc/ndr.c
index d438408ee2..38be9fe42a 100644
--- a/src/kdc/ndr.c
+++ b/src/kdc/ndr.c
@@ -242,7 +242,7 @@ ndr_enc_delegation_info(struct pac_s4u_delegation_info *in, krb5_data *out)
{
krb5_error_code ret;
size_t i;
- struct k5buf b;
+ struct k5buf b = EMPTY_K5BUF;
struct encoded_wchars pt_encoded = { 0 }, *tss_encoded = NULL;
uint32_t pointer = 0;
diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c
index 82bbed6312..21aa3742b1 100644
--- a/src/lib/kdb/decrypt_key.c
+++ b/src/lib/kdb/decrypt_key.c
@@ -60,7 +60,7 @@ krb5_dbe_def_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
krb5_keyblock *dbkey_out,
krb5_keysalt *keysalt_out)
{
- krb5_error_code ret;
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
int16_t keylen;
krb5_enc_data cipher;
krb5_data plain = empty_data();
@@ -74,36 +74,38 @@ krb5_dbe_def_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
if (mkey == NULL)
return KRB5_KDB_BADSTORED_MKEY;
- if (kd->key_data_contents[0] != NULL && kd->key_data_length[0] >= 2) {
- keylen = load_16_le(kd->key_data_contents[0]);
- if (keylen < 0)
- return EINVAL;
- cipher.enctype = ENCTYPE_UNKNOWN;
- cipher.ciphertext = make_data(kd->key_data_contents[0] + 2,
- kd->key_data_length[0] - 2);
- ret = alloc_data(&plain, kd->key_data_length[0] - 2);
- if (ret)
- goto cleanup;
+ if (kd->key_data_contents[0] == NULL || kd->key_data_length[0] < 2)
+ return KRB5_KDB_INVALIDKEYSIZE;
- ret = krb5_c_decrypt(context, mkey, 0, 0, &cipher, &plain);
- if (ret)
- goto cleanup;
+ keylen = load_16_le(kd->key_data_contents[0]);
+ if (keylen < 0)
+ return KRB5_KDB_INVALIDKEYSIZE;
- /* Make sure the plaintext has at least as many bytes as the true ke
- * length (it may have more due to padding). */
- if ((unsigned int)keylen > plain.length) {
- ret = KRB5_CRYPTO_INTERNAL;
- if (ret)
- goto cleanup;
- }
+ cipher.enctype = ENCTYPE_UNKNOWN;
+ cipher.ciphertext = make_data(kd->key_data_contents[0] + 2,
+ kd->key_data_length[0] - 2);
+ ret = alloc_data(&plain, kd->key_data_length[0] - 2);
+ if (ret)
+ goto cleanup;
- kb.magic = KV5M_KEYBLOCK;
- kb.enctype = kd->key_data_type[0];
- kb.length = keylen;
- kb.contents = (uint8_t *)plain.data;
- plain = empty_data();
+ ret = krb5_c_decrypt(context, mkey, 0, 0, &cipher, &plain);
+ if (ret)
+ goto cleanup;
+
+ /* Make sure the plaintext has at least as many bytes as the true key
+ * length (it may have more due to padding). */
+ if ((unsigned int)keylen > plain.length) {
+ ret = KRB5_CRYPTO_INTERNAL;
+ if (ret)
+ goto cleanup;
}
+ kb.magic = KV5M_KEYBLOCK;
+ kb.enctype = kd->key_data_type[0];
+ kb.length = keylen;
+ kb.contents = (uint8_t *)plain.data;
+ plain = empty_data();
+
/* Decode salt data. */
if (keysalt_out != NULL) {
if (kd->key_data_ver == 2) {
diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
index 98d601c8ab..4f1d2911b0 100644
--- a/src/lib/rpc/svc_auth_gss.c
+++ b/src/lib/rpc/svc_auth_gss.c
@@ -297,7 +297,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
struct opaque_auth *oa;
gss_buffer_desc rpcbuf, checksum;
OM_uint32 maj_stat, min_stat, qop_state;
- u_char rpchdr[128];
+ u_char rpchdr[32 + MAX_AUTH_BYTES];
int32_t *buf;
log_debug("in svcauth_gss_validate()");
@@ -315,6 +315,8 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
return (FALSE);
buf = (int32_t *)(void *)rpchdr;
+
+ /* Write the 32 first bytes of the header. */
IXDR_PUT_LONG(buf, msg->rm_xid);
IXDR_PUT_ENUM(buf, msg->rm_direction);
IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
@@ -323,6 +325,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
IXDR_PUT_ENUM(buf, oa->oa_flavor);
IXDR_PUT_LONG(buf, oa->oa_length);
+
if (oa->oa_length) {
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
buf += RNDUP(oa->oa_length) / sizeof(int32_t);
diff --git a/src/lib/rpc/svc_udp.c b/src/lib/rpc/svc_udp.c
index 8ecbdf2b33..3aff277eb7 100644
--- a/src/lib/rpc/svc_udp.c
+++ b/src/lib/rpc/svc_udp.c
@@ -248,8 +248,9 @@ static bool_t svcudp_reply(
{
struct svcudp_data *su = su_data(xprt);
XDR *xdrs = &su->su_xdrs;
- int slen;
+ u_int slen;
bool_t stat = FALSE;
+ ssize_t r;
xdrproc_t xdr_results = NULL;
caddr_t xdr_location = 0;
@@ -272,12 +273,12 @@ static bool_t svcudp_reply(
if (xdr_replymsg(xdrs, msg) &&
(!has_args ||
(SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
- slen = (int)XDR_GETPOS(xdrs);
- if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
- (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
- == slen) {
+ slen = XDR_GETPOS(xdrs);
+ r = sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen);
+ if (r >= 0 && (u_int)r == slen) {
stat = TRUE;
- if (su->su_cache && slen >= 0) {
+ if (su->su_cache) {
cache_set(xprt, (uint32_t) slen);
}
}
diff --git a/src/util/support/threads.c b/src/util/support/threads.c
index be7e4c2e3f..4ded805b79 100644
--- a/src/util/support/threads.c
+++ b/src/util/support/threads.c
@@ -118,7 +118,6 @@ struct tsd_block {
# pragma weak pthread_mutex_destroy
# pragma weak pthread_mutex_init
# pragma weak pthread_self
-# pragma weak pthread_equal
# pragma weak pthread_getspecific
# pragma weak pthread_setspecific
# pragma weak pthread_key_create
@@ -151,7 +150,6 @@ int krb5int_pthread_loaded (void)
|| &pthread_mutex_destroy == 0
|| &pthread_mutex_init == 0
|| &pthread_self == 0
- || &pthread_equal == 0
/* Any program that's really multithreaded will have to be
able to create threads. */
|| &pthread_create == 0
--
2.46.0

View file

@ -0,0 +1,629 @@
From ea02fd7bb79861b8e36517c7c95af821a16657c4 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Thu, 22 Aug 2024 17:15:50 +0200
Subject: [PATCH] Generate and verify message MACs in libkrad
Implement some of the measures specified in
draft-ietf-radext-deprecating-radius-03 for mitigating the BlastRADIUS
attack (CVE-2024-3596):
* Include a Message-Authenticator MAC as the first attribute when
generating a packet of type Access-Request, Access-Reject,
Access-Accept, or Access-Challenge (sections 5.2.1 and 5.2.4), if
the secret is non-empty. (An empty secret indicates the use of Unix
domain socket transport.)
* Validate the Message-Authenticator MAC in received packets, if
present.
FreeRADIUS enforces Message-Authenticator as of versions 3.2.5 and
3.0.27. libkrad must generate Message-Authenticator attributes in
order to remain compatible with these implementations.
[ghudson@mit.edu: adjusted style and naming; simplified some
functions; edited commit message]
ticket: 9142 (new)
tags: pullup
target_version: 1.21-next
(cherry picked from commit 871125fea8ce0370a972bf65f7d1de63f619b06c)
---
src/include/k5-int.h | 5 +
src/lib/crypto/krb/checksum_hmac_md5.c | 28 ++++
src/lib/crypto/libk5crypto.exports | 1 +
src/lib/krad/attr.c | 17 ++
src/lib/krad/attrset.c | 59 +++++--
src/lib/krad/internal.h | 7 +-
src/lib/krad/packet.c | 206 +++++++++++++++++++++++--
src/lib/krad/t_attrset.c | 2 +-
src/lib/krad/t_daemon.py | 3 +-
src/lib/krad/t_packet.c | 11 ++
src/tests/t_otp.py | 3 +
11 files changed, 311 insertions(+), 31 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 69d6a6f569..b7789a2dd8 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2403,4 +2403,9 @@ krb5_boolean
k5_sname_compare(krb5_context context, krb5_const_principal sname,
krb5_const_principal princ);
+/* Generate an HMAC-MD5 keyed checksum as specified by RFC 2104. */
+krb5_error_code
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output);
+
#endif /* _KRB5_INT_H */
diff --git a/src/lib/crypto/krb/checksum_hmac_md5.c b/src/lib/crypto/krb/checksum_hmac_md5.c
index ec024f3966..a809388549 100644
--- a/src/lib/crypto/krb/checksum_hmac_md5.c
+++ b/src/lib/crypto/krb/checksum_hmac_md5.c
@@ -92,3 +92,31 @@ cleanup:
free(hash_iov);
return ret;
}
+
+krb5_error_code
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ krb5_error_code ret;
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+ krb5_keyblock keyblock = { 0 };
+ krb5_data hashed_key;
+ uint8_t hkeybuf[16];
+ krb5_crypto_iov iov;
+
+ /* Hash the key if it is longer than the block size. */
+ if (key->length > hash->blocksize) {
+ hashed_key = make_data(hkeybuf, sizeof(hkeybuf));
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *key;
+ ret = hash->hash(&iov, 1, &hashed_key);
+ if (ret)
+ return ret;
+ key = &hashed_key;
+ }
+
+ keyblock.magic = KV5M_KEYBLOCK;
+ keyblock.length = key->length;
+ keyblock.contents = (uint8_t *)key->data;
+ return krb5int_hmac_keyblock(hash, &keyblock, data, num_data, output);
+}
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index d8ffa63304..00e0ce1812 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -102,3 +102,4 @@ krb5_c_prfplus
krb5_c_derive_prfplus
k5_enctype_to_ssf
krb5int_c_deprecated_enctype
+k5_hmac_md5
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
index 42d354a3b5..65ed1d35e7 100644
--- a/src/lib/krad/attr.c
+++ b/src/lib/krad/attr.c
@@ -125,6 +125,23 @@ static const attribute_record attributes[UCHAR_MAX] = {
{"NAS-Port-Type", 4, 4, NULL, NULL},
{"Port-Limit", 4, 4, NULL, NULL},
{"Login-LAT-Port", 1, MAX_ATTRSIZE, NULL, NULL},
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
+ {NULL, 0, 0, NULL, NULL}, /* Password-Retry */
+ {NULL, 0, 0, NULL, NULL}, /* Prompt */
+ {NULL, 0, 0, NULL, NULL}, /* Connect-Info */
+ {NULL, 0, 0, NULL, NULL}, /* Configuration-Token */
+ {NULL, 0, 0, NULL, NULL}, /* EAP-Message */
+ {"Message-Authenticator", MD5_DIGEST_SIZE, MD5_DIGEST_SIZE, NULL, NULL},
};
/* Encode User-Password attribute. */
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
index 6ec031e320..e5457ebfd7 100644
--- a/src/lib/krad/attrset.c
+++ b/src/lib/krad/attrset.c
@@ -164,15 +164,44 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
return 0;
}
+/* Place an encoded attributes into outbuf at position *i. Increment *i by the
+ * length of the encoding. */
+static krb5_error_code
+append_attr(krb5_context ctx, const char *secret,
+ const uint8_t *auth, krad_attr type, const krb5_data *data,
+ uint8_t outbuf[MAX_ATTRSETSIZE], size_t *i, krb5_boolean *is_fips)
+{
+ uint8_t buffer[MAX_ATTRSIZE];
+ size_t attrlen;
+ krb5_error_code retval;
+
+ retval = kr_attr_encode(ctx, secret, auth, type, data, buffer, &attrlen,
+ is_fips);
+ if (retval)
+ return retval;
+
+ if (attrlen > MAX_ATTRSETSIZE - *i - 2)
+ return EMSGSIZE;
+
+ outbuf[(*i)++] = type;
+ outbuf[(*i)++] = attrlen + 2;
+ memcpy(outbuf + *i, buffer, attrlen);
+ *i += attrlen;
+
+ return 0;
+}
+
krb5_error_code
kr_attrset_encode(const krad_attrset *set, const char *secret,
- const unsigned char *auth,
+ const uint8_t *auth, krb5_boolean add_msgauth,
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
krb5_boolean *is_fips)
{
- unsigned char buffer[MAX_ATTRSIZE];
krb5_error_code retval;
- size_t i = 0, attrlen;
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ const uint8_t zeroes[MD5_DIGEST_SIZE] = { 0 };
+ krb5_data zerodata;
+ size_t i = 0;
attr *a;
if (set == NULL) {
@@ -180,19 +209,21 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
return 0;
}
- K5_TAILQ_FOREACH(a, &set->list, list) {
- retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
- buffer, &attrlen, is_fips);
- if (retval != 0)
+ if (add_msgauth) {
+ /* Encode Message-Authenticator as the first attribute, per
+ * draft-ietf-radext-deprecating-radius-03 section 5.2. */
+ zerodata = make_data((uint8_t *)zeroes, MD5_DIGEST_SIZE);
+ retval = append_attr(set->ctx, secret, auth, msgauth_type, &zerodata,
+ outbuf, &i, is_fips);
+ if (retval)
return retval;
+ }
- if (i + attrlen + 2 > MAX_ATTRSETSIZE)
- return EMSGSIZE;
-
- outbuf[i++] = a->type;
- outbuf[i++] = attrlen + 2;
- memcpy(&outbuf[i], buffer, attrlen);
- i += attrlen;
+ K5_TAILQ_FOREACH(a, &set->list, list) {
+ retval = append_attr(set->ctx, secret, auth, a->type, &a->attr,
+ outbuf, &i, is_fips);
+ if (retval)
+ return retval;
}
*outlen = i;
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
index a17b6f39b1..ca66f3ec68 100644
--- a/src/lib/krad/internal.h
+++ b/src/lib/krad/internal.h
@@ -49,6 +49,8 @@
#define UCHAR_MAX 255
#endif
+#define MD5_DIGEST_SIZE 16
+
/* RFC 2865 */
#define MAX_ATTRSIZE (UCHAR_MAX - 2)
#define MAX_ATTRSETSIZE (KRAD_PACKET_SIZE_MAX - 20)
@@ -79,10 +81,11 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
krad_attr type, const krb5_data *in,
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
-/* Encode the attributes into the buffer. */
+/* Encode set into outbuf. If add_msgauth is true, include a zeroed
+ * Message-Authenticator as the first attribute. */
krb5_error_code
kr_attrset_encode(const krad_attrset *set, const char *secret,
- const unsigned char *auth,
+ const uint8_t *auth, krb5_boolean add_msgauth,
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
krb5_boolean *is_fips);
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
index c5446b890c..3c1a4d507e 100644
--- a/src/lib/krad/packet.c
+++ b/src/lib/krad/packet.c
@@ -36,6 +36,7 @@
typedef unsigned char uchar;
/* RFC 2865 */
+#define MSGAUTH_SIZE (2 + MD5_DIGEST_SIZE)
#define OFFSET_CODE 0
#define OFFSET_ID 1
#define OFFSET_LENGTH 2
@@ -222,6 +223,106 @@ packet_set_attrset(krb5_context ctx, const char *secret, krad_packet *pkt)
return kr_attrset_decode(ctx, &tmp, secret, pkt_auth(pkt), &pkt->attrset);
}
+/* Determine if a packet requires a Message-Authenticator attribute. */
+static inline krb5_boolean
+requires_msgauth(const char *secret, krad_code code)
+{
+ /* If no secret is provided, assume that the transport is a UNIX socket.
+ * Message-Authenticator is required only on UDP and TCP connections. */
+ if (*secret == '\0')
+ return FALSE;
+
+ /*
+ * Per draft-ietf-radext-deprecating-radius-03 sections 5.2.1 and 5.2.4,
+ * Message-Authenticator is required in Access-Request packets and all
+ * potential responses when UDP or TCP transport is used.
+ */
+ return code == krad_code_name2num("Access-Request") ||
+ code == krad_code_name2num("Access-Reject") ||
+ code == krad_code_name2num("Access-Accept") ||
+ code == krad_code_name2num("Access-Challenge");
+}
+
+/* Check if the packet has a Message-Authenticator attribute. */
+static inline krb5_boolean
+has_pkt_msgauth(const krad_packet *pkt)
+{
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+
+ return krad_attrset_get(pkt->attrset, msgauth_type, 0) != NULL;
+}
+
+/* Return the beginning of the Message-Authenticator attribute in pkt, or NULL
+ * if no such attribute is present. */
+static const uint8_t *
+lookup_msgauth_addr(const krad_packet *pkt)
+{
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ size_t i;
+ uint8_t *p;
+
+ i = OFFSET_ATTR;
+ while (i + 2 < pkt->pkt.length) {
+ p = (uint8_t *)offset(&pkt->pkt, i);
+ if (msgauth_type == *p)
+ return p;
+ i += p[1];
+ }
+
+ return NULL;
+}
+
+/*
+ * Calculate the message authenticator MAC for pkt as specified in RFC 2869
+ * section 5.14, placing the result in mac_out. Use the provided authenticator
+ * auth, which may be from pkt or from a corresponding request.
+ */
+static krb5_error_code
+calculate_mac(const char *secret, const krad_packet *pkt,
+ const uint8_t auth[AUTH_FIELD_SIZE],
+ uint8_t mac_out[MD5_DIGEST_SIZE])
+{
+ uint8_t zeroed_msgauth[MSGAUTH_SIZE];
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ const uint8_t *msgauth_attr, *msgauth_end, *pkt_end;
+ krb5_crypto_iov input[5];
+ krb5_data ksecr, mac;
+
+ msgauth_attr = lookup_msgauth_addr(pkt);
+ if (msgauth_attr == NULL)
+ return EINVAL;
+ msgauth_end = msgauth_attr + MSGAUTH_SIZE;
+ pkt_end = (const uint8_t *)pkt->pkt.data + pkt->pkt.length;
+
+ /* Read code, id, and length from the packet. */
+ input[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[0].data = make_data(pkt->pkt.data, OFFSET_AUTH);
+
+ /* Read the provided authenticator. */
+ input[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[1].data = make_data((uint8_t *)auth, AUTH_FIELD_SIZE);
+
+ /* Read any attributes before Message-Authenticator. */
+ input[2].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[2].data = make_data(pkt_attr(pkt), msgauth_attr - pkt_attr(pkt));
+
+ /* Read Message-Authenticator with the data bytes all set to zero, per RFC
+ * 2869 section 5.14. */
+ zeroed_msgauth[0] = msgauth_type;
+ zeroed_msgauth[1] = MSGAUTH_SIZE;
+ memset(zeroed_msgauth + 2, 0, MD5_DIGEST_SIZE);
+ input[3].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[3].data = make_data(zeroed_msgauth, MSGAUTH_SIZE);
+
+ /* Read any attributes after Message-Authenticator. */
+ input[4].flags = KRB5_CRYPTO_TYPE_DATA;
+ input[4].data = make_data((uint8_t *)msgauth_end, pkt_end - msgauth_end);
+
+ mac = make_data(mac_out, MD5_DIGEST_SIZE);
+ ksecr = string2data((char *)secret);
+ return k5_hmac_md5(&ksecr, input, 5, &mac);
+}
+
ssize_t
krad_packet_bytes_needed(const krb5_data *buffer)
{
@@ -255,6 +356,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
krad_packet *pkt;
uchar id;
size_t attrset_len;
+ krb5_boolean msgauth_required;
pkt = packet_new();
if (pkt == NULL) {
@@ -274,9 +376,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
if (retval != 0)
goto error;
+ /* Determine if Message-Authenticator is required. */
+ msgauth_required = (*secret != '\0' &&
+ code == krad_code_name2num("Access-Request"));
+
/* Encode the attributes. */
- retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
- &attrset_len, &pkt->is_fips);
+ retval = kr_attrset_encode(set, secret, pkt_auth(pkt), msgauth_required,
+ pkt_attr(pkt), &attrset_len, &pkt->is_fips);
if (retval != 0)
goto error;
@@ -285,6 +391,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
pkt_code_set(pkt, code);
pkt_len_set(pkt, pkt->pkt.length);
+ if (msgauth_required) {
+ /* Calculate and set the Message-Authenticator MAC. */
+ retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2);
+ if (retval != 0)
+ goto error;
+ }
+
/* Copy the attrset for future use. */
retval = packet_set_attrset(ctx, secret, pkt);
if (retval != 0)
@@ -307,14 +420,19 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
krb5_error_code retval;
krad_packet *pkt;
size_t attrset_len;
+ krb5_boolean msgauth_required;
pkt = packet_new();
if (pkt == NULL)
return ENOMEM;
+ /* Determine if Message-Authenticator is required. */
+ msgauth_required = requires_msgauth(secret, code);
+
/* Encode the attributes. */
- retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
- &attrset_len, &pkt->is_fips);
+ retval = kr_attrset_encode(set, secret, pkt_auth(request),
+ msgauth_required, pkt_attr(pkt), &attrset_len,
+ &pkt->is_fips);
if (retval != 0)
goto error;
@@ -330,6 +448,18 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
if (retval != 0)
goto error;
+ if (msgauth_required) {
+ /*
+ * Calculate and replace the Message-Authenticator MAC. Per RFC 2869
+ * section 5.14, use the authenticator from the request, not from the
+ * response.
+ */
+ retval = calculate_mac(secret, pkt, pkt_auth(request),
+ pkt_attr(pkt) + 2);
+ if (retval != 0)
+ goto error;
+ }
+
/* Copy the attrset for future use. */
retval = packet_set_attrset(ctx, secret, pkt);
if (retval != 0)
@@ -343,6 +473,34 @@ error:
return retval;
}
+/* Verify the Message-Authenticator value in pkt, using the provided
+ * authenticator (which may be from pkt or from a corresponding request). */
+static krb5_error_code
+verify_msgauth(const char *secret, const krad_packet *pkt,
+ const uint8_t auth[AUTH_FIELD_SIZE])
+{
+ uint8_t mac[MD5_DIGEST_SIZE];
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
+ const krb5_data *msgauth;
+ krb5_error_code retval;
+
+ msgauth = krad_packet_get_attr(pkt, msgauth_type, 0);
+ if (msgauth == NULL)
+ return ENODATA;
+
+ retval = calculate_mac(secret, pkt, auth, mac);
+ if (retval)
+ return retval;
+
+ if (msgauth->length != MD5_DIGEST_SIZE)
+ return EMSGSIZE;
+
+ if (k5_bcmp(mac, msgauth->data, MD5_DIGEST_SIZE) != 0)
+ return EBADMSG;
+
+ return 0;
+}
+
/* Decode a packet. */
static krb5_error_code
decode_packet(krb5_context ctx, const char *secret, const krb5_data *buffer,
@@ -394,21 +552,35 @@ krad_packet_decode_request(krb5_context ctx, const char *secret,
krad_packet **reqpkt)
{
const krad_packet *tmp = NULL;
+ krad_packet *req;
krb5_error_code retval;
- retval = decode_packet(ctx, secret, buffer, reqpkt);
- if (cb != NULL && retval == 0) {
+ retval = decode_packet(ctx, secret, buffer, &req);
+ if (retval)
+ return retval;
+
+ /* Verify Message-Authenticator if present. */
+ if (has_pkt_msgauth(req)) {
+ retval = verify_msgauth(secret, req, pkt_auth(req));
+ if (retval) {
+ krad_packet_free(req);
+ return retval;
+ }
+ }
+
+ if (cb != NULL) {
for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) {
if (pkt_id_get(*reqpkt) == pkt_id_get(tmp))
break;
}
- }
- if (cb != NULL && (retval != 0 || tmp != NULL))
- (*cb)(data, TRUE);
+ if (tmp != NULL)
+ (*cb)(data, TRUE);
+ }
+ *reqpkt = req;
*duppkt = tmp;
- return retval;
+ return 0;
}
krb5_error_code
@@ -435,9 +607,17 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
break;
}
- /* If the authenticator matches, then the response is valid. */
- if (memcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) == 0)
- break;
+ /* Verify the response authenticator. */
+ if (k5_bcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) != 0)
+ continue;
+
+ /* Verify Message-Authenticator if present. */
+ if (has_pkt_msgauth(*rsppkt)) {
+ if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0)
+ continue;
+ }
+
+ break;
}
}
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
index 4cdb8b7d8e..f9c66509bd 100644
--- a/src/lib/krad/t_attrset.c
+++ b/src/lib/krad/t_attrset.c
@@ -63,7 +63,7 @@ main(void)
noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
/* Encode attrset. */
- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len,
+ noerror(kr_attrset_encode(set, "foo", auth, FALSE, buffer, &encode_len,
&is_fips));
krad_attrset_free(set);
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
index 4a3de079c7..647d4894eb 100755
--- a/src/lib/krad/t_daemon.py
+++ b/src/lib/krad/t_daemon.py
@@ -40,6 +40,7 @@ DICTIONARY = """
ATTRIBUTE\tUser-Name\t1\tstring
ATTRIBUTE\tUser-Password\t2\toctets
ATTRIBUTE\tNAS-Identifier\t32\tstring
+ATTRIBUTE\tMessage-Authenticator\t80\toctets
"""
class TestServer(server.Server):
@@ -52,7 +53,7 @@ class TestServer(server.Server):
if key == "User-Password":
passwd = [pkt.PwDecrypt(x) for x in pkt[key]]
- reply = self.CreateReplyPacket(pkt)
+ reply = self.CreateReplyPacket(pkt, message_authenticator=True)
if passwd == ['accept']:
reply.code = packet.AccessAccept
else:
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
index c22489144f..104b6507a2 100644
--- a/src/lib/krad/t_packet.c
+++ b/src/lib/krad/t_packet.c
@@ -172,6 +172,9 @@ main(int argc, const char **argv)
krb5_data username, password;
krb5_boolean auth = FALSE;
krb5_context ctx;
+ const krad_packet *dupreq;
+ const krb5_data *encpkt;
+ krad_packet *decreq;
username = string2data("testUser");
@@ -184,9 +187,17 @@ main(int argc, const char **argv)
password = string2data("accept");
noerror(make_packet(ctx, &username, &password, &packets[ACCEPT_PACKET]));
+ encpkt = krad_packet_encode(packets[ACCEPT_PACKET]);
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
+ &dupreq, &decreq));
+ krad_packet_free(decreq);
password = string2data("reject");
noerror(make_packet(ctx, &username, &password, &packets[REJECT_PACKET]));
+ encpkt = krad_packet_encode(packets[REJECT_PACKET]);
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
+ &dupreq, &decreq));
+ krad_packet_free(decreq);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
index c3b820a411..dd5cdc5c26 100755
--- a/src/tests/t_otp.py
+++ b/src/tests/t_otp.py
@@ -49,6 +49,7 @@ ATTRIBUTE User-Name 1 string
ATTRIBUTE User-Password 2 octets
ATTRIBUTE Service-Type 6 integer
ATTRIBUTE NAS-Identifier 32 string
+ATTRIBUTE Message-Authenticator 80 octets
'''
class RadiusDaemon(Process):
@@ -97,6 +98,8 @@ class RadiusDaemon(Process):
reply.code = packet.AccessReject
replyq['reply'] = False
+ reply.add_message_authenticator()
+
outq.put(replyq)
if addr is None:
sock.send(reply.ReplyPacket())
--
2.46.0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
From 43d10f1580c033fe706470e7588c720ac7854918 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Wed, 21 Jun 2023 18:27:11 +0200
Subject: [PATCH] Add ecdsa-with-sha512/256 to supportedCMSTypes
Elliptic curve certificates are already supported for PKINIT
pre-authentication, but their associated signature types aren't
advertized. Add ecdsa-with-sha512 and ecdsa-with-sha256 OIDs to the
supportedCMSTypes list sent by the client.
[ghudson@mit.edu: edited commit message]
ticket: 9100 (new)
(cherry picked from commit 9913e5c92c4e5cb76d6ae58386f744766d2e6454)
---
src/plugins/preauth/pkinit/pkinit_constants.c | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
index 10f8688ec2..905e90d29c 100644
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
@@ -64,14 +64,52 @@ static char sha512WithRSAEncr_oid[9] = {
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
};
+/* RFC 3279 ecdsa-with-SHA1: iso(1) member-body(2) us(840) ansi-X9-62(10045)
+ * signatures(4) 1 */
+static char ecdsaWithSha1_oid[] = {
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01
+};
+
+/* RFC 5758 ecdsa-with-SHA256: iso(1) member-body(2) us(840) ansi-X9-62(10045)
+ * signatures(4) ecdsa-with-SHA2(3) 2 */
+static char ecdsaWithSha256_oid[] = {
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02
+};
+
+/* RFC 5758 ecdsa-with-SHA384: iso(1) member-body(2) us(840) ansi-X9-62(10045)
+ * signatures(4) ecdsa-with-SHA2(3) 3 */
+static char ecdsaWithSha384_oid[] = {
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03
+};
+
+/* RFC 5758 ecdsa-with-SHA512: iso(1) member-body(2) us(840) ansi-X9-62(10045)
+ * signatures(4) ecdsa-with-SHA2(3) 4 */
+static char ecdsaWithSha512_oid[] = {
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04
+};
+
const krb5_data sha256WithRSAEncr_id = {
KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
};
const krb5_data sha512WithRSAEncr_id = {
KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
};
+const krb5_data ecdsaWithSha1_id = {
+ KV5M_DATA, sizeof(ecdsaWithSha1_oid), ecdsaWithSha1_oid
+};
+const krb5_data ecdsaWithSha256_id = {
+ KV5M_DATA, sizeof(ecdsaWithSha256_oid), ecdsaWithSha256_oid
+};
+const krb5_data ecdsaWithSha384_id = {
+ KV5M_DATA, sizeof(ecdsaWithSha384_oid), ecdsaWithSha384_oid
+};
+const krb5_data ecdsaWithSha512_id = {
+ KV5M_DATA, sizeof(ecdsaWithSha512_oid), ecdsaWithSha512_oid
+};
krb5_data const * const supported_cms_algs[] = {
+ &ecdsaWithSha512_id,
+ &ecdsaWithSha256_id,
&sha512WithRSAEncr_id,
&sha256WithRSAEncr_id,
NULL
--
2.47.1

View file

@ -0,0 +1,264 @@
From fba4cbf0bc50569b8ea6d1e1c3303eaab84935e1 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 30 Jul 2023 01:07:38 -0400
Subject: [PATCH] Get rid of pkinit_crypto_openssl.h
Fold pkinit_crypto_openssl.h into the one source file where it was
used. Also clean up the include of <arpa/inet.h>, as htonl() is no
longer used after commit 1c87ce6c44a9de0824580a2d72a8a202237e01f4.
(cherry picked from commit b3352945fb8836f8b4095e0b8aad04b54aca3152)
---
src/plugins/preauth/pkinit/deps | 2 +-
.../preauth/pkinit/pkinit_crypto_openssl.c | 85 +++++++++++-
.../preauth/pkinit/pkinit_crypto_openssl.h | 121 ------------------
3 files changed, 83 insertions(+), 125 deletions(-)
delete mode 100644 src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
diff --git a/src/plugins/preauth/pkinit/deps b/src/plugins/preauth/pkinit/deps
index 58320aa801..b6f4476fe8 100644
--- a/src/plugins/preauth/pkinit/deps
+++ b/src/plugins/preauth/pkinit/deps
@@ -112,4 +112,4 @@ pkinit_crypto_openssl.so pkinit_crypto_openssl.po $(OUTPRE)pkinit_crypto_openssl
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
$(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
pkcs11.h pkinit.h pkinit_accessor.h pkinit_crypto.h \
- pkinit_crypto_openssl.c pkinit_crypto_openssl.h pkinit_trace.h
+ pkinit_crypto_openssl.c pkinit_trace.h
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index f6d494bd11..ae8599d5a2 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -30,20 +30,99 @@
*/
#include "k5-int.h"
-#include "pkinit_crypto_openssl.h"
#include "k5-buf.h"
#include "k5-err.h"
#include "k5-hex.h"
-#include <unistd.h>
+#include "pkinit.h"
#include <dirent.h>
-#include <arpa/inet.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pkcs12.h>
+#include <openssl/obj_mac.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#include <openssl/asn1.h>
+#include <openssl/pem.h>
+#include <openssl/asn1t.h>
+#include <openssl/cms.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/core_names.h>
#include <openssl/kdf.h>
+#include <openssl/decoder.h>
#include <openssl/params.h>
#endif
+#define DN_BUF_LEN 256
+#define MAX_CREDS_ALLOWED 20
+
+struct _pkinit_cred_info {
+ char *name;
+ X509 *cert;
+ EVP_PKEY *key;
+#ifndef WITHOUT_PKCS11
+ CK_BYTE_PTR cert_id;
+ int cert_id_len;
+#endif
+};
+typedef struct _pkinit_cred_info *pkinit_cred_info;
+
+struct _pkinit_identity_crypto_context {
+ pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
+ STACK_OF(X509) *my_certs; /* available user certs */
+ char *identity; /* identity name for user cert */
+ int cert_index; /* cert to use out of available certs*/
+ EVP_PKEY *my_key; /* available user keys if in filesystem */
+ STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
+ STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
+ STACK_OF(X509_CRL) *revoked; /* available crls */
+ int pkcs11_method;
+ krb5_prompter_fct prompter;
+ void *prompter_data;
+#ifndef WITHOUT_PKCS11
+ char *p11_module_name;
+ CK_SLOT_ID slotid;
+ char *token_label;
+ char *cert_label;
+ /* These are crypto-specific. */
+ struct plugin_file_handle *p11_module;
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST_PTR p11;
+ uint8_t *cert_id;
+ size_t cert_id_len;
+ CK_MECHANISM_TYPE mech;
+#endif
+ krb5_boolean defer_id_prompt;
+ pkinit_deferred_id *deferred_ids;
+};
+
+struct _pkinit_plg_crypto_context {
+ EVP_PKEY *dh_1024;
+ EVP_PKEY *dh_2048;
+ EVP_PKEY *dh_4096;
+ EVP_PKEY *ec_p256;
+ EVP_PKEY *ec_p384;
+ EVP_PKEY *ec_p521;
+ ASN1_OBJECT *id_pkinit_authData;
+ ASN1_OBJECT *id_pkinit_DHKeyData;
+ ASN1_OBJECT *id_pkinit_rkeyData;
+ ASN1_OBJECT *id_pkinit_san;
+ ASN1_OBJECT *id_ms_san_upn;
+ ASN1_OBJECT *id_pkinit_KPClientAuth;
+ ASN1_OBJECT *id_pkinit_KPKdc;
+ ASN1_OBJECT *id_ms_kp_sc_logon;
+ ASN1_OBJECT *id_kp_serverAuth;
+};
+
+struct _pkinit_req_crypto_context {
+ X509 *received_cert;
+ EVP_PKEY *client_pkey;
+};
+
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
deleted file mode 100644
index b7a3358800..0000000000
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * COPYRIGHT (C) 2006,2007
- * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
- * ALL RIGHTS RESERVED
- *
- * Permission is granted to use, copy, create derivative works
- * and redistribute this software and such derivative works
- * for any purpose, so long as the name of The University of
- * Michigan is not used in any advertising or publicity
- * pertaining to the use of distribution of this software
- * without specific, written prior authorization. If the
- * above copyright notice or any other identification of the
- * University of Michigan is included in any copy of any
- * portion of this software, then the disclaimer below must
- * also be included.
- *
- * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
- * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
- * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
- * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
- * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
- * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
- * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
- * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGES.
- */
-
-#ifndef _PKINIT_CRYPTO_OPENSSL_H
-#define _PKINIT_CRYPTO_OPENSSL_H
-
-#include "pkinit.h"
-
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-#include <openssl/x509.h>
-#include <openssl/pkcs7.h>
-#include <openssl/pkcs12.h>
-#include <openssl/obj_mac.h>
-#include <openssl/x509v3.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#include <openssl/asn1.h>
-#include <openssl/pem.h>
-#include <openssl/asn1t.h>
-#include <openssl/cms.h>
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#include <openssl/core_names.h>
-#include <openssl/decoder.h>
-#endif
-
-#define DN_BUF_LEN 256
-#define MAX_CREDS_ALLOWED 20
-
-struct _pkinit_cred_info {
- char *name;
- X509 *cert;
- EVP_PKEY *key;
-#ifndef WITHOUT_PKCS11
- CK_BYTE_PTR cert_id;
- int cert_id_len;
-#endif
-};
-typedef struct _pkinit_cred_info * pkinit_cred_info;
-
-struct _pkinit_identity_crypto_context {
- pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
- STACK_OF(X509) *my_certs; /* available user certs */
- char *identity; /* identity name for user cert */
- int cert_index; /* cert to use out of available certs*/
- EVP_PKEY *my_key; /* available user keys if in filesystem */
- STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
- STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
- STACK_OF(X509_CRL) *revoked; /* available crls */
- int pkcs11_method;
- krb5_prompter_fct prompter;
- void *prompter_data;
-#ifndef WITHOUT_PKCS11
- char *p11_module_name;
- CK_SLOT_ID slotid;
- char *token_label;
- char *cert_label;
- /* These are crypto-specific */
- struct plugin_file_handle *p11_module;
- CK_SESSION_HANDLE session;
- CK_FUNCTION_LIST_PTR p11;
- uint8_t *cert_id;
- size_t cert_id_len;
- CK_MECHANISM_TYPE mech;
-#endif
- krb5_boolean defer_id_prompt;
- pkinit_deferred_id *deferred_ids;
-};
-
-struct _pkinit_plg_crypto_context {
- EVP_PKEY *dh_1024;
- EVP_PKEY *dh_2048;
- EVP_PKEY *dh_4096;
- EVP_PKEY *ec_p256;
- EVP_PKEY *ec_p384;
- EVP_PKEY *ec_p521;
- ASN1_OBJECT *id_pkinit_authData;
- ASN1_OBJECT *id_pkinit_DHKeyData;
- ASN1_OBJECT *id_pkinit_rkeyData;
- ASN1_OBJECT *id_pkinit_san;
- ASN1_OBJECT *id_ms_san_upn;
- ASN1_OBJECT *id_pkinit_KPClientAuth;
- ASN1_OBJECT *id_pkinit_KPKdc;
- ASN1_OBJECT *id_ms_kp_sc_logon;
- ASN1_OBJECT *id_kp_serverAuth;
-};
-
-struct _pkinit_req_crypto_context {
- X509 *received_cert;
- EVP_PKEY *client_pkey;
-};
-
-#endif /* _PKINIT_CRYPTO_OPENSSL_H */
--
2.47.1

View file

@ -0,0 +1,157 @@
From 1b01057df4c2223fbf92be44f1e764207208ef03 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 26 Feb 2024 19:03:38 -0500
Subject: [PATCH] Use SoftHSMv2 for PKCS11 PKINIT tests
Instead of softpkcs11, use SoftHSMv2 to mock the PKCS11 token for
PKINIT tests. Use pkcs11-tool from OpenSC to initialize the token and
import a certificate and key. SoftHSM does not support PIN-less
tokens (see https://github.com/opendnssec/SoftHSMv2/issues/480) so
remove that test for now.
(cherry picked from commit 8ab61608236883fdc5c2d43f4bd1ff2094401d19)
---
.github/workflows/build.yml | 2 +-
src/tests/t_pkinit.py | 82 ++++++++++++++++++++-----------------
2 files changed, 45 insertions(+), 39 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 68a4788adb..d7ae86b150 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -33,7 +33,7 @@ jobs:
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get update -qq
- sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh
+ sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh softhsm2 opensc
pip3 install pyrad
- name: Build
env:
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index f8f2debc1b..4435746429 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -1,11 +1,10 @@
from k5test import *
+import re
# Skip this test if pkinit wasn't built.
if not pkinit_enabled:
skip_rest('PKINIT tests', 'PKINIT module not built')
-soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so')
-
# Construct a krb5.conf fragment configuring pkinit.
user_pem = os.path.join(pkinit_certs, 'user.pem')
privkey_pem = os.path.join(pkinit_certs, 'privkey.pem')
@@ -55,9 +54,6 @@ p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12
p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
p12_generic_identity = 'PKCS12:%s' % generic_p12
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
-p11_identity = 'PKCS11:' + soft_pkcs11
-p11_token_identity = ('PKCS11:module_name=' + soft_pkcs11 +
- ':slotid=1:token=SoftToken (token)')
# Start a realm with the test kdb module for the following UPN SAN tests.
realm = K5Realm(kdc_conf=alias_kdc_conf, create_kdb=False, pkinit=True)
@@ -389,53 +385,63 @@ realm.klist(realm.user_princ)
realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
expected_code=1, expected_msg='Preauthentication failed while')
-softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
-realm.env['SOFTPKCS11RC'] = softpkcs11rc
+softhsm2 = '/usr/lib/softhsm/libsofthsm2.so'
+if not os.path.exists(softhsm2):
+ skip_rest('PKCS11 tests', 'SoftHSMv2 required')
+pkcs11_tool = which('pkcs11-tool')
+if not pkcs11_tool:
+ skip_rest('PKCS11 tests', 'pkcs11-tool from OpenSC required')
+tool_cmd = [pkcs11_tool, '--module', softhsm2]
+
+# Prepare a SoftHSM token.
+softhsm2_conf = os.path.join(realm.testdir, 'softhsm2.conf')
+softhsm2_tokens = os.path.join(realm.testdir, 'tokens')
+os.mkdir(softhsm2_tokens)
+realm.env['SOFTHSM2_CONF'] = softhsm2_conf
+with open(softhsm2_conf, 'w') as f:
+ f.write('directories.tokendir = %s\n' % softhsm2_tokens)
+realm.run(tool_cmd + ['--init-token', '--label', 'user',
+ '--so-pin', 'sopin', '--init-pin', '--pin', 'userpin'])
+realm.run(tool_cmd + ['-w', user_pem, '-y', 'cert'])
+realm.run(tool_cmd + ['-w', privkey_pem, '-y', 'privkey',
+ '-l', '--pin', 'userpin'])
+
+# Extract the slot ID generated by SoftHSM.
+out = realm.run(tool_cmd + ['-L'])
+m = re.search(r'slot ID 0x([0-9a-f]+)\n', out)
+if not m:
+ fail('could not extract slot ID from SoftHSM token')
+slot_id = int(m.group(1), 16)
+
+p11_attr = 'X509_user_identity=PKCS11:' + softhsm2
+p11_token_identity = ('PKCS11:module_name=%s:slotid=%d:token=user' %
+ (softhsm2, slot_id))
-# PKINIT with PKCS11: identity, with no need for a PIN.
-mark('PKCS11 identity, no PIN')
-conf = open(softpkcs11rc, 'w')
-conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem))
-conf.close()
-# Expect to succeed without having to supply any more information.
-realm.kinit(realm.user_princ,
- flags=['-X', 'X509_user_identity=%s' % p11_identity])
+mark('PKCS11 identity, with PIN (prompter)')
+realm.kinit(realm.user_princ, flags=['-X', p11_attr], password='userpin')
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
-# PKINIT with PKCS11: identity, with a PIN supplied by the prompter.
-mark('PKCS11 identity, with PIN (prompter)')
-os.remove(softpkcs11rc)
-conf = open(softpkcs11rc, 'w')
-conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem,
- privkey_enc_pem))
-conf.close()
-# Expect failure if the responder does nothing, and there's no prompter
+mark('PKCS11 identity, unavailable PIN')
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
- '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ],
- expected_code=2)
-realm.kinit(realm.user_princ,
- flags=['-X', 'X509_user_identity=%s' % p11_identity],
- password='encrypted')
-realm.klist(realm.user_princ)
-realm.run([kvno, realm.host_princ])
+ '-X', p11_attr, realm.user_princ], expected_code=2)
-# Supply the wrong PIN.
mark('PKCS11 identity, wrong PIN')
expected_trace = ('PKINIT client has no configured identity; giving up',)
realm.kinit(realm.user_princ,
- flags=['-X', 'X509_user_identity=%s' % p11_identity],
+ flags=['-X', p11_attr],
password='wrong', expected_code=1, expected_trace=expected_trace)
# PKINIT with PKCS11: identity, with a PIN supplied by the responder.
-# Supply the response in raw form.
+# Supply the response in raw form. Expect the PIN_COUNT_LOW flag (1)
+# to be set due to the previous test.
mark('PKCS11 identity, with PIN (responder)')
-realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
- '-r', 'pkinit={"%s": "encrypted"}' % p11_token_identity,
- '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ])
+realm.run(['./responder', '-x', 'pkinit={"%s": 1}' % p11_token_identity,
+ '-r', 'pkinit={"%s": "userpin"}' % p11_token_identity,
+ '-X', p11_attr, realm.user_princ])
# Supply the response through the convenience API.
-realm.run(['./responder', '-X', 'X509_user_identity=%s' % p11_identity,
- '-p', '%s=%s' % (p11_token_identity, 'encrypted'),
+realm.run(['./responder', '-X', p11_attr,
+ '-p', '%s=%s' % (p11_token_identity, 'userpin'),
realm.user_princ])
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
--
2.47.1

View file

@ -0,0 +1,202 @@
From b0315d30f066c4241fcecc33dd9e4d1c7c28b9d8 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 9 Feb 2024 17:32:40 -0500
Subject: [PATCH] Simplify PKINIT cert representation
In the _pkinit_identity_crypto_context structure, the my_certs field
is a stack which only ever contains one cert and is only ever used to
retrieve that one cert. The cert_index field is always 0. Replace
these fields with a my_cert field pointing directly to the X509
certificate.
Simplify crypto_cert_select_default() by making it call
crypto_cert_select() with index 0 after verifying the certificate
count.
(cherry picked from commit f95dfb7908456f9563cee66706216a21df8d791f)
---
.../preauth/pkinit/pkinit_crypto_openssl.c | 74 +++++--------------
1 file changed, 20 insertions(+), 54 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index ae8599d5a2..da59cb1e02 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -73,10 +73,9 @@ typedef struct _pkinit_cred_info *pkinit_cred_info;
struct _pkinit_identity_crypto_context {
pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
- STACK_OF(X509) *my_certs; /* available user certs */
+ X509 *my_cert; /* selected user or KDC cert */
char *identity; /* identity name for user cert */
- int cert_index; /* cert to use out of available certs*/
- EVP_PKEY *my_key; /* available user keys if in filesystem */
+ EVP_PKEY *my_key; /* selected cert key if in filesystem */
STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
STACK_OF(X509_CRL) *revoked; /* available crls */
@@ -1489,8 +1488,7 @@ pkinit_init_certs(pkinit_identity_crypto_context ctx)
for (i = 0; i < MAX_CREDS_ALLOWED; i++)
ctx->creds[i] = NULL;
- ctx->my_certs = NULL;
- ctx->cert_index = 0;
+ ctx->my_cert = NULL;
ctx->my_key = NULL;
ctx->trustedCAs = NULL;
ctx->intermediateCAs = NULL;
@@ -1506,8 +1504,8 @@ pkinit_fini_certs(pkinit_identity_crypto_context ctx)
if (ctx == NULL)
return;
- if (ctx->my_certs != NULL)
- sk_X509_pop_free(ctx->my_certs, X509_free);
+ if (ctx->my_cert != NULL)
+ X509_free(ctx->my_cert);
if (ctx->my_key != NULL)
EVP_PKEY_free(ctx->my_key);
@@ -1696,7 +1694,6 @@ cms_signeddata_create(krb5_context context,
ASN1_OCTET_STRING *digest = NULL;
unsigned int alg_len = 0, digest_len = 0;
unsigned char *y = NULL;
- X509 *cert = NULL;
ASN1_OBJECT *oid = NULL, *oid_copy;
/* Start creating PKCS7 data. */
@@ -1715,7 +1712,7 @@ cms_signeddata_create(krb5_context context,
if (oid == NULL)
goto cleanup;
- if (id_cryptoctx->my_certs != NULL) {
+ if (id_cryptoctx->my_cert != NULL) {
X509_STORE *certstore = NULL;
X509_STORE_CTX *certctx;
STACK_OF(X509) *certstack = NULL;
@@ -1726,8 +1723,6 @@ cms_signeddata_create(krb5_context context,
if ((cert_stack = sk_X509_new_null()) == NULL)
goto cleanup;
- cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
-
certstore = X509_STORE_new();
if (certstore == NULL)
goto cleanup;
@@ -1736,7 +1731,7 @@ cms_signeddata_create(krb5_context context,
certctx = X509_STORE_CTX_new();
if (certctx == NULL)
goto cleanup;
- X509_STORE_CTX_init(certctx, certstore, cert,
+ X509_STORE_CTX_init(certctx, certstore, id_cryptoctx->my_cert,
id_cryptoctx->intermediateCAs);
X509_STORE_CTX_trusted_stack(certctx, id_cryptoctx->trustedCAs);
if (!X509_verify_cert(certctx)) {
@@ -1764,13 +1759,13 @@ cms_signeddata_create(krb5_context context,
if (!ASN1_INTEGER_set(p7si->version, 1))
goto cleanup;
if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
- X509_get_issuer_name(cert)))
+ X509_get_issuer_name(id_cryptoctx->my_cert)))
goto cleanup;
/* because ASN1_INTEGER_set is used to set a 'long' we will do
* things the ugly way. */
ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
if (!(p7si->issuer_and_serial->serial =
- ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
+ ASN1_INTEGER_dup(X509_get_serialNumber(id_cryptoctx->my_cert))))
goto cleanup;
/* will not fill-out EVP_PKEY because it's on the smartcard */
@@ -3311,7 +3306,7 @@ pkinit_check_kdc_pkid(krb5_context context,
PKCS7_ISSUER_AND_SERIAL *is = NULL;
const unsigned char *p = pdid_buf;
int status = 1;
- X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
+ X509 *kdc_cert = id_cryptoctx->my_cert;
*valid_kdcPkId = 0;
pkiDebug("found kdcPkId in AS REQ\n");
@@ -4783,7 +4778,8 @@ cleanup:
}
/*
- * Set the certificate in idctx->creds[cred_index] as the selected certificate.
+ * Set the certificate in idctx->creds[cred_index] as the selected certificate,
+ * stealing pointers from it.
*/
krb5_error_code
crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx,
@@ -4795,20 +4791,17 @@ crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx,
return ENOENT;
ci = idctx->creds[cred_index];
- /* copy the selected cert into our id_cryptoctx */
- if (idctx->my_certs != NULL)
- sk_X509_pop_free(idctx->my_certs, X509_free);
- idctx->my_certs = sk_X509_new_null();
- sk_X509_push(idctx->my_certs, ci->cert);
- free(idctx->identity);
+
+ idctx->my_cert = ci->cert;
+ ci->cert = NULL;
+
/* hang on to the selected credential name */
+ free(idctx->identity);
if (ci->name != NULL)
idctx->identity = strdup(ci->name);
else
idctx->identity = NULL;
- ci->cert = NULL; /* Don't free it twice */
- idctx->cert_index = 0;
if (idctx->pkcs11_method != 1) {
idctx->my_key = ci->key;
ci->key = NULL; /* Don't free it twice */
@@ -4837,41 +4830,14 @@ crypto_cert_select_default(krb5_context context,
retval = crypto_cert_get_count(id_cryptoctx, &cert_count);
if (retval)
- goto errout;
+ return retval;
if (cert_count != 1) {
TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count);
- retval = EINVAL;
- goto errout;
- }
- /* copy the selected cert into our id_cryptoctx */
- if (id_cryptoctx->my_certs != NULL) {
- sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
+ return EINVAL;
}
- id_cryptoctx->my_certs = sk_X509_new_null();
- sk_X509_push(id_cryptoctx->my_certs, id_cryptoctx->creds[0]->cert);
- id_cryptoctx->creds[0]->cert = NULL; /* Don't free it twice */
- id_cryptoctx->cert_index = 0;
- /* hang on to the selected credential name */
- if (id_cryptoctx->creds[0]->name != NULL)
- id_cryptoctx->identity = strdup(id_cryptoctx->creds[0]->name);
- else
- id_cryptoctx->identity = NULL;
- if (id_cryptoctx->pkcs11_method != 1) {
- id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
- id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */
- }
-#ifndef WITHOUT_PKCS11
- else {
- id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
- id_cryptoctx->creds[0]->cert_id = NULL; /* Don't free it twice */
- id_cryptoctx->cert_id_len = id_cryptoctx->creds[0]->cert_id_len;
- }
-#endif
- retval = 0;
-errout:
- return retval;
+ return crypto_cert_select(context, id_cryptoctx, 0);
}
--
2.47.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,599 @@
From e43c05e7b0b93401dd68fc3ec3186c3a455b04ea Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 23 Feb 2024 13:51:26 -0500
Subject: [PATCH] Improve PKCS11 error reporting in PKINIT
Create a helper p11err() to set extended error message for failed
PKCS11 operations, and use it instead of pkiDebug() and pkcs11error().
ticket: 9113 (new)
(cherry picked from commit 98afb314d13939cbee19c69885dcb655db8460da)
---
.../preauth/pkinit/pkinit_crypto_openssl.c | 262 ++++++++++--------
src/plugins/preauth/pkinit/pkinit_trace.h | 9 -
2 files changed, 142 insertions(+), 129 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 4accfc2664..402bf1b9b3 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -161,9 +161,11 @@ static krb5_error_code pkinit_create_sequence_of_principal_identifiers
int type, krb5_pa_data ***e_data_out);
#ifndef WITHOUT_PKCS11
-static krb5_error_code pkinit_find_private_key
-(pkinit_identity_crypto_context, CK_ATTRIBUTE_TYPE usage,
- CK_OBJECT_HANDLE *objp);
+static krb5_error_code
+pkinit_find_private_key(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ CK_ATTRIBUTE_TYPE usage,
+ CK_OBJECT_HANDLE *objp);
static krb5_error_code pkinit_login
(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
CK_TOKEN_INFO *tip, const char *password);
@@ -180,6 +182,8 @@ static krb5_error_code pkinit_sign_data_pkcs11
(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
unsigned char *data, unsigned int data_len,
unsigned char **sig, unsigned int *sig_len);
+
+static krb5_error_code p11err(krb5_context context, CK_RV rv, const char *op);
#endif /* WITHOUT_PKCS11 */
static krb5_error_code pkinit_sign_data_fs
@@ -197,9 +201,6 @@ create_krb5_invalidCertificates(krb5_context context,
static krb5_error_code
create_identifiers_from_stack(STACK_OF(X509) *sk,
krb5_external_principal_identifier *** ids);
-static const char *
-pkcs11err(int err);
-
#if OPENSSL_VERSION_NUMBER < 0x10100000L
@@ -944,8 +945,9 @@ cleanup:
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+#ifndef WITHOUT_PKC11
static struct pkcs11_errstrings {
- short code;
+ CK_RV code;
char *text;
} pkcs11_errstrings[] = {
{ 0x0, "ok" },
@@ -1035,6 +1037,7 @@ static struct pkcs11_errstrings {
{ 0x200, "function rejected" },
{ -1, NULL }
};
+#endif
MAKE_INIT_FUNCTION(pkinit_openssl_init);
@@ -1563,6 +1566,8 @@ pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
free(ctx->token_label);
free(ctx->cert_id);
free(ctx->cert_label);
+ ctx->p11_module_name = ctx->token_label = ctx->cert_label = NULL;
+ ctx->cert_id = NULL;
#endif
}
@@ -3344,48 +3349,53 @@ pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
}
#ifndef WITHOUT_PKCS11
-static struct plugin_file_handle *
+static krb5_error_code
load_pkcs11_module(krb5_context context, const char *modname,
- CK_FUNCTION_LIST_PTR_PTR p11p)
+ struct plugin_file_handle **handle_out,
+ CK_FUNCTION_LIST_PTR_PTR p11_out)
{
struct plugin_file_handle *handle = NULL;
- CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
+ CK_RV rv, (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
struct errinfo einfo = EMPTY_ERRINFO;
- const char *errmsg = NULL;
+ const char *errmsg = NULL, *failure;
void (*sym)(void);
long err;
- CK_RV rv;
TRACE_PKINIT_PKCS11_OPEN(context, modname);
err = krb5int_open_plugin(modname, &handle, &einfo);
if (err) {
- errmsg = k5_get_error(&einfo, err);
- TRACE_PKINIT_PKCS11_OPEN_FAILED(context, errmsg);
+ failure = _("Cannot load PKCS11 module");
goto error;
}
err = krb5int_get_plugin_func(handle, "C_GetFunctionList", &sym, &einfo);
if (err) {
- errmsg = k5_get_error(&einfo, err);
- TRACE_PKINIT_PKCS11_GETSYM_FAILED(context, errmsg);
+ failure = _("Cannot find C_GetFunctionList in PKCS11 module");
goto error;
}
getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))sym;
- rv = (*getflist)(p11p);
+ rv = (*getflist)(p11_out);
if (rv != CKR_OK) {
- TRACE_PKINIT_PKCS11_GETFLIST_FAILED(context, pkcs11err(rv));
+ failure = _("Cannot retrieve function list in PKCS11 module");
goto error;
}
- return handle;
+ *handle_out = handle;
+ return 0;
error:
- k5_free_error(&einfo, errmsg);
+ if (err) {
+ errmsg = k5_get_error(&einfo, err);
+ k5_setmsg(context, err, _("%s: %s"), failure, errmsg);
+ } else {
+ err = KRB5KDC_ERR_PREAUTH_FAILED;
+ k5_setmsg(context, err, "%s", failure);
+ }
k5_clear_error(&einfo);
if (handle != NULL)
krb5int_close_plugin(handle);
- return NULL;
+ return err;
}
static krb5_error_code
@@ -3393,12 +3403,13 @@ pkinit_login(krb5_context context,
pkinit_identity_crypto_context id_cryptoctx,
CK_TOKEN_INFO *tip, const char *password)
{
+ krb5_error_code ret = 0;
+ CK_RV rv;
krb5_data rdat;
char *prompt;
const char *warning;
krb5_prompt kprompt;
krb5_prompt_type prompt_type;
- int r = 0;
if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
rdat.data = NULL;
@@ -3407,7 +3418,7 @@ pkinit_login(krb5_context context,
rdat.data = strdup(password);
rdat.length = strlen(password);
} else if (id_cryptoctx->prompter == NULL) {
- r = KRB5_LIBOS_CANTREADPWD;
+ ret = KRB5_LIBOS_CANTREADPWD;
rdat.data = NULL;
} else {
if (tip->flags & CKF_USER_PIN_LOCKED)
@@ -3431,31 +3442,28 @@ pkinit_login(krb5_context context,
/* PROMPTER_INVOCATION */
k5int_set_prompt_types(context, &prompt_type);
- r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
- NULL, NULL, 1, &kprompt);
+ ret = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
+ NULL, NULL, 1, &kprompt);
k5int_set_prompt_types(context, 0);
free(prompt);
}
- if (r == 0) {
- r = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
- (u_char *) rdat.data, rdat.length);
-
- if (r != CKR_OK) {
- TRACE_PKINIT_PKCS11_LOGIN_FAILED(context, pkcs11err(r));
- r = KRB5KDC_ERR_PREAUTH_FAILED;
- }
+ if (!ret) {
+ rv = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
+ (uint8_t *)rdat.data, rdat.length);
+ if (rv != CKR_OK)
+ ret = p11err(context, rv, "C_Login");
}
free(rdat.data);
- return r;
+ return ret;
}
static krb5_error_code
pkinit_open_session(krb5_context context,
pkinit_identity_crypto_context cctx)
{
- CK_ULONG i, pret;
+ CK_ULONG i, rv;
unsigned char *cp;
size_t label_len;
CK_ULONG count = 0;
@@ -3469,30 +3477,35 @@ pkinit_open_session(krb5_context context,
return 0; /* session already open */
/* Load module */
- cctx->p11_module = load_pkcs11_module(context, cctx->p11_module_name,
- &cctx->p11);
- if (cctx->p11_module == NULL)
- return KRB5KDC_ERR_PREAUTH_FAILED;
+ ret = load_pkcs11_module(context, cctx->p11_module_name, &cctx->p11_module,
+ &cctx->p11);
+ if (ret)
+ goto cleanup;
/* Init */
- pret = cctx->p11->C_Initialize(NULL);
- if (pret != CKR_OK) {
- pkiDebug("C_Initialize: %s\n", pkcs11err(pret));
- return KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = cctx->p11->C_Initialize(NULL);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_Initialize");
+ goto cleanup;
}
/* Get the list of available slots */
- if (cctx->p11->C_GetSlotList(TRUE, NULL, &count) != CKR_OK)
- return KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = cctx->p11->C_GetSlotList(TRUE, NULL, &count);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_GetSlotList");
+ goto cleanup;
+ }
if (count == 0) {
TRACE_PKINIT_PKCS11_NO_TOKEN(context);
- return KRB5KDC_ERR_PREAUTH_FAILED;
+ ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ goto cleanup;
}
- slotlist = calloc(count, sizeof(CK_SLOT_ID));
+ slotlist = k5calloc(count, sizeof(CK_SLOT_ID), &ret);
if (slotlist == NULL)
- return ENOMEM;
- if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK) {
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ goto cleanup;
+ rv = cctx->p11->C_GetSlotList(TRUE, slotlist, &count);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_GetSlotList");
goto cleanup;
}
@@ -3503,19 +3516,17 @@ pkinit_open_session(krb5_context context,
continue;
/* Open session */
- pret = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
- NULL, NULL, &cctx->session);
- if (pret != CKR_OK) {
- pkiDebug("C_OpenSession: %s\n", pkcs11err(pret));
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
+ NULL, NULL, &cctx->session);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_OpenSession");
goto cleanup;
}
/* Get token info */
- pret = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo);
- if (pret != CKR_OK) {
- pkiDebug("C_GetTokenInfo: %s\n", pkcs11err(pret));
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_GetTokenInfo");
goto cleanup;
}
@@ -3577,6 +3588,10 @@ pkinit_open_session(krb5_context context,
ret = 0;
cleanup:
+ /* On error, finalize the PKCS11 fields to ensure that we don't mistakenly
+ * short-circuit with success on the next call. */
+ if (ret)
+ pkinit_fini_pkcs11(cctx);
free(slotlist);
free(p11name);
return ret;
@@ -3598,16 +3613,17 @@ cleanup:
* If there are more than one, we just take the first one.
*/
-krb5_error_code
-pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
+static krb5_error_code
+pkinit_find_private_key(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
CK_ATTRIBUTE_TYPE usage,
CK_OBJECT_HANDLE *objp)
{
CK_OBJECT_CLASS cls;
CK_ATTRIBUTE attrs[4];
CK_ULONG count;
+ CK_RV rv;
unsigned int nattrs = 0;
- int r;
#ifdef PKINIT_USE_KEY_USAGE
CK_BBOOL true_false;
#endif
@@ -3637,18 +3653,21 @@ pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
nattrs++;
- r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
- if (r != CKR_OK) {
- pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
- pkcs11err(r));
- return KRB5KDC_ERR_PREAUTH_FAILED;
- }
+ rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
+ nattrs);
+ if (rv != CKR_OK)
+ return p11err(context, rv, _("C_FindObjectsInit"));
- r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
+ rv = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1,
+ &count);
id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
- pkiDebug("found %d private keys (%s)\n", (int)count, pkcs11err(r));
- if (r != CKR_OK || count < 1)
+ if (rv != CKR_OK)
+ return p11err(context, rv, _("C_FindObjects"));
+ if (count < 1) {
+ k5_setmsg(context, KRB5KDC_ERR_PREAUTH_FAILED,
+ _("Found no private keys in PKCS11 token"));
return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
return 0;
}
#endif
@@ -3796,34 +3815,32 @@ pkinit_sign_data_pkcs11(krb5_context context,
CK_FUNCTION_LIST_PTR p11;
CK_ATTRIBUTE attr;
CK_KEY_TYPE keytype;
+ CK_RV rv;
EVP_MD_CTX *ctx;
const EVP_MD *md = EVP_sha256();
unsigned int mdlen;
uint8_t mdbuf[EVP_MAX_MD_SIZE], *dinfo = NULL, *sigbuf = NULL, *input;
size_t dinfo_len, input_len;
- int r;
*sig = NULL;
*sig_len = 0;
- if (pkinit_open_session(context, id_cryptoctx)) {
- pkiDebug("can't open pkcs11 session\n");
- return KRB5KDC_ERR_PREAUTH_FAILED;
- }
+ ret = pkinit_open_session(context, id_cryptoctx);
+ if (ret)
+ return ret;
p11 = id_cryptoctx->p11;
session = id_cryptoctx->session;
- ret = pkinit_find_private_key(id_cryptoctx, CKA_SIGN, &obj);
+ ret = pkinit_find_private_key(context, id_cryptoctx, CKA_SIGN, &obj);
if (ret)
return ret;
attr.type = CKA_KEY_TYPE;
attr.pValue = &keytype;
attr.ulValueLen = sizeof(keytype);
- r = p11->C_GetAttributeValue(session, obj, &attr, 1);
- if (r) {
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(r));
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = p11->C_GetAttributeValue(session, obj, &attr, 1);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_GetAttributeValue");
goto cleanup;
}
@@ -3865,10 +3882,9 @@ pkinit_sign_data_pkcs11(krb5_context context,
mech.pParameter = NULL;
mech.ulParameterLen = 0;
- r = p11->C_SignInit(session, &mech, obj);
- if (r != CKR_OK) {
- pkiDebug("C_SignInit: %s\n", pkcs11err(r));
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = p11->C_SignInit(session, &mech, obj);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_SignInit");
goto cleanup;
}
@@ -3881,18 +3897,17 @@ pkinit_sign_data_pkcs11(krb5_context context,
if (sigbuf == NULL)
goto cleanup;
- r = p11->C_Sign(session, input, input_len, sigbuf, &len);
- if (r == CKR_BUFFER_TOO_SMALL || (r == CKR_OK && len >= PK_SIGLEN_GUESS)) {
+ rv = p11->C_Sign(session, input, input_len, sigbuf, &len);
+ if (rv == CKR_BUFFER_TOO_SMALL ||
+ (rv == CKR_OK && len >= PK_SIGLEN_GUESS)) {
free(sigbuf);
- pkiDebug("C_Sign realloc %d\n", (int) len);
sigbuf = k5alloc(len, &ret);
if (sigbuf == NULL)
goto cleanup;
- r = p11->C_Sign(session, input, input_len, sigbuf, &len);
+ rv = p11->C_Sign(session, input, input_len, sigbuf, &len);
}
- if (r != CKR_OK) {
- pkiDebug("C_Sign: %s\n", pkcs11err(r));
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_Sign");
goto cleanup;
}
@@ -4348,13 +4363,14 @@ reassemble_pkcs11_name(pkinit_identity_opts *idopts)
}
static krb5_error_code
-load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
- pkinit_identity_opts *idopts, pkinit_cred_info *cred_out)
+load_one_cert(krb5_context context, CK_FUNCTION_LIST_PTR p11,
+ CK_SESSION_HANDLE session, pkinit_identity_opts *idopts,
+ pkinit_cred_info *cred_out)
{
krb5_error_code ret;
CK_ATTRIBUTE attrs[2];
CK_BYTE_PTR cert = NULL, cert_id = NULL;
- CK_RV pret;
+ CK_RV rv;
const unsigned char *cp;
CK_OBJECT_HANDLE obj;
CK_ULONG count;
@@ -4364,8 +4380,8 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
*cred_out = NULL;
/* Look for X.509 cert. */
- pret = p11->C_FindObjects(session, &obj, 1, &count);
- if (pret != CKR_OK || count <= 0)
+ rv = p11->C_FindObjects(session, &obj, 1, &count);
+ if (rv != CKR_OK || count <= 0)
return 0;
/* Get cert and id len. */
@@ -4375,10 +4391,9 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
attrs[1].type = CKA_ID;
attrs[1].pValue = NULL;
attrs[1].ulValueLen = 0;
- pret = p11->C_GetAttributeValue(session, obj, attrs, 2);
- if (pret != CKR_OK && pret != CKR_BUFFER_TOO_SMALL) {
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(pret));
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = p11->C_GetAttributeValue(session, obj, attrs, 2);
+ if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL) {
+ ret = p11err(context, rv, "C_GetAttributeValue");
goto cleanup;
}
@@ -4393,10 +4408,9 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
attrs[0].pValue = cert;
attrs[1].type = CKA_ID;
attrs[1].pValue = cert_id;
- pret = p11->C_GetAttributeValue(session, obj, attrs, 2);
- if (pret != CKR_OK) {
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(pret));
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ rv = p11->C_GetAttributeValue(session, obj, attrs, 2);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_GetAttributeValue");
goto cleanup;
}
@@ -4406,7 +4420,8 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
cp = (unsigned char *)cert;
x = d2i_X509(NULL, &cp, (int)attrs[0].ulValueLen);
if (x == NULL) {
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ ret = oerr(context, 0,
+ _("Failed to decode X509 certificate from PKCS11 token"));
goto cleanup;
}
@@ -4444,7 +4459,7 @@ pkinit_get_certs_pkcs11(krb5_context context,
int i;
unsigned int nattrs;
krb5_error_code ret;
- CK_RV pret;
+ CK_RV rv;
/* Copy stuff from idopts -> id_cryptoctx */
if (idopts->p11_module_name != NULL) {
@@ -4516,16 +4531,16 @@ pkinit_get_certs_pkcs11(krb5_context context,
nattrs++;
}
- pret = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
- nattrs);
- if (pret != CKR_OK) {
- pkiDebug("C_FindObjectsInit: %s\n", pkcs11err(pret));
+ rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
+ nattrs);
+ if (rv != CKR_OK) {
+ ret = p11err(context, rv, "C_FindObjectsInit");
return KRB5KDC_ERR_PREAUTH_FAILED;
}
for (i = 0; i < MAX_CREDS_ALLOWED; i++) {
- ret = load_one_cert(id_cryptoctx->p11, id_cryptoctx->session, idopts,
- &id_cryptoctx->creds[i]);
+ ret = load_one_cert(context, id_cryptoctx->p11, id_cryptoctx->session,
+ idopts, &id_cryptoctx->creds[i]);
if (ret)
return ret;
if (id_cryptoctx->creds[i] == NULL)
@@ -5510,19 +5525,26 @@ print_pubkey(BIGNUM * key, char *msg)
}
#endif
-static const char *
-pkcs11err(int err)
+#ifndef WITHOUT_PKCS11
+static krb5_error_code
+p11err(krb5_context context, CK_RV rv, const char *op)
{
+ krb5_error_code code = KRB5KDC_ERR_PREAUTH_FAILED;
int i;
+ const char *msg;
- for (i = 0; pkcs11_errstrings[i].text != NULL; i++)
- if (pkcs11_errstrings[i].code == err)
+ for (i = 0; pkcs11_errstrings[i].text != NULL; i++) {
+ if (pkcs11_errstrings[i].code == rv)
break;
- if (pkcs11_errstrings[i].text != NULL)
- return (pkcs11_errstrings[i].text);
+ }
+ msg = pkcs11_errstrings[i].text;
+ if (msg == NULL)
+ msg = "unknown PKCS11 error";
- return "unknown PKCS11 error";
+ krb5_set_error_message(context, code, _("PKCS11 error (%s): %s"), op, msg);
+ return code;
}
+#endif
/*
* Add an item to the pkinit_identity_crypto_context's list of deferred
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
index 1c1ceb5a41..1faa6816d7 100644
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
@@ -98,21 +98,12 @@
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \
TRACE(c, "PKINIT OpenSSL error: {str}", msg)
-#define TRACE_PKINIT_PKCS11_GETFLIST_FAILED(c, errstr) \
- TRACE(c, "PKINIT PKCS11 C_GetFunctionList failed: {str}", errstr)
-#define TRACE_PKINIT_PKCS11_GETSYM_FAILED(c, errstr) \
- TRACE(c, "PKINIT unable to find PKCS11 plugin symbol " \
- "C_GetFunctionList: {str}", errstr)
-#define TRACE_PKINIT_PKCS11_LOGIN_FAILED(c, errstr) \
- TRACE(c, "PKINIT PKCS11 C_Login failed: {str}", errstr)
#define TRACE_PKINIT_PKCS11_NO_MATCH_TOKEN(c) \
TRACE(c, "PKINIT PKCS#11 module has no matching tokens")
#define TRACE_PKINIT_PKCS11_NO_TOKEN(c) \
TRACE(c, "PKINIT PKCS#11 module shows no slots with tokens")
#define TRACE_PKINIT_PKCS11_OPEN(c, name) \
TRACE(c, "PKINIT opening PKCS#11 module \"{str}\"", name)
-#define TRACE_PKINIT_PKCS11_OPEN_FAILED(c, errstr) \
- TRACE(c, "PKINIT PKCS#11 module open failed: {str}", errstr)
#define TRACE_PKINIT_PKCS11_SLOT(c, slot, len, label) \
TRACE(c, "PKINIT PKCS#11 slotid {int} token {lenstr}", \
slot, len, label)
--
2.47.1

View file

@ -0,0 +1,61 @@
From 946f7dba8cea3d2ed0e68c5e7594cbd7e1364609 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Thu, 1 Aug 2024 10:56:07 +0200
Subject: [PATCH] Set missing mask flags for kdb5_util operations
Set KADM5_TL_DATA for the use_mkey and update_princ_encryption
commands. (Commit c877f13c8985d820583b0d7ac1bb4c5dc36e677e did this
for the add_new_mkey and purge_mkeys commands.) Set appropriate flags
for the add_random_key command.
[ghudson@mit.edu: combined two commits; pruned out proposed mask flag
additions for values represented within key data or tl-data (like
KADM5_MKVNO), as those flags are currently only used in the kadm5
protocol, not to communicate with the KDB module]
ticket: 9158 (new)
(cherry picked from commit 4ed7da378940198cf4415f86d4eb013de6ac6455)
---
src/kadmin/dbutil/kdb5_mkey.c | 4 +++-
src/kadmin/dbutil/kdb5_util.c | 3 +++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c
index aceb0a9b80..ac5c51d05e 100644
--- a/src/kadmin/dbutil/kdb5_mkey.c
+++ b/src/kadmin/dbutil/kdb5_mkey.c
@@ -525,6 +525,8 @@ kdb5_use_mkey(int argc, char *argv[])
goto cleanup_return;
}
+ master_entry->mask |= KADM5_TL_DATA;
+
if ((retval = krb5_db_put_principal(util_context, master_entry))) {
com_err(progname, retval,
_("while adding master key entry to the database"));
@@ -814,7 +816,7 @@ update_princ_encryption_1(void *cb, krb5_db_entry *ent)
goto fail;
}
- ent->mask |= KADM5_KEY_DATA;
+ ent->mask |= KADM5_KEY_DATA | KADM5_TL_DATA;
if ((retval = krb5_db_put_principal(util_context, ent))) {
com_err(progname, retval, _("while updating principal '%s' key data "
diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c
index 55d529fa4c..afc817891b 100644
--- a/src/kadmin/dbutil/kdb5_util.c
+++ b/src/kadmin/dbutil/kdb5_util.c
@@ -600,6 +600,9 @@ add_random_key(int argc, char **argv)
exit_status++;
return;
}
+
+ dbent->mask |= KADM5_ATTRIBUTES | KADM5_KEY_DATA | KADM5_TL_DATA;
+
ret = krb5_db_put_principal(util_context, dbent);
krb5_db_free_principal(util_context, dbent);
if (ret) {
--
2.47.1

View file

@ -0,0 +1,64 @@
From 9b669dd42b28e7900f5ccac2816204e7d04ea23c Mon Sep 17 00:00:00 2001
From: Zoltan Borbely <Zoltan.Borbely@morganstanley.com>
Date: Tue, 28 Jan 2025 16:39:25 -0500
Subject: [PATCH] Prevent overflow when calculating ulog block size
In kdb_log.c:resize(), log an error and fail if the update size is
larger than the largest possible block size (2^16-1).
CVE-2025-24528:
In MIT krb5 release 1.7 and later with incremental propagation
enabled, an authenticated attacker can cause kadmind to write beyond
the end of the mapped region for the iprop log file, likely causing a
process crash.
[ghudson@mit.edu: edited commit message and added CVE description]
ticket: 9159 (new)
tags: pullup
target_version: 1.21-next
(cherry picked from commit 78ceba024b64d49612375be4a12d1c066b0bfbd0)
---
src/lib/kdb/kdb_log.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
index e9b95fce59..c805ebd988 100644
--- a/src/lib/kdb/kdb_log.c
+++ b/src/lib/kdb/kdb_log.c
@@ -183,7 +183,7 @@ extend_file_to(int fd, unsigned int new_size)
*/
static krb5_error_code
resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
- unsigned int recsize)
+ unsigned int recsize, const kdb_incr_update_t *upd)
{
unsigned int new_block, new_size;
@@ -195,6 +195,12 @@ resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
new_block *= ULOG_BLOCK;
new_size += ulogentries * new_block;
+ if (new_block > UINT16_MAX) {
+ syslog(LOG_ERR, _("ulog overflow caused by principal %.*s"),
+ upd->kdb_princ_name.utf8str_t_len,
+ upd->kdb_princ_name.utf8str_t_val);
+ return KRB5_LOG_ERROR;
+ }
if (new_size > MAXLOGLEN)
return KRB5_LOG_ERROR;
@@ -291,7 +297,7 @@ store_update(kdb_log_context *log_ctx, kdb_incr_update_t *upd)
recsize = sizeof(kdb_ent_header_t) + upd_size;
if (recsize > ulog->kdb_block) {
- retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize);
+ retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize, upd);
if (retval)
return retval;
}
--
2.48.1

View file

@ -0,0 +1,327 @@
From c617915958a5cb05463713adcf03b6a0e0512ac3 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 16 Dec 2022 18:31:07 -0500
Subject: [PATCH] Don't issue session keys with deprecated enctypes
A paper by Tom Tervoort noted that rc4-hmac pre-hashes the input for
its checksum and GSS operations before applying HMAC, and is therefore
potentially vulnerable to hash collision attacks if a protocol
contains a restricted signing oracle.
In light of these potential attacks, begin the functional deprecation
of DES3 and RC4 by disallowing their use as session key enctypes by
default. Add the variables allow_des3 and allow_rc4 in case
negotiability of these enctypes for session keys needs to be turned
back on, with the expectation that in future releases the enctypes
will be more comprehensively deprecated.
ticket: 9081
(cherry picked from commit 1b57a4d134bbd0e7c52d5885a92eccc815726463)
---
doc/admin/conf_files/krb5_conf.rst | 12 ++++++++++++
doc/admin/enctypes.rst | 23 +++++++++++++++++++---
src/include/k5-int.h | 4 ++++
src/kdc/kdc_util.c | 10 ++++++++++
src/lib/krb5/krb/get_in_tkt.c | 31 +++++++++++++++++++-----------
src/lib/krb5/krb/init_ctx.c | 10 ++++++++++
src/tests/gssapi/t_enctypes.py | 5 +++--
src/tests/t_etype_info.py | 5 +++--
src/tests/t_sesskeynego.py | 28 +++++++++++++++++++++++++--
src/util/k5test.py | 9 ++++++++-
10 files changed, 116 insertions(+), 21 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index dca52e1426..d51fd3ce7e 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -95,6 +95,18 @@ Additionally, krb5.conf may include any of the relations described in
The libdefaults section may contain any of the following relations:
+**allow_des3**
+ Permit the KDC to issue tickets with des3-cbc-sha1 session keys.
+ In future releases, this flag will allow des3-cbc-sha1 to be used
+ at all. The default value for this tag is false. (Added in
+ release 1.21.)
+
+**allow_rc4**
+ Permit the KDC to issue tickets with arcfour-hmac session keys.
+ In future releases, this flag will allow arcfour-hmac to be used
+ at all. The default value for this tag is false. (Added in
+ release 1.21.)
+
**allow_weak_crypto**
If this flag is set to false, then weak encryption types (as noted
in :ref:`Encryption_types` in :ref:`kdc.conf(5)`) will be filtered
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
index c4d5499d3b..2b4ed7da0b 100644
--- a/doc/admin/enctypes.rst
+++ b/doc/admin/enctypes.rst
@@ -48,12 +48,15 @@ Session key selection
The KDC chooses the session key enctype by taking the intersection of
its **permitted_enctypes** list, the list of long-term keys for the
most recent kvno of the service, and the client's requested list of
-enctypes.
+enctypes. Starting in krb5-1.21, all services are assumed to support
+aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session
+keys will not be issued by default.
Starting in krb5-1.11, it is possible to set a string attribute on a
service principal to control what session key enctypes the KDC may
-issue for service tickets for that principal. See :ref:`set_string`
-in :ref:`kadmin(1)` for details.
+issue for service tickets for that principal, overriding the service's
+long-term keys and the assumption of aes256-cts-hmac-sha1-96 support.
+See :ref:`set_string` in :ref:`kadmin(1)` for details.
Choosing enctypes for a service
@@ -87,6 +90,20 @@ affect how enctypes are chosen.
acceptable risk for your environment and the weak enctypes are
required for backward compatibility.
+**allow_des3**
+ was added in release 1.21 and defaults to *false*. Unless this
+ flag is set to *true*, the KDC will not issue tickets with
+ des3-cbc-sha1 session keys. In a future release, this flag will
+ control whether des3-cbc-sha1 is permitted in similar fashion to
+ weak enctypes.
+
+**allow_rc4**
+ was added in release 1.21 and defaults to *false*. Unless this
+ flag is set to *true*, the KDC will not issue tickets with
+ arcfour-hmac session keys. In a future release, this flag will
+ control whether arcfour-hmac is permitted in similar fashion to
+ weak enctypes.
+
**permitted_enctypes**
controls the set of enctypes that a service will permit for
session keys and for ticket and authenticator encryption. The KDC
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index b7789a2dd8..d0a263aa7d 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -181,6 +181,8 @@ typedef unsigned char u_char;
* matches the variable name. Keep these alphabetized. */
#define KRB5_CONF_ACL_FILE "acl_file"
#define KRB5_CONF_ADMIN_SERVER "admin_server"
+#define KRB5_CONF_ALLOW_DES3 "allow_des3"
+#define KRB5_CONF_ALLOW_RC4 "allow_rc4"
#define KRB5_CONF_ALLOW_WEAK_CRYPTO "allow_weak_crypto"
#define KRB5_CONF_AUTH_TO_LOCAL "auth_to_local"
#define KRB5_CONF_AUTH_TO_LOCAL_NAMES "auth_to_local_names"
@@ -1241,6 +1243,8 @@ struct _krb5_context {
struct _kdb_log_context *kdblog_context;
krb5_boolean allow_weak_crypto;
+ krb5_boolean allow_des3;
+ krb5_boolean allow_rc4;
krb5_boolean ignore_acceptor_hostname;
krb5_boolean enforce_ok_as_delegate;
enum dns_canonhost dns_canonicalize_hostname;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 93415ba862..c7b6e4090d 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1108,6 +1108,16 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
if (!krb5_is_permitted_enctype(context, ktype[i]))
continue;
+ /*
+ * Prevent these deprecated enctypes from being used as session keys
+ * unless they are explicitly allowed. In the future they will be more
+ * comprehensively disabled and eventually removed.
+ */
+ if (ktype[i] == ENCTYPE_DES3_CBC_SHA1 && !context->allow_des3)
+ continue;
+ if (ktype[i] == ENCTYPE_ARCFOUR_HMAC && !context->allow_rc4)
+ continue;
+
if (dbentry_supports_enctype(context, server, ktype[i]))
return ktype[i];
}
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 1b420a3ac2..ea089f0fcc 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1582,22 +1582,31 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
(*prompter)(context, data, 0, banner, 0, 0);
}
-/* Display a warning via the prompter if des3-cbc-sha1 was used for either the
- * reply key or the session key. */
+/* Display a warning via the prompter if a deprecated enctype was used for
+ * either the reply key or the session key. */
static void
-warn_des3(krb5_context context, krb5_init_creds_context ctx,
- krb5_enctype as_key_enctype)
+warn_deprecated(krb5_context context, krb5_init_creds_context ctx,
+ krb5_enctype as_key_enctype)
{
- const char *banner;
+ krb5_enctype etype;
+ char encbuf[128], banner[256];
- if (as_key_enctype != ENCTYPE_DES3_CBC_SHA1 &&
- ctx->cred.keyblock.enctype != ENCTYPE_DES3_CBC_SHA1)
- return;
if (ctx->prompter == NULL)
return;
- banner = _("Warning: encryption type des3-cbc-sha1 used for "
- "authentication is weak and will be disabled");
+ if (krb5int_c_deprecated_enctype(as_key_enctype))
+ etype = as_key_enctype;
+ else if (krb5int_c_deprecated_enctype(ctx->cred.keyblock.enctype))
+ etype = ctx->cred.keyblock.enctype;
+ else
+ return;
+
+ if (krb5_enctype_to_name(etype, FALSE, encbuf, sizeof(encbuf)) != 0)
+ return;
+ snprintf(banner, sizeof(banner),
+ _("Warning: encryption type %s used for authentication is "
+ "deprecated and will be disabled"), encbuf);
+
/* PROMPTER_INVOCATION */
(*ctx->prompter)(context, ctx->prompter_data, NULL, banner, 0, NULL);
}
@@ -1848,7 +1857,7 @@ init_creds_step_reply(krb5_context context,
ctx->complete = TRUE;
warn_pw_expiry(context, ctx->opt, ctx->prompter, ctx->prompter_data,
ctx->in_tkt_service, ctx->reply);
- warn_des3(context, ctx, encrypting_key.enctype);
+ warn_deprecated(context, ctx, encrypting_key.enctype);
cleanup:
krb5_free_pa_data(context, kdc_padata);
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 582a2945ff..a32f8dbf03 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -220,6 +220,16 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
goto cleanup;
ctx->allow_weak_crypto = tmp;
+ retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp);
+ if (retval)
+ goto cleanup;
+ ctx->allow_des3 = tmp;
+
+ retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp);
+ if (retval)
+ goto cleanup;
+ ctx->allow_rc4 = tmp;
+
retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp);
if (retval)
goto cleanup;
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index 2f95d89967..e6bde47afc 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -10,8 +10,9 @@ d_rc4 = 'DEPRECATED:arcfour-hmac'
# These tests make assumptions about the default enctype lists, so set
# them explicitly rather than relying on the library defaults.
-supp='aes256-cts:normal aes128-cts:normal rc4-hmac:normal'
-conf = {'libdefaults': {'permitted_enctypes': 'aes rc4'},
+supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
+conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4',
+ 'allow_des3': 'true', 'allow_rc4': 'true'},
'realms': {'$realm': {'supported_enctypes': supp}}}
realm = K5Realm(krb5_conf=conf)
shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
index a6f538b66d..75d9621dd6 100644
--- a/src/tests/t_etype_info.py
+++ b/src/tests/t_etype_info.py
@@ -1,7 +1,8 @@
from k5test import *
-supported_enctypes = 'aes128-cts rc4-hmac'
-conf = {'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
+supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac'
+conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'},
+ 'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
realm.run([kadminl, 'addprinc', '-pw', 'pw', '+requires_preauth',
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
index 9024aee838..5a213617b5 100755
--- a/src/tests/t_sesskeynego.py
+++ b/src/tests/t_sesskeynego.py
@@ -25,6 +25,8 @@ conf3 = {'libdefaults': {
'default_tkt_enctypes': 'aes128-cts',
'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
+conf5 = {'libdefaults': {'allow_rc4': 'true'}}
+conf6 = {'libdefaults': {'allow_des3': 'true'}}
# Test with client request and session_enctypes preferring aes128, but
# aes256 long-term key.
realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
@@ -54,10 +56,12 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
'aes128-cts,aes256-cts'])
test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
-# 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term.
+# 3b: Skip RC4 (as the KDC does not allow it for session keys by
+# default) and negotiate aes128-cts session key, with only an aes256
+# long-term service key.
realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
'rc4-hmac,aes128-cts,aes256-cts'])
-test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
+test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
realm.stop()
# 4: Check that permitted_enctypes is a default for session key enctypes.
@@ -67,4 +71,24 @@ realm.run([kvno, 'user'],
expected_trace=('etypes requested in TGS request: aes256-cts',))
realm.stop()
+# 5: allow_rc4 permits negotiation of rc4-hmac session key.
+realm = K5Realm(krb5_conf=conf5, create_host=False, get_creds=False)
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
+realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac'])
+test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
+realm.stop()
+
+# 6: allow_des3 permits negotiation of des3-cbc-sha1 session key.
+realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False)
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
+realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1'])
+test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96')
+realm.stop()
+
+# 7: default config negotiates aes256-sha1 session key for RC4-only service.
+realm = K5Realm(create_host=False, get_creds=False)
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server'])
+test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'DEPRECATED:arcfour-hmac')
+realm.stop()
+
success('sesskeynego')
diff --git a/src/util/k5test.py b/src/util/k5test.py
index d823653aa0..8e5f5ba8e9 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -1338,9 +1338,16 @@ _passes = [
# No special settings; exercises AES256.
('default', None, None, None),
+ # Exercise the DES3 enctype.
+ ('des3', None,
+ {'libdefaults': {'permitted_enctypes': 'des3 aes256-sha1'}},
+ {'realms': {'$realm': {
+ 'supported_enctypes': 'des3-cbc-sha1:normal',
+ 'master_key_type': 'des3-cbc-sha1'}}}),
+
# Exercise the arcfour enctype.
('arcfour', None,
- {'libdefaults': {'permitted_enctypes': 'rc4'}},
+ {'libdefaults': {'permitted_enctypes': 'rc4 aes256-sha1'}},
{'realms': {'$realm': {
'supported_enctypes': 'arcfour-hmac:normal',
'master_key_type': 'arcfour-hmac'}}}),
--
2.49.0

View file

@ -0,0 +1,260 @@
From b0993b57dbe584f9308cc7773b930efe76e19ba3 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Fri, 4 Apr 2025 15:08:36 +0200
Subject: [PATCH] [downstream] Remove 3des support (cumulative 1)
Remove mentions for the triple-DES encryption type which were added
since the previous downstream patch.
---
README | 15 +++++++--------
doc/admin/conf_files/krb5_conf.rst | 6 ------
doc/admin/enctypes.rst | 11 ++---------
doc/mitK5features.rst | 5 ++---
src/include/k5-int.h | 2 --
src/kdc/kdc_util.c | 2 --
src/lib/krb5/krb/init_ctx.c | 5 -----
src/man/krb5.conf.man | 6 ------
src/tests/gssapi/t_enctypes.py | 5 ++---
src/tests/t_etype_info.py | 4 ++--
src/tests/t_sesskeynego.py | 8 --------
src/util/k5test.py | 7 -------
12 files changed, 15 insertions(+), 61 deletions(-)
diff --git a/README b/README
index 6d6f7f16e3..9341bd3dd8 100644
--- a/README
+++ b/README
@@ -81,11 +81,11 @@ Triple-DES and RC4 transitions
------------------------------
Beginning with the krb5-1.21 release, the KDC will not issue tickets
-with triple-DES or RC4 session keys unless explicitly configured using
-the new allow_des3 and allow_rc4 variables in [libdefaults]. To
-facilitate the negotiation of session keys, the KDC will assume that
-all services can handle aes256-sha1 session keys unless the service
-principal has a session_enctypes string attribute.
+with RC4 session keys unless explicitly configured using the new
+allow_rc4 variable in [libdefaults]. To facilitate the negotiation of
+session keys, the KDC will assume that all services can handle
+aes256-sha1 session keys unless the service principal has a
+session_enctypes string attribute.
Beginning with the krb5-1.19 release, a warning will be issued if
initial credentials are acquired using the des3-cbc-sha1 encryption
@@ -164,9 +164,8 @@ Developer experience:
Protocol evolution:
-* The KDC will no longer issue tickets with RC4 or triple-DES session
- keys unless explicitly configured with the new allow_rc4 or
- allow_des3 variables respectively.
+* The KDC will no longer issue tickets with RC4 session keys unless
+ explicitly configured with the new allow_rc4 variable.
* The KDC will assume that all services can handle aes256-sha1 session
keys unless the service principal has a session_enctypes string
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index d51fd3ce7e..d20dcf18e3 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -95,12 +95,6 @@ Additionally, krb5.conf may include any of the relations described in
The libdefaults section may contain any of the following relations:
-**allow_des3**
- Permit the KDC to issue tickets with des3-cbc-sha1 session keys.
- In future releases, this flag will allow des3-cbc-sha1 to be used
- at all. The default value for this tag is false. (Added in
- release 1.21.)
-
**allow_rc4**
Permit the KDC to issue tickets with arcfour-hmac session keys.
In future releases, this flag will allow arcfour-hmac to be used
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
index 2b4ed7da0b..6ce4638d5e 100644
--- a/doc/admin/enctypes.rst
+++ b/doc/admin/enctypes.rst
@@ -49,8 +49,8 @@ The KDC chooses the session key enctype by taking the intersection of
its **permitted_enctypes** list, the list of long-term keys for the
most recent kvno of the service, and the client's requested list of
enctypes. Starting in krb5-1.21, all services are assumed to support
-aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session
-keys will not be issued by default.
+aes256-cts-hmac-sha1-96; also, arcfour-hmac session keys will not be
+issued by default.
Starting in krb5-1.11, it is possible to set a string attribute on a
service principal to control what session key enctypes the KDC may
@@ -90,13 +90,6 @@ affect how enctypes are chosen.
acceptable risk for your environment and the weak enctypes are
required for backward compatibility.
-**allow_des3**
- was added in release 1.21 and defaults to *false*. Unless this
- flag is set to *true*, the KDC will not issue tickets with
- des3-cbc-sha1 session keys. In a future release, this flag will
- control whether des3-cbc-sha1 is permitted in similar fashion to
- weak enctypes.
-
**allow_rc4**
was added in release 1.21 and defaults to *false*. Unless this
flag is set to *true*, the KDC will not issue tickets with
diff --git a/doc/mitK5features.rst b/doc/mitK5features.rst
index cad0855724..64d746b0af 100644
--- a/doc/mitK5features.rst
+++ b/doc/mitK5features.rst
@@ -659,9 +659,8 @@ Release 1.21
* Protocol evolution:
- - The KDC will no longer issue tickets with RC4 or triple-DES
- session keys unless explicitly configured with the new allow_rc4
- or allow_des3 variables respectively.
+ - The KDC will no longer issue tickets with RC4 session keys unless
+ explicitly configured with the new allow_rc4 variable.
- The KDC will assume that all services can handle aes256-sha1
session keys unless the service principal has a session_enctypes
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index d0a263aa7d..82a763298d 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -181,7 +181,6 @@ typedef unsigned char u_char;
* matches the variable name. Keep these alphabetized. */
#define KRB5_CONF_ACL_FILE "acl_file"
#define KRB5_CONF_ADMIN_SERVER "admin_server"
-#define KRB5_CONF_ALLOW_DES3 "allow_des3"
#define KRB5_CONF_ALLOW_RC4 "allow_rc4"
#define KRB5_CONF_ALLOW_WEAK_CRYPTO "allow_weak_crypto"
#define KRB5_CONF_AUTH_TO_LOCAL "auth_to_local"
@@ -1243,7 +1242,6 @@ struct _krb5_context {
struct _kdb_log_context *kdblog_context;
krb5_boolean allow_weak_crypto;
- krb5_boolean allow_des3;
krb5_boolean allow_rc4;
krb5_boolean ignore_acceptor_hostname;
krb5_boolean enforce_ok_as_delegate;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index c7b6e4090d..bafcf5f728 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1113,8 +1113,6 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
* unless they are explicitly allowed. In the future they will be more
* comprehensively disabled and eventually removed.
*/
- if (ktype[i] == ENCTYPE_DES3_CBC_SHA1 && !context->allow_des3)
- continue;
if (ktype[i] == ENCTYPE_ARCFOUR_HMAC && !context->allow_rc4)
continue;
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index a32f8dbf03..82aba64c5e 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -220,11 +220,6 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
goto cleanup;
ctx->allow_weak_crypto = tmp;
- retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp);
- if (retval)
- goto cleanup;
- ctx->allow_des3 = tmp;
-
retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp);
if (retval)
goto cleanup;
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man
index 6c0e9aff8c..4b53988712 100644
--- a/src/man/krb5.conf.man
+++ b/src/man/krb5.conf.man
@@ -178,12 +178,6 @@ kdc.conf(5), but it is not a recommended practice.
The libdefaults section may contain any of the following relations:
.INDENT 0.0
.TP
-\fBallow_des3\fP
-Permit the KDC to issue tickets with des3\-cbc\-sha1 session keys.
-In future releases, this flag will allow des3\-cbc\-sha1 to be used
-at all. The default value for this tag is false. (Added in
-release 1.21.)
-.TP
\fBallow_rc4\fP
Permit the KDC to issue tickets with arcfour\-hmac session keys.
In future releases, this flag will allow arcfour\-hmac to be used
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index e6bde47afc..1bb8c40b6b 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -10,9 +10,8 @@ d_rc4 = 'DEPRECATED:arcfour-hmac'
# These tests make assumptions about the default enctype lists, so set
# them explicitly rather than relying on the library defaults.
-supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
-conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4',
- 'allow_des3': 'true', 'allow_rc4': 'true'},
+supp='aes256-cts:normal aes128-cts:normal rc4-hmac:normal'
+conf = {'libdefaults': {'permitted_enctypes': 'aes rc4', 'allow_rc4': 'true'},
'realms': {'$realm': {'supported_enctypes': supp}}}
realm = K5Realm(krb5_conf=conf)
shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
index 75d9621dd6..e82ff7ff07 100644
--- a/src/tests/t_etype_info.py
+++ b/src/tests/t_etype_info.py
@@ -1,7 +1,7 @@
from k5test import *
-supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac'
-conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'},
+supported_enctypes = 'aes128-cts rc4-hmac'
+conf = {'libdefaults': {'allow_rc4': 'true'},
'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
index 5a213617b5..c7dba0ff5b 100755
--- a/src/tests/t_sesskeynego.py
+++ b/src/tests/t_sesskeynego.py
@@ -26,7 +26,6 @@ conf3 = {'libdefaults': {
'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
conf5 = {'libdefaults': {'allow_rc4': 'true'}}
-conf6 = {'libdefaults': {'allow_des3': 'true'}}
# Test with client request and session_enctypes preferring aes128, but
# aes256 long-term key.
realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
@@ -78,13 +77,6 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac'])
test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
realm.stop()
-# 6: allow_des3 permits negotiation of des3-cbc-sha1 session key.
-realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False)
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
-realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1'])
-test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96')
-realm.stop()
-
# 7: default config negotiates aes256-sha1 session key for RC4-only service.
realm = K5Realm(create_host=False, get_creds=False)
realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server'])
diff --git a/src/util/k5test.py b/src/util/k5test.py
index 8e5f5ba8e9..b953827018 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -1338,13 +1338,6 @@ _passes = [
# No special settings; exercises AES256.
('default', None, None, None),
- # Exercise the DES3 enctype.
- ('des3', None,
- {'libdefaults': {'permitted_enctypes': 'des3 aes256-sha1'}},
- {'realms': {'$realm': {
- 'supported_enctypes': 'des3-cbc-sha1:normal',
- 'master_key_type': 'des3-cbc-sha1'}}}),
-
# Exercise the arcfour enctype.
('arcfour', None,
{'libdefaults': {'permitted_enctypes': 'rc4 aes256-sha1'}},
--
2.49.0

View file

@ -0,0 +1,692 @@
From 9d03713af124c2096d071ba36893018da8d71655 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Tue, 14 Jan 2025 13:31:11 +0100
Subject: [PATCH] Add PKINIT paChecksum2 from MS-PKCA v20230920
In 2023, Microsoft updated MS-PKCA to add the optional paChecksum2
element in the PKAuthenticator sequence. This checksum accepts SHA-1,
SHA-256, SHA-384, and SHA-512 digests.
In Windows Server 2025, this checksum becomes mandatory when using
PKINIT with FFDH (but strangely not with ECDH if SHA-1 is configured as
allowed).
[ghudson@mit.edu: refactored crypto interfaces to reduce complexity of
calling code]
ticket: 9166 (new)
(cherry picked from commit 310793ba63782af5ffa3a95d20e41f8f03ca7e00)
---
src/include/k5-int-pkinit.h | 25 ++--
src/lib/krb5/asn.1/asn1_k_encode.c | 18 ++-
src/plugins/preauth/pkinit/pkinit.h | 1 +
src/plugins/preauth/pkinit/pkinit_clnt.c | 41 +++----
src/plugins/preauth/pkinit/pkinit_constants.c | 42 +++++--
src/plugins/preauth/pkinit/pkinit_crypto.h | 24 +++-
.../preauth/pkinit/pkinit_crypto_openssl.c | 116 +++++++++++++++++-
src/plugins/preauth/pkinit/pkinit_kdf_test.c | 4 +-
src/plugins/preauth/pkinit/pkinit_lib.c | 16 ++-
src/plugins/preauth/pkinit/pkinit_srv.c | 38 ++----
src/plugins/preauth/pkinit/pkinit_trace.h | 5 +-
src/tests/asn.1/krb5_decode_test.c | 2 +-
src/tests/asn.1/ktest.c | 7 +-
src/tests/asn.1/ktest_equal.c | 2 +-
src/tests/asn.1/pkinit_encode.out | 2 +-
src/tests/asn.1/pkinit_trval.out | 2 +-
16 files changed, 250 insertions(+), 95 deletions(-)
diff --git a/src/include/k5-int-pkinit.h b/src/include/k5-int-pkinit.h
index 915904e518..cf6b1f99c5 100644
--- a/src/include/k5-int-pkinit.h
+++ b/src/include/k5-int-pkinit.h
@@ -36,21 +36,28 @@
* pkinit structures
*/
-/* PKAuthenticator */
-typedef struct _krb5_pk_authenticator {
- krb5_int32 cusec; /* (0..999999) */
- krb5_timestamp ctime;
- krb5_int32 nonce; /* (0..4294967295) */
- krb5_checksum paChecksum;
- krb5_data *freshnessToken;
-} krb5_pk_authenticator;
-
/* AlgorithmIdentifier */
typedef struct _krb5_algorithm_identifier {
krb5_data algorithm; /* OID */
krb5_data parameters; /* Optional */
} krb5_algorithm_identifier;
+/* PAChecksum2 */
+typedef struct _krb5_pachecksum2 {
+ krb5_data checksum;
+ krb5_algorithm_identifier algorithmIdentifier;
+} krb5_pachecksum2;
+
+/* PKAuthenticator */
+typedef struct _krb5_pk_authenticator {
+ krb5_int32 cusec; /* (0..999999) */
+ krb5_timestamp ctime;
+ krb5_int32 nonce; /* (0..4294967295) */
+ krb5_data paChecksum;
+ krb5_data *freshnessToken; /* Optional */
+ krb5_pachecksum2 *paChecksum2; /* Optional */
+} krb5_pk_authenticator;
+
/** AuthPack from RFC 4556*/
typedef struct _krb5_auth_pack {
krb5_pk_authenticator pkAuthenticator;
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 5378b5c23b..cf7b500837 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -1394,20 +1394,30 @@ DEFSEQTYPE(pkinit_supp_pub_info, krb5_pkinit_supp_pub_info,
MAKE_ENCODER(encode_krb5_pkinit_supp_pub_info, pkinit_supp_pub_info);
MAKE_ENCODER(encode_krb5_sp80056a_other_info, sp80056a_other_info);
-/* A krb5_checksum encoded as an OCTET STRING, for PKAuthenticator. */
-DEFCOUNTEDTYPE(ostring_checksum, krb5_checksum, contents, length, octetstring);
+DEFFIELD(pachecksum2_0, krb5_pachecksum2, checksum, 0, ostring_data);
+DEFFIELD(pachecksum2_1, krb5_pachecksum2, algorithmIdentifier, 1,
+ algorithm_identifier);
+static const struct atype_info *pachecksum2_fields[] = {
+ &k5_atype_pachecksum2_0, &k5_atype_pachecksum2_1
+};
+DEFSEQTYPE(pachecksum2, krb5_pachecksum2, pachecksum2_fields);
+
+DEFPTRTYPE(pachecksum2_ptr, pachecksum2);
+DEFOPTIONALZEROTYPE(opt_pachecksum2_ptr, pachecksum2_ptr);
DEFFIELD(pk_authenticator_0, krb5_pk_authenticator, cusec, 0, int32);
DEFFIELD(pk_authenticator_1, krb5_pk_authenticator, ctime, 1, kerberos_time);
DEFFIELD(pk_authenticator_2, krb5_pk_authenticator, nonce, 2, int32);
DEFFIELD(pk_authenticator_3, krb5_pk_authenticator, paChecksum, 3,
- ostring_checksum);
+ ostring_data);
DEFFIELD(pk_authenticator_4, krb5_pk_authenticator, freshnessToken, 4,
opt_ostring_data_ptr);
+DEFFIELD(pk_authenticator_5, krb5_pk_authenticator, paChecksum2, 5,
+ opt_pachecksum2_ptr);
static const struct atype_info *pk_authenticator_fields[] = {
&k5_atype_pk_authenticator_0, &k5_atype_pk_authenticator_1,
&k5_atype_pk_authenticator_2, &k5_atype_pk_authenticator_3,
- &k5_atype_pk_authenticator_4
+ &k5_atype_pk_authenticator_4, &k5_atype_pk_authenticator_5
};
DEFSEQTYPE(pk_authenticator, krb5_pk_authenticator, pk_authenticator_fields);
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
index 7ba7155bb4..a1564b6df2 100644
--- a/src/plugins/preauth/pkinit/pkinit.h
+++ b/src/plugins/preauth/pkinit/pkinit.h
@@ -338,6 +338,7 @@ void free_krb5_external_principal_identifier(krb5_external_principal_identifier
void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in);
void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in);
void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in);
+void free_pachecksum2(krb5_context context, krb5_pachecksum2 **in);
krb5_error_code pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src);
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index b08022a214..433f477538 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -56,10 +56,9 @@ use_content_info(krb5_context context, pkinit_req_context req,
static krb5_error_code
pkinit_as_req_create(krb5_context context, pkinit_context plgctx,
pkinit_req_context reqctx, krb5_timestamp ctsec,
- krb5_int32 cusec, krb5_ui_4 nonce,
- const krb5_checksum *cksum,
- krb5_principal client, krb5_principal server,
- krb5_data **as_req);
+ krb5_int32 cusec, krb5_ui_4 nonce, const krb5_data *cksum,
+ const krb5_pachecksum2 *cksum2, krb5_principal client,
+ krb5_principal server, krb5_data **as_req);
static krb5_error_code
pkinit_as_rep_parse(krb5_context context, pkinit_context plgctx,
@@ -89,7 +88,8 @@ pa_pkinit_gen_req(krb5_context context,
krb5_timestamp ctsec = 0;
krb5_int32 cusec = 0;
krb5_ui_4 nonce = 0;
- krb5_checksum cksum;
+ krb5_data cksum = empty_data();
+ krb5_pachecksum2 *cksum2 = NULL;
krb5_data *der_req = NULL;
krb5_pa_data **return_pa_data = NULL;
@@ -118,15 +118,10 @@ pa_pkinit_gen_req(krb5_context context,
goto cleanup;
}
- retval = krb5_c_make_checksum(context, CKSUMTYPE_SHA1, NULL, 0, der_req,
- &cksum);
+ retval = crypto_generate_checksums(context, der_req, &cksum, &cksum2);
if (retval)
goto cleanup;
- TRACE_PKINIT_CLIENT_REQ_CHECKSUM(context, &cksum);
-#ifdef DEBUG_CKSUM
- pkiDebug("calculating checksum on buf size (%d)\n", der_req->length);
- print_buffer(der_req->data, der_req->length);
-#endif
+ TRACE_PKINIT_CLIENT_REQ_CHECKSUMS(context, &cksum, cksum2);
retval = cb->get_preauth_time(context, rock, TRUE, &ctsec, &cusec);
if (retval)
@@ -140,7 +135,8 @@ pa_pkinit_gen_req(krb5_context context,
nonce = request->nonce;
retval = pkinit_as_req_create(context, plgctx, reqctx, ctsec, cusec,
- nonce, &cksum, request->client, request->server, &out_data);
+ nonce, &cksum, cksum2, request->client,
+ request->server, &out_data);
if (retval) {
pkiDebug("error %d on pkinit_as_req_create; aborting PKINIT\n",
(int) retval);
@@ -168,23 +164,19 @@ pa_pkinit_gen_req(krb5_context context,
cleanup:
krb5_free_data(context, der_req);
- krb5_free_checksum_contents(context, &cksum);
+ krb5_free_data_contents(context, &cksum);
+ free_pachecksum2(context, &cksum2);
krb5_free_data(context, out_data);
krb5_free_pa_data(context, return_pa_data);
return retval;
}
static krb5_error_code
-pkinit_as_req_create(krb5_context context,
- pkinit_context plgctx,
- pkinit_req_context reqctx,
- krb5_timestamp ctsec,
- krb5_int32 cusec,
- krb5_ui_4 nonce,
- const krb5_checksum * cksum,
- krb5_principal client,
- krb5_principal server,
- krb5_data ** as_req)
+pkinit_as_req_create(krb5_context context, pkinit_context plgctx,
+ pkinit_req_context reqctx, krb5_timestamp ctsec,
+ krb5_int32 cusec, krb5_ui_4 nonce, const krb5_data *cksum,
+ const krb5_pachecksum2 *cksum2, krb5_principal client,
+ krb5_principal server, krb5_data **as_req)
{
krb5_error_code retval = ENOMEM;
krb5_data spki = empty_data(), *coded_auth_pack = NULL;
@@ -202,6 +194,7 @@ pkinit_as_req_create(krb5_context context,
auth_pack.pkAuthenticator.paChecksum = *cksum;
if (!reqctx->opts->disable_freshness)
auth_pack.pkAuthenticator.freshnessToken = reqctx->freshness_token;
+ auth_pack.pkAuthenticator.paChecksum2 = (krb5_pachecksum2 *)cksum2;
auth_pack.clientDHNonce.length = 0;
auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids;
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
index 905e90d29c..a32b373c32 100644
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
@@ -34,25 +34,49 @@
/* RFC 8636 id-pkinit-kdf-ah-sha1: iso(1) identified-organization(3) dod(6)
* internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha1(1) */
-static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
+static char kdf_sha1[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
/* RFC 8636 id-pkinit-kdf-ah-sha256: iso(1) identified-organization(3) dod(6)
* internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha256(2) */
-static char sha256_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
+static char kdf_sha256[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
/* RFC 8636 id-pkinit-kdf-ah-sha512: iso(1) identified-organization(3) dod(6)
* internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha512(3) */
-static char sha512_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
+static char kdf_sha512[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
-const krb5_data sha1_id = { KV5M_DATA, sizeof(sha1_oid), sha1_oid };
-const krb5_data sha256_id = { KV5M_DATA, sizeof(sha256_oid), sha256_oid };
-const krb5_data sha512_id = { KV5M_DATA, sizeof(sha512_oid), sha512_oid };
+const krb5_data kdf_sha1_id = { KV5M_DATA, sizeof(kdf_sha1), kdf_sha1 };
+const krb5_data kdf_sha256_id = { KV5M_DATA, sizeof(kdf_sha256), kdf_sha256 };
+const krb5_data kdf_sha512_id = { KV5M_DATA, sizeof(kdf_sha512), kdf_sha512 };
krb5_data const * const supported_kdf_alg_ids[] = {
- &sha256_id,
- &sha1_id,
- &sha512_id,
+ &kdf_sha256_id,
+ &kdf_sha1_id,
+ &kdf_sha512_id,
NULL
};
+/* RFC 3370 sha-1: iso(1) identified-organization(3) oiw(14) secsig(3)
+ * algorithm(2) 26 */
+static char cms_sha1[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a };
+/* RFC 5754 id-sha256: joint-iso-itu-t(2) country(16) us(840) organization(1)
+ * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 */
+static char cms_sha256[] = {
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
+};
+/* RFC 5754 id-sha384: joint-iso-itu-t(2) country(16) us(840) organization(1)
+ * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 */
+static char cms_sha384[] = {
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
+};
+/* RFC 5754 id-sha512: joint-iso-itu-t(2) country(16) us(840) organization(1)
+ * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 */
+static char cms_sha512[] = {
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
+};
+
+const krb5_data cms_sha1_id = { KV5M_DATA, sizeof(cms_sha1), cms_sha1 };
+const krb5_data cms_sha256_id = { KV5M_DATA, sizeof(cms_sha256), cms_sha256 };
+const krb5_data cms_sha384_id = { KV5M_DATA, sizeof(cms_sha384), cms_sha384 };
+const krb5_data cms_sha512_id = { KV5M_DATA, sizeof(cms_sha512), cms_sha512 };
+
/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
* rsadsi(113549) pkcs(1) 1 11 */
static char sha256WithRSAEncr_oid[9] = {
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
index fd876e4850..3b12e904b1 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
@@ -562,9 +562,13 @@ pkinit_alg_agility_kdf(krb5_context context,
krb5_data *pk_as_rep,
krb5_keyblock *key_block);
-extern const krb5_data sha1_id;
-extern const krb5_data sha256_id;
-extern const krb5_data sha512_id;
+extern const krb5_data kdf_sha1_id;
+extern const krb5_data kdf_sha256_id;
+extern const krb5_data kdf_sha512_id;
+extern const krb5_data cms_sha1_id;
+extern const krb5_data cms_sha256_id;
+extern const krb5_data cms_sha384_id;
+extern const krb5_data cms_sha512_id;
extern const krb5_data oakley_1024;
extern const krb5_data oakley_2048;
extern const krb5_data oakley_4096;
@@ -597,4 +601,18 @@ crypto_req_cert_matching_data(krb5_context context,
int parse_dh_min_bits(krb5_context context, const char *str);
+/* Generate a SHA-1 checksum over body in *cksum1_out and a SHA-256 checksum
+ * over body in *cksum2_out with appropriate metadata. */
+krb5_error_code
+crypto_generate_checksums(krb5_context context, const krb5_data *body,
+ krb5_data *cksum1_out,
+ krb5_pachecksum2 **cksum2_out);
+
+/* Verify the SHA-1 checksum in cksum1 and the tagged checksum in cksum2.
+ * cksum2 may be NULL, in which case only cksum1 is verified. */
+krb5_error_code
+crypto_verify_checksums(krb5_context context, krb5_data *body,
+ const krb5_data *cksum1,
+ const krb5_pachecksum2 *cksum2);
+
#endif /* _PKINIT_CRYPTO_H */
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 402bf1b9b3..429b7d202c 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -2616,11 +2616,11 @@ cleanup:
static const EVP_MD *
algid_to_md(const krb5_data *alg_id)
{
- if (data_eq(*alg_id, sha1_id))
+ if (data_eq(*alg_id, kdf_sha1_id))
return EVP_sha1();
- if (data_eq(*alg_id, sha256_id))
+ if (data_eq(*alg_id, kdf_sha256_id))
return EVP_sha256();
- if (data_eq(*alg_id, sha512_id))
+ if (data_eq(*alg_id, kdf_sha512_id))
return EVP_sha512();
return NULL;
}
@@ -5663,3 +5663,113 @@ parse_dh_min_bits(krb5_context context, const char *str)
TRACE_PKINIT_DH_INVALID_MIN_BITS(context, str);
return PKINIT_DEFAULT_DH_MIN_BITS;
}
+
+/* Return the OpenSSL message digest type matching the given CMS OID, or NULL
+ * if it doesn't match any of the CMS OIDs we know about. */
+static const EVP_MD *
+md_from_cms_oid(const krb5_data *alg_id)
+{
+ if (data_eq(*alg_id, cms_sha1_id))
+ return EVP_sha1();
+ if (data_eq(*alg_id, cms_sha256_id))
+ return EVP_sha256();
+ if (data_eq(*alg_id, cms_sha384_id))
+ return EVP_sha384();
+ if (data_eq(*alg_id, cms_sha512_id))
+ return EVP_sha512();
+ return NULL;
+}
+
+/* Compute a message digest of the given type over body, placing the result in
+ * *digest_out in allocated storage. Return true on success. */
+static krb5_boolean
+make_digest(const krb5_data *body, const EVP_MD *md, krb5_data *digest_out)
+{
+ krb5_error_code ret;
+ krb5_data d;
+
+ if (md == NULL)
+ return FALSE;
+ ret = alloc_data(&d, EVP_MD_size(md));
+ if (ret)
+ return FALSE;
+ if (!EVP_Digest(body->data, body->length, (uint8_t *)d.data, &d.length, md,
+ NULL)) {
+ free(d.data);
+ return FALSE;
+ }
+ *digest_out = d;
+ return TRUE;
+}
+
+/* Return true if digest verifies for the given body and message digest
+ * type. */
+static krb5_boolean
+check_digest(const krb5_data *body, const EVP_MD *md, const krb5_data *digest)
+{
+ unsigned int digest_len;
+ uint8_t buf[EVP_MAX_MD_SIZE];
+
+ if (md == NULL)
+ return FALSE;
+ if (!EVP_Digest(body->data, body->length, buf, &digest_len, md, NULL))
+ return FALSE;
+ return (digest->length == digest_len &&
+ CRYPTO_memcmp(digest->data, buf, digest_len) == 0);
+}
+
+krb5_error_code
+crypto_generate_checksums(krb5_context context, const krb5_data *body,
+ krb5_data *cksum1_out, krb5_pachecksum2 **cksum2_out)
+{
+ krb5_data cksum1 = empty_data();
+ krb5_pachecksum2 *cksum2 = NULL;
+ krb5_error_code ret;
+
+ if (!make_digest(body, EVP_sha1(), &cksum1))
+ goto fail;
+
+ cksum2 = k5alloc(sizeof(*cksum2), &ret);
+ if (cksum2 == NULL)
+ goto fail;
+
+ if (!make_digest(body, EVP_sha256(), &cksum2->checksum))
+ goto fail;
+
+ if (krb5int_copy_data_contents(context, &cms_sha256_id,
+ &cksum2->algorithmIdentifier.algorithm))
+ goto fail;
+
+ cksum2->algorithmIdentifier.parameters = empty_data();
+
+ *cksum1_out = cksum1;
+ *cksum2_out = cksum2;
+ return 0;
+
+fail:
+ krb5_free_data_contents(context, &cksum1);
+ free_pachecksum2(context, &cksum2);
+ return KRB5_CRYPTO_INTERNAL;
+}
+
+krb5_error_code
+crypto_verify_checksums(krb5_context context, krb5_data *body,
+ const krb5_data *cksum1,
+ const krb5_pachecksum2 *cksum2)
+{
+ const EVP_MD *md;
+
+ /* RFC 4556 doesn't say what error to return if the checksum doesn't match.
+ * Windows returns this one. */
+ if (!check_digest(body, EVP_sha1(), cksum1))
+ return KRB5KRB_AP_ERR_MODIFIED;
+
+ if (cksum2 == NULL)
+ return 0;
+
+ md = md_from_cms_oid(&cksum2->algorithmIdentifier.algorithm);
+ if (!check_digest(body, md, &cksum2->checksum))
+ return KRB5KRB_AP_ERR_MODIFIED;
+
+ return 0;
+}
diff --git a/src/plugins/preauth/pkinit/pkinit_kdf_test.c b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
index 99c93ac128..dd6e8d7503 100644
--- a/src/plugins/preauth/pkinit/pkinit_kdf_test.c
+++ b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
@@ -126,7 +126,7 @@ main(int argc, char **argv)
/* TEST 1: SHA-1/AES */
/* set up algorithm id */
- alg_id.algorithm = sha1_id;
+ alg_id.algorithm = kdf_sha1_id;
enctype = enctype_aes;
@@ -157,7 +157,7 @@ main(int argc, char **argv)
/* TEST 2: SHA-256/AES */
/* set up algorithm id */
- alg_id.algorithm = sha256_id;
+ alg_id.algorithm = kdf_sha256_id;
enctype = enctype_aes;
diff --git a/src/plugins/preauth/pkinit/pkinit_lib.c b/src/plugins/preauth/pkinit/pkinit_lib.c
index 25965eb5d2..891f47fd26 100644
--- a/src/plugins/preauth/pkinit/pkinit_lib.c
+++ b/src/plugins/preauth/pkinit/pkinit_lib.c
@@ -29,6 +29,7 @@
* SUCH DAMAGES.
*/
+#include "k5-int.h"
#include "pkinit.h"
#define FAKECERT
@@ -119,8 +120,9 @@ free_krb5_auth_pack(krb5_auth_pack **in)
{
if ((*in) == NULL) return;
krb5_free_data_contents(NULL, &(*in)->clientPublicValue);
- free((*in)->pkAuthenticator.paChecksum.contents);
+ free((*in)->pkAuthenticator.paChecksum.data);
krb5_free_data(NULL, (*in)->pkAuthenticator.freshnessToken);
+ free_pachecksum2(NULL, &(*in)->pkAuthenticator.paChecksum2);
if ((*in)->supportedCMSTypes != NULL)
free_krb5_algorithm_identifiers(&((*in)->supportedCMSTypes));
if ((*in)->supportedKDFs) {
@@ -196,6 +198,18 @@ free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in)
free(*in);
}
+void
+free_pachecksum2(krb5_context context, krb5_pachecksum2 **in)
+{
+ if (*in == NULL)
+ return;
+ krb5_free_data_contents(context, &(*in)->checksum);
+ krb5_free_data_contents(context, &(*in)->algorithmIdentifier.algorithm);
+ krb5_free_data_contents(context, &(*in)->algorithmIdentifier.parameters);
+ free(*in);
+ *in = NULL;
+}
+
void
init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
{
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index e22bcb195b..f558308483 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -428,11 +428,12 @@ pkinit_server_verify_padata(krb5_context context,
krb5_data authp_data = {0, 0, NULL}, krb5_authz = {0, 0, NULL};
krb5_pa_pk_as_req *reqp = NULL;
krb5_auth_pack *auth_pack = NULL;
+ krb5_pk_authenticator *pka;
pkinit_kdc_context plgctx = NULL;
pkinit_kdc_req_context reqctx = NULL;
krb5_checksum cksum = {0, 0, 0, NULL};
krb5_data *der_req = NULL;
- krb5_data k5data, *ftoken;
+ krb5_data k5data;
int is_signed = 1;
krb5_pa_data **e_data = NULL;
krb5_kdcpreauth_modreq modreq = NULL;
@@ -524,8 +525,9 @@ pkinit_server_verify_padata(krb5_context context,
pkiDebug("failed to decode krb5_auth_pack\n");
goto cleanup;
}
+ pka = &auth_pack->pkAuthenticator;
- retval = krb5_check_clockskew(context, auth_pack->pkAuthenticator.ctime);
+ retval = krb5_check_clockskew(context, pka->ctime);
if (retval)
goto cleanup;
@@ -548,36 +550,14 @@ pkinit_server_verify_padata(krb5_context context,
goto cleanup;
}
der_req = cb->request_body(context, rock);
- retval = krb5_c_make_checksum(context, CKSUMTYPE_SHA1, NULL, 0, der_req,
- &cksum);
- if (retval) {
- pkiDebug("unable to calculate AS REQ checksum\n");
- goto cleanup;
- }
- if (cksum.length != auth_pack->pkAuthenticator.paChecksum.length ||
- k5_bcmp(cksum.contents, auth_pack->pkAuthenticator.paChecksum.contents,
- cksum.length) != 0) {
- pkiDebug("failed to match the checksum\n");
-#ifdef DEBUG_CKSUM
- pkiDebug("calculating checksum on buf size (%d)\n", req_pkt->length);
- print_buffer(req_pkt->data, req_pkt->length);
- pkiDebug("received checksum type=%d size=%d ",
- auth_pack->pkAuthenticator.paChecksum.checksum_type,
- auth_pack->pkAuthenticator.paChecksum.length);
- print_buffer(auth_pack->pkAuthenticator.paChecksum.contents,
- auth_pack->pkAuthenticator.paChecksum.length);
- pkiDebug("expected checksum type=%d size=%d ",
- cksum.checksum_type, cksum.length);
- print_buffer(cksum.contents, cksum.length);
-#endif
- retval = KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED;
+ retval = crypto_verify_checksums(context, der_req, &pka->paChecksum,
+ pka->paChecksum2);
+ if (retval)
goto cleanup;
- }
- ftoken = auth_pack->pkAuthenticator.freshnessToken;
- if (ftoken != NULL) {
- retval = cb->check_freshness_token(context, rock, ftoken);
+ if (pka->freshnessToken != NULL) {
+ retval = cb->check_freshness_token(context, rock, pka->freshnessToken);
if (retval)
goto cleanup;
valid_freshness_token = TRUE;
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
index 1faa6816d7..7b68d4b3b1 100644
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
@@ -58,8 +58,9 @@
TRACE(c, "PKINIT client verified DH reply")
#define TRACE_PKINIT_CLIENT_REP_DH_FAIL(c) \
TRACE(c, "PKINIT client could not verify DH reply")
-#define TRACE_PKINIT_CLIENT_REQ_CHECKSUM(c, cksum) \
- TRACE(c, "PKINIT client computed kdc-req-body checksum {cksum}", cksum)
+#define TRACE_PKINIT_CLIENT_REQ_CHECKSUMS(c, ck1, ck2) \
+ TRACE(c, "PKINIT client computed checksums: {hexdata} {hexdata}", \
+ ck1, &(ck2)->checksum)
#define TRACE_PKINIT_CLIENT_REQ_DH(c) \
TRACE(c, "PKINIT client making DH request")
#define TRACE_PKINIT_CLIENT_SAN_CONFIG_DNSNAME(c, host) \
diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
index 2fa6dce8eb..f47849abad 100644
--- a/src/tests/asn.1/krb5_decode_test.c
+++ b/src/tests/asn.1/krb5_decode_test.c
@@ -1174,7 +1174,7 @@ main(int argc, char **argv)
/* decode_krb5_auth_pack */
{
setup(krb5_auth_pack,ktest_make_sample_auth_pack);
- decode_run("krb5_auth_pack","","30 81 85 A0 35 30 33 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61",
+ decode_run("krb5_auth_pack","","30 81 89 A0 39 30 37 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61",
acc.decode_krb5_auth_pack,
ktest_equal_auth_pack,ktest_free_auth_pack);
ktest_empty_auth_pack(&ref);
diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
index d37e4fa7e6..7f54aa3184 100644
--- a/src/tests/asn.1/ktest.c
+++ b/src/tests/asn.1/ktest.c
@@ -700,9 +700,7 @@ ktest_make_sample_pk_authenticator(krb5_pk_authenticator *p)
p->cusec = SAMPLE_USEC;
p->ctime = SAMPLE_TIME;
p->nonce = SAMPLE_NONCE;
- ktest_make_sample_checksum(&p->paChecksum);
- /* We don't encode the checksum type, only the contents. */
- p->paChecksum.checksum_type = 0;
+ ktest_make_sample_data(&p->paChecksum);
p->freshnessToken = ealloc(sizeof(krb5_data));
ktest_make_sample_data(p->freshnessToken);
}
@@ -1604,8 +1602,7 @@ ktest_empty_pa_otp_req(krb5_pa_otp_req *p)
static void
ktest_empty_pk_authenticator(krb5_pk_authenticator *p)
{
- ktest_empty_checksum(&p->paChecksum);
- p->paChecksum.contents = NULL;
+ ktest_empty_data(&p->paChecksum);
krb5_free_data(NULL, p->freshnessToken);
p->freshnessToken = NULL;
}
diff --git a/src/tests/asn.1/ktest_equal.c b/src/tests/asn.1/ktest_equal.c
index b48a0285d2..13786dd1e5 100644
--- a/src/tests/asn.1/ktest_equal.c
+++ b/src/tests/asn.1/ktest_equal.c
@@ -844,7 +844,7 @@ ktest_equal_pk_authenticator(krb5_pk_authenticator *ref,
p = p && scalar_equal(cusec);
p = p && scalar_equal(ctime);
p = p && scalar_equal(nonce);
- p = p && struct_equal(paChecksum, ktest_equal_checksum);
+ p = p && data_eq(ref->paChecksum, var->paChecksum);
return p;
}
diff --git a/src/tests/asn.1/pkinit_encode.out b/src/tests/asn.1/pkinit_encode.out
index 6ec7aaa36a..a764182e15 100644
--- a/src/tests/asn.1/pkinit_encode.out
+++ b/src/tests/asn.1/pkinit_encode.out
@@ -1,7 +1,7 @@
encode_krb5_pa_pk_as_req: 30 38 80 08 6B 72 62 35 64 61 74 61 A1 22 30 20 30 1E 80 08 6B 72 62 35 64 61 74 61 81 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61
encode_krb5_pa_pk_as_rep(dhInfo): A0 28 30 26 80 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
encode_krb5_pa_pk_as_rep(encKeyPack): 81 08 6B 72 62 35 64 61 74 61
-encode_krb5_auth_pack: 30 81 85 A0 35 30 33 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
+encode_krb5_auth_pack: 30 81 89 A0 39 30 37 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
encode_krb5_kdc_dh_key_info: 30 25 A0 0B 03 09 00 6B 72 62 35 64 61 74 61 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A
encode_krb5_reply_key_pack: 30 26 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34
encode_krb5_sp80056a_other_info: 30 81 81 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A0 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 0A 04 08 6B 72 62 35 64 61 74 61
diff --git a/src/tests/asn.1/pkinit_trval.out b/src/tests/asn.1/pkinit_trval.out
index 46f4a34108..c47bd71f67 100644
--- a/src/tests/asn.1/pkinit_trval.out
+++ b/src/tests/asn.1/pkinit_trval.out
@@ -38,7 +38,7 @@ encode_krb5_auth_pack:
. . [0] [Integer] 123456
. . [1] [Generalized Time] "19940610060317Z"
. . [2] [Integer] 42
-. . [3] [Octet String] "1234"
+. . [3] [Octet String] "krb5data"
. . [4] [Octet String] "krb5data"
. [1] [Octet String] "pvalue"
. [2] [Sequence/Sequence Of]
--
2.49.0

View file

@ -0,0 +1,381 @@
From 33afd2a6cfdf87d153170b41fbabfb92be49c422 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Thu, 10 Apr 2025 10:04:22 +0200
Subject: [PATCH] [downstream] Do not block HMAC-MD4/5 in FIPS mode
To ensure RC4 HMAC-MD5 was not used in FIPS mode, access to HMAC-MD4/5
was not allowed in this mode. However, since we provide the
"radius_md5_fips_override" configuration parameter to allow using RADIUS
regardless to the FIPS restrictions, we should allow HMAC-MD5 to be used
too in this case, because it is required for the newly supported
Message-Authenticator attribute.
A FIPS mode check is added in calculate_mac() which will fail if
"radius_md5_fips_override" is not true. It will not affect interactions
between krb5kdc and ipa-otpd, because the Message-Authenticator
attribute is not generated in this case.
---
src/lib/crypto/krb/crypto_int.h | 9 +++
src/lib/crypto/openssl/Makefile.in | 9 ++-
src/lib/crypto/openssl/common.c | 80 +++++++++++++++++++
.../crypto/openssl/hash_provider/hash_evp.c | 62 ++------------
src/lib/crypto/openssl/hmac.c | 15 ++--
src/lib/krad/packet.c | 19 +++--
6 files changed, 120 insertions(+), 74 deletions(-)
create mode 100644 src/lib/crypto/openssl/common.c
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index 1ee4b30e02..ff67b6bd35 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -36,6 +36,9 @@
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+#include <openssl/provider.h>
+
/*
* OpenSSL 3.0 relegates MD4 and RC4 to the legacy provider, which must be
* explicitly loaded into a library context. Performing this loading within a
@@ -660,4 +663,10 @@ iov_cursor_advance(struct iov_cursor *c, size_t nblocks)
c->out_pos += nblocks * c->block_size;
}
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+krb5_error_code k5_get_ossl_legacy_libctx(OSSL_LIB_CTX **libctx);
+
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
+
#endif /* CRYPTO_INT_H */
diff --git a/src/lib/crypto/openssl/Makefile.in b/src/lib/crypto/openssl/Makefile.in
index 8e4cdb8bbf..cc131000bd 100644
--- a/src/lib/crypto/openssl/Makefile.in
+++ b/src/lib/crypto/openssl/Makefile.in
@@ -8,21 +8,24 @@ STLIBOBJS=\
hmac.o \
kdf.o \
pbkdf2.o \
- sha256.o
+ sha256.o \
+ common.o
OBJS=\
$(OUTPRE)cmac.$(OBJEXT) \
$(OUTPRE)hmac.$(OBJEXT) \
$(OUTPRE)kdf.$(OBJEXT) \
$(OUTPRE)pbkdf2.$(OBJEXT) \
- $(OUTPRE)sha256.$(OBJEXT)
+ $(OUTPRE)sha256.$(OBJEXT) \
+ $(OUTPRE)common.$(OBJEXT)
SRCS=\
$(srcdir)/cmac.c \
$(srcdir)/hmac.c \
$(srcdir)/kdf.c \
$(srcdir)/pbkdf2.c \
- $(srcdir)/sha256.c
+ $(srcdir)/sha256.c \
+ $(srcdir)/common.c
SUBDIROBJLISTS= md4/OBJS.ST \
md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \
diff --git a/src/lib/crypto/openssl/common.c b/src/lib/crypto/openssl/common.c
new file mode 100644
index 0000000000..ced43fd54c
--- /dev/null
+++ b/src/lib/crypto/openssl/common.c
@@ -0,0 +1,80 @@
+#include "crypto_int.h"
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+#include <openssl/provider.h>
+#include <openssl/fips.h>
+#include <threads.h>
+#include <stdbool.h>
+
+typedef struct ossl_legacy_context {
+ bool initialized;
+ OSSL_LIB_CTX *libctx;
+ OSSL_PROVIDER *default_provider;
+ OSSL_PROVIDER *legacy_provider;
+} ossl_legacy_context_t;
+
+static thread_local ossl_legacy_context_t g_ossl_legacy_ctx;
+
+static krb5_error_code
+init_ossl_legacy_ctx(ossl_legacy_context_t *ctx)
+{
+ ctx->libctx = OSSL_LIB_CTX_new();
+ if (!ctx->libctx)
+ return KRB5_CRYPTO_INTERNAL;
+
+ /* Load both legacy and default provider as both may be needed. */
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
+
+ if (!(ctx->default_provider && ctx->legacy_provider))
+ return KRB5_CRYPTO_INTERNAL;
+
+ ctx->initialized = true;
+ return 0;
+}
+
+static void
+deinit_ossl_legacy_ctx(ossl_legacy_context_t *ctx)
+{
+ if (ctx->legacy_provider)
+ OSSL_PROVIDER_unload(ctx->legacy_provider);
+
+ if (ctx->default_provider)
+ OSSL_PROVIDER_unload(ctx->default_provider);
+
+ if (ctx->libctx)
+ OSSL_LIB_CTX_free(ctx->libctx);
+
+ ctx->initialized = false;
+}
+
+krb5_error_code
+k5_get_ossl_legacy_libctx(OSSL_LIB_CTX **libctx)
+{
+ krb5_error_code err;
+
+ if (!FIPS_mode()) {
+ if (libctx)
+ *libctx = NULL;
+ err = 0;
+ goto end;
+ }
+
+ if (!g_ossl_legacy_ctx.initialized) {
+ err = init_ossl_legacy_ctx(&g_ossl_legacy_ctx);
+ if (err) {
+ deinit_ossl_legacy_ctx(&g_ossl_legacy_ctx);
+ goto end;
+ }
+ }
+
+ if (libctx)
+ *libctx = g_ossl_legacy_ctx.libctx;
+ err = 0;
+
+end:
+ return err;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index eb2e693e9f..2fd5d383d6 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -44,48 +44,7 @@
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#endif
-#include <openssl/provider.h>
#include <openssl/fips.h>
-#include <threads.h>
-
-typedef struct ossl_lib_md_context {
- OSSL_LIB_CTX *libctx;
- OSSL_PROVIDER *default_provider;
- OSSL_PROVIDER *legacy_provider;
-} ossl_md_context_t;
-
-static thread_local ossl_md_context_t *ossl_md_ctx = NULL;
-
-static krb5_error_code
-init_ossl_md_ctx(ossl_md_context_t *ctx, const char *algo)
-{
- ctx->libctx = OSSL_LIB_CTX_new();
- if (!ctx->libctx)
- return KRB5_CRYPTO_INTERNAL;
-
- /* Load both legacy and default provider as both may be needed. */
- ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
- ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
-
- if (!(ctx->default_provider && ctx->legacy_provider))
- return KRB5_CRYPTO_INTERNAL;
-
- return 0;
-}
-
-static void
-deinit_ossl_ctx(ossl_md_context_t *ctx)
-{
- if (ctx->legacy_provider)
- OSSL_PROVIDER_unload(ctx->legacy_provider);
-
- if (ctx->default_provider)
- OSSL_PROVIDER_unload(ctx->default_provider);
-
- if (ctx->libctx)
- OSSL_LIB_CTX_free(ctx->libctx);
-}
-
static krb5_error_code
hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
@@ -120,25 +79,14 @@ hash_legacy_evp(const char *algo, const krb5_crypto_iov *data, size_t num_data,
krb5_data *output)
{
krb5_error_code err;
+ OSSL_LIB_CTX *ossl_libctx;
EVP_MD *md = NULL;
- if (!ossl_md_ctx) {
- ossl_md_ctx = malloc(sizeof(ossl_md_context_t));
- if (!ossl_md_ctx) {
- err = ENOMEM;
- goto end;
- }
-
- err = init_ossl_md_ctx(ossl_md_ctx, algo);
- if (err) {
- deinit_ossl_ctx(ossl_md_ctx);
- free(ossl_md_ctx);
- ossl_md_ctx = NULL;
- goto end;
- }
- }
+ err = k5_get_ossl_legacy_libctx(&ossl_libctx);
+ if (err)
+ goto end;
- md = EVP_MD_fetch(ossl_md_ctx->libctx, algo, NULL);
+ md = EVP_MD_fetch(ossl_libctx, algo, NULL);
if (!md) {
err = KRB5_CRYPTO_INTERNAL;
goto end;
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index 25a419d73a..8f9e88fec9 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -59,7 +59,6 @@
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/params.h>
#include <openssl/core_names.h>
-#include <openssl/fips.h>
#else
#include <openssl/hmac.h>
#endif
@@ -112,11 +111,7 @@ map_digest(const struct krb5_hash_provider *hash)
return EVP_sha256();
else if (hash == &krb5int_hash_sha384)
return EVP_sha384();
-
- if (FIPS_mode())
- return NULL;
-
- if (hash == &krb5int_hash_md5)
+ else if (hash == &krb5int_hash_md5)
return EVP_md5();
else if (hash == &krb5int_hash_md4)
return EVP_md4();
@@ -138,13 +133,19 @@ krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
EVP_MAC_CTX *ctx = NULL;
OSSL_PARAM params[2], *p = params;
size_t i = 0, md_len;
+ OSSL_LIB_CTX *ossl_libctx;
+ krb5_error_code err;
if (md == NULL || keyblock->length > hash->blocksize)
return KRB5_CRYPTO_INTERNAL;
if (output->length < hash->hashsize)
return KRB5_BAD_MSIZE;
- mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ err = k5_get_ossl_legacy_libctx(&ossl_libctx);
+ if (err)
+ return err;
+
+ mac = EVP_MAC_fetch(ossl_libctx, "HMAC", NULL);
if (mac == NULL)
return KRB5_CRYPTO_INTERNAL;
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
index 3c1a4d507e..b95c99df65 100644
--- a/src/lib/krad/packet.c
+++ b/src/lib/krad/packet.c
@@ -278,7 +278,7 @@ lookup_msgauth_addr(const krad_packet *pkt)
* auth, which may be from pkt or from a corresponding request.
*/
static krb5_error_code
-calculate_mac(const char *secret, const krad_packet *pkt,
+calculate_mac(krb5_context ctx, const char *secret, const krad_packet *pkt,
const uint8_t auth[AUTH_FIELD_SIZE],
uint8_t mac_out[MD5_DIGEST_SIZE])
{
@@ -288,6 +288,10 @@ calculate_mac(const char *secret, const krad_packet *pkt,
krb5_crypto_iov input[5];
krb5_data ksecr, mac;
+ /* Do not use HMAC-MD5 if not explicitly allowed */
+ if (kr_use_fips(ctx))
+ return KRB5_CRYPTO_INTERNAL;
+
msgauth_attr = lookup_msgauth_addr(pkt);
if (msgauth_attr == NULL)
return EINVAL;
@@ -393,7 +397,8 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
if (msgauth_required) {
/* Calculate and set the Message-Authenticator MAC. */
- retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2);
+ retval = calculate_mac(ctx, secret, pkt, pkt_auth(pkt),
+ pkt_attr(pkt) + 2);
if (retval != 0)
goto error;
}
@@ -454,7 +459,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
* section 5.14, use the authenticator from the request, not from the
* response.
*/
- retval = calculate_mac(secret, pkt, pkt_auth(request),
+ retval = calculate_mac(ctx, secret, pkt, pkt_auth(request),
pkt_attr(pkt) + 2);
if (retval != 0)
goto error;
@@ -476,7 +481,7 @@ error:
/* Verify the Message-Authenticator value in pkt, using the provided
* authenticator (which may be from pkt or from a corresponding request). */
static krb5_error_code
-verify_msgauth(const char *secret, const krad_packet *pkt,
+verify_msgauth(krb5_context ctx, const char *secret, const krad_packet *pkt,
const uint8_t auth[AUTH_FIELD_SIZE])
{
uint8_t mac[MD5_DIGEST_SIZE];
@@ -488,7 +493,7 @@ verify_msgauth(const char *secret, const krad_packet *pkt,
if (msgauth == NULL)
return ENODATA;
- retval = calculate_mac(secret, pkt, auth, mac);
+ retval = calculate_mac(ctx, secret, pkt, auth, mac);
if (retval)
return retval;
@@ -561,7 +566,7 @@ krad_packet_decode_request(krb5_context ctx, const char *secret,
/* Verify Message-Authenticator if present. */
if (has_pkt_msgauth(req)) {
- retval = verify_msgauth(secret, req, pkt_auth(req));
+ retval = verify_msgauth(ctx, secret, req, pkt_auth(req));
if (retval) {
krad_packet_free(req);
return retval;
@@ -613,7 +618,7 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
/* Verify Message-Authenticator if present. */
if (has_pkt_msgauth(*rsppkt)) {
- if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0)
+ if (verify_msgauth(ctx, secret, *rsppkt, pkt_auth(tmp)) != 0)
continue;
}
--
2.49.0

View file

@ -0,0 +1,189 @@
From 1761e06398e4f043e4f540f57131c37fcc53a1b9 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Wed, 10 Dec 2025 10:42:02 +0200
Subject: [PATCH] Fix strchr() conformance to C23
C23 7.28.5.1 specifies search functions such as strchr() as generic,
returning const char * if the first argument is of type const char *.
Fix uses of strchr() to conform to this change.
[jrische@redhat.com: altered changes to avoid casts; fixed an
additional case]
[ghudson@mit.edu: condensed some declarations; rewrote commit message]
ticket: 9191 (new)
(cherry picked from commit 6cd8580d823585d50ee4f30efd9f7e855823a369)
---
src/lib/krb5/ccache/ccbase.c | 4 ++--
src/lib/krb5/os/expand_path.c | 3 ++-
src/lib/krb5/os/locate_kdc.c | 15 +++++++--------
src/plugins/preauth/pkinit/pkinit_crypto.h | 2 +-
.../preauth/pkinit/pkinit_crypto_openssl.c | 6 +++---
src/plugins/preauth/pkinit/pkinit_identity.c | 2 +-
src/plugins/preauth/pkinit/pkinit_matching.c | 2 +-
src/tests/responder.c | 3 +--
8 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
index 5a01320832..1aada91b5e 100644
--- a/src/lib/krb5/ccache/ccbase.c
+++ b/src/lib/krb5/ccache/ccbase.c
@@ -201,8 +201,8 @@ krb5_cc_register(krb5_context context, const krb5_cc_ops *ops,
krb5_error_code KRB5_CALLCONV
krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache)
{
- char *pfx, *cp;
- const char *resid;
+ char *pfx;
+ const char *cp, *resid;
unsigned int pfxlen;
krb5_error_code err;
const krb5_cc_ops *ops;
diff --git a/src/lib/krb5/os/expand_path.c b/src/lib/krb5/os/expand_path.c
index 5cbccf08c8..6569b8820b 100644
--- a/src/lib/krb5/os/expand_path.c
+++ b/src/lib/krb5/os/expand_path.c
@@ -454,7 +454,8 @@ k5_expand_path_tokens_extra(krb5_context context, const char *path_in,
{
krb5_error_code ret;
struct k5buf buf;
- char *tok_begin, *tok_end, *tok_val, **extra_tokens = NULL, *path;
+ const char *tok_begin, *tok_end;
+ char *tok_val, **extra_tokens = NULL, *path;
const char *path_left;
size_t nargs = 0, i;
va_list ap;
diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
index edca5ac7eb..47e15c849f 100644
--- a/src/lib/krb5/os/locate_kdc.c
+++ b/src/lib/krb5/os/locate_kdc.c
@@ -188,8 +188,8 @@ oom:
}
static void
-parse_uri_if_https(const char *host_or_uri, k5_transport *transport,
- const char **host, const char **uri_path)
+parse_uri_if_https(char *host_or_uri, k5_transport *transport,
+ char **host, const char **uri_path)
{
char *cp;
@@ -229,8 +229,7 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm,
k5_transport transport, int udpport)
{
const char *realm_srv_names[4];
- char **hostlist = NULL, *realmstr = NULL, *host = NULL;
- const char *hostspec;
+ char **hostlist = NULL, *realmstr = NULL, *host = NULL, *hostspec;
krb5_error_code code;
int i, default_port;
@@ -535,8 +534,8 @@ prof_locate_server(krb5_context context, const krb5_data *realm,
* Return a NULL *host_out if there are any problems parsing the URI.
*/
static void
-parse_uri_fields(const char *uri, k5_transport *transport_out,
- const char **host_out, int *primary_out)
+parse_uri_fields(char *uri, k5_transport *transport_out,
+ char **host_out, int *primary_out)
{
k5_transport transport;
@@ -604,8 +603,8 @@ locate_uri(krb5_context context, const krb5_data *realm,
krb5_error_code ret;
k5_transport transport, host_trans;
struct srv_dns_entry *answers, *entry;
- char *host;
- const char *host_field, *path;
+ char *host, *host_field;
+ const char *path;
int port, def_port, primary;
ret = k5_make_uri_query(context, realm, req_service, &answers);
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
index 3b12e904b1..99e2394040 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
@@ -456,7 +456,7 @@ krb5_error_code crypto_load_cas_and_crls
defines the storage type (file, directory, etc) */
int catype, /* IN
defines the ca type (anchor, intermediate, crls) */
- char *id); /* IN
+ const char *id); /* IN
defines the location (filename, directory name, etc) */
/*
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 429b7d202c..6013080afc 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -4956,7 +4956,7 @@ load_cas_and_crls(krb5_context context,
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_crypto_context id_cryptoctx,
int catype,
- char *filename)
+ const char *filename)
{
STACK_OF(X509_INFO) *sk = NULL;
STACK_OF(X509) *ca_certs = NULL;
@@ -5114,7 +5114,7 @@ load_cas_and_crls_dir(krb5_context context,
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_crypto_context id_cryptoctx,
int catype,
- char *dirname)
+ const char *dirname)
{
krb5_error_code retval = EINVAL;
DIR *d = NULL;
@@ -5166,7 +5166,7 @@ crypto_load_cas_and_crls(krb5_context context,
pkinit_identity_crypto_context id_cryptoctx,
int idtype,
int catype,
- char *id)
+ const char *id)
{
switch (idtype) {
case IDTYPE_FILE:
diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c
index a5a979f279..b06d519c66 100644
--- a/src/plugins/preauth/pkinit/pkinit_identity.c
+++ b/src/plugins/preauth/pkinit/pkinit_identity.c
@@ -474,7 +474,7 @@ process_option_ca_crl(krb5_context context,
const char *value,
int catype)
{
- char *residual;
+ const char *residual;
unsigned int typelen;
int idtype;
diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c
index b42485a50a..5a7f2ba3fa 100644
--- a/src/plugins/preauth/pkinit/pkinit_matching.c
+++ b/src/plugins/preauth/pkinit/pkinit_matching.c
@@ -263,7 +263,7 @@ parse_rule_component(krb5_context context,
char err_buf[128];
int ret;
struct keyword_desc *kw, *nextkw;
- char *nk;
+ const char *nk;
int found_next_kw = 0;
char *value = NULL;
size_t len;
diff --git a/src/tests/responder.c b/src/tests/responder.c
index 82f870ea5d..4221a20283 100644
--- a/src/tests/responder.c
+++ b/src/tests/responder.c
@@ -282,8 +282,7 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx)
/* Provide a particular response for an OTP challenge. */
if (data->otp_answer != NULL) {
if (krb5_responder_otp_get_challenge(ctx, rctx, &ochl) == 0) {
- key = strchr(data->otp_answer, '=');
- if (key != NULL) {
+ if (strchr(data->otp_answer, '=') != NULL) {
/* Make a copy of the answer that we can chop up. */
key = strdup(data->otp_answer);
if (key == NULL)
--
2.51.1

226
0040-automated-fast.patch Normal file
View file

@ -0,0 +1,226 @@
From 3baf9b93dc1dfe38585722c71d7268304cb4a01a Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Sun, 21 Sep 2025 11:14:51 +0300
Subject: libkrb5: in case PKINIT is configured, attempt Anonymous
PKINIT for FAST
If auto_fast_armor is configured for the realm or globally, optimistically
assume that Anonymous PKINIT is supported as well and try to obtain it for
FAST use in case no pre-made FAST channel was established by the caller.
This behavior will automatically enable use of passwordless pre-authentication
methods which rely on FAST channel presence in deployments such as FreeIPA.
Notably, Microsoft Active Directory KDCs do not support Anonymous PKINIT. For
these deployments only a machine account (host keytab) can be used to build a
FAST channel. However, libkrb5 does not have access to /etc/krb5.keytab in a
general case.
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
---
src/lib/krb5/krb/fast.c | 118 ++++++++++++++++++++++++++++++++++++++++
src/lib/krb5/krb/fast.h | 2 +
src/man/krb5.conf.man | 13 +++++
3 files changed, 133 insertions(+)
diff --git a/src/lib/krb5/krb/fast.c b/src/lib/krb5/krb/fast.c
index 62c9f0841..ee2e08189 100644
--- a/src/lib/krb5/krb/fast.c
+++ b/src/lib/krb5/krb/fast.c
@@ -168,6 +168,109 @@ krb5int_fast_prep_req_body(krb5_context context,
return retval;
}
+static krb5_boolean
+fast_is_pkinit_allowed(krb5_context context, krb5_data *realm)
+{
+ int value;
+ krb5_error_code retval = EINVAL;
+ char realmstr[1024];
+ const char *option = "auto_fast_armor";
+ const int def_value = FALSE;
+
+ if (realm != NULL && realm->length > sizeof(realmstr)-1)
+ return FALSE;
+
+ if (realm != NULL) {
+ strncpy(realmstr, realm->data, realm->length);
+ realmstr[realm->length] = '\0';
+
+ retval = profile_get_boolean(context->profile,
+ KRB5_CONF_REALMS, realmstr,
+ option, def_value, &value);
+ }
+
+ return retval ? FALSE : value;
+
+}
+
+static krb5_error_code
+fast_acquire_pkinit_armor(krb5_context context,
+ struct krb5int_fast_request_state *state,
+ krb5_get_init_creds_opt *opt, krb5_kdc_req *request)
+{
+ krb5_context ctx;
+ krb5_get_init_creds_opt *options = NULL;
+ krb5_error_code retval = 0;
+ krb5_data *target_realm = &request->server->realm;
+ krb5_creds creds;
+ krb5_principal anon_princ = NULL;
+ krb5_ccache out_cc;
+
+ /* short circuit, we are asked to perform Anonymous PKINIT already */
+ if (opt->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) {
+ return EINVAL;
+ }
+
+ /* skip realms which do not allow use of automated FAST armor */
+ if (!fast_is_pkinit_allowed(context, target_realm)) {
+ return EINVAL;
+ }
+
+ retval = krb5_init_context(&ctx);
+ if (retval != 0) {
+ return retval;
+ }
+ retval = krb5_get_init_creds_opt_alloc(ctx, &options);
+ if (retval != 0) {
+ goto cleanup;
+ }
+ krb5_get_init_creds_opt_set_anonymous(options, 1);
+ retval = krb5_cc_new_unique(ctx, "MEMORY", NULL, &out_cc);
+ if (retval != 0) {
+ goto cleanup;
+ }
+
+ retval = krb5_get_init_creds_opt_set_out_ccache(ctx, options, out_cc);
+ if (retval != 0) {
+ goto cleanup;
+ }
+
+ retval = krb5_build_principal_ext(ctx, &anon_princ,
+ target_realm->length, target_realm->data,
+ strlen(KRB5_WELLKNOWN_NAMESTR),
+ KRB5_WELLKNOWN_NAMESTR,
+ strlen(KRB5_ANONYMOUS_PRINCSTR),
+ KRB5_ANONYMOUS_PRINCSTR, 0);
+ if (retval != 0) {
+ goto cleanup;
+ }
+
+ retval = krb5_get_init_creds_password(ctx, &creds, anon_princ, 0,
+ NULL /* no prompter */, NULL,
+ 0, NULL /* service name */,
+ options);
+ if (retval == 0) {
+ state->fast_state_flags |= KRB5INT_FAST_OWN_ARMOR;
+ state->armor_ccache = out_cc;
+ }
+cleanup:
+ if (retval != 0 && out_cc != NULL) {
+ (void) krb5_cc_destroy(ctx, out_cc);
+ }
+ if (retval == 0) {
+ krb5_free_cred_contents(ctx, &creds);
+ }
+ if (options != NULL) {
+ krb5_get_init_creds_opt_free(ctx, options);
+ }
+ if (anon_princ != NULL) {
+ krb5_free_principal(ctx, anon_princ);
+ }
+ krb5_free_context(ctx);
+
+ return retval;
+}
+
krb5_error_code
krb5int_fast_as_armor(krb5_context context,
struct krb5int_fast_request_state *state,
@@ -178,10 +281,20 @@ krb5int_fast_as_armor(krb5_context context,
krb5_principal target_principal = NULL;
krb5_data *target_realm;
const char *ccname = k5_gic_opt_get_fast_ccache_name(opt);
+ char *fast_ccname = NULL;
krb5_flags fast_flags;
krb5_clear_error_message(context);
target_realm = &request->server->realm;
+ if (ccname == NULL) {
+ retval = fast_acquire_pkinit_armor(context, state, opt, request);
+ if (retval == 0) {
+ retval = krb5_cc_get_full_name(context, state->armor_ccache, &fast_ccname);
+ if (retval == 0 && fast_ccname != NULL)
+ ccname = fast_ccname;
+ }
+ retval = 0;
+ }
if (ccname != NULL) {
TRACE_FAST_ARMOR_CCACHE(context, ccname);
state->fast_state_flags |= KRB5INT_FAST_ARMOR_AVAIL;
@@ -220,6 +333,8 @@ krb5int_fast_as_armor(krb5_context context,
krb5_cc_close(context, ccache);
if (target_principal)
krb5_free_principal(context, target_principal);
+ if (fast_ccname)
+ free(fast_ccname);
return retval;
}
@@ -615,6 +730,9 @@ krb5int_fast_free_state(krb5_context context,
/*We are responsible for none of the store in the fast_outer_req*/
krb5_free_keyblock(context, state->armor_key);
krb5_free_fast_armor(context, state->armor);
+ if (state->fast_state_flags & KRB5INT_FAST_OWN_ARMOR) {
+ krb5_cc_destroy(context, state->armor_ccache);
+ }
free(state);
}
diff --git a/src/lib/krb5/krb/fast.h b/src/lib/krb5/krb/fast.h
index 7156ea203..e5fe8bd54 100644
--- a/src/lib/krb5/krb/fast.h
+++ b/src/lib/krb5/krb/fast.h
@@ -34,6 +34,7 @@ struct krb5int_fast_request_state {
krb5_kdc_req fast_outer_request;
krb5_keyblock *armor_key; /*non-null means fast is in use*/
krb5_fast_armor *armor;
+ krb5_ccache armor_ccache;
krb5_ui_4 fast_state_flags;
krb5_ui_4 fast_options;
krb5_int32 nonce;
@@ -41,6 +42,7 @@ struct krb5int_fast_request_state {
#define KRB5INT_FAST_DO_FAST (1l<<0) /* Perform FAST */
#define KRB5INT_FAST_ARMOR_AVAIL (1l<<1)
+#define KRB5INT_FAST_OWN_ARMOR (1l<<2)
krb5_error_code
krb5int_fast_prep_req_body(krb5_context context,
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man
index d4caa2bd3..ac7649647 100644
--- a/src/man/krb5.conf.man
+++ b/src/man/krb5.conf.man
@@ -650,6 +650,19 @@ primary KDC, in case the user\(aqs password has just been changed, and
the updated database has not been propagated to the replica
servers yet. New in release 1.19.
.TP
+\fBauto_fast_armor\fP
+If this flag is true, then initial ticket request will use Anonymous
+PKINIT to protect the communication as a FAST channel in case an application
+did not provide its own FAST channel. This is useful for deployments where
+pre-authentication methods require use of the FAST channel, such as
+passwordless methods provided by FreeIPA. Microsoft Active Directory
+implementation of PKINIT does not support Anonymous PKINIT feature.
+As a result, \fIauto_fast_armor\fP defaults to false.
+.sp
+Use of \fIauto_fast_armor = true\fP requires properly configured PKINIT and
+WELLKNOWN/ANONYMOUS principal defined on the KDC side. Consult KDC documentation
+for details.
+.TP
\fBv4_instance_convert\fP
This subsection allows the administrator to configure exceptions
to the \fBdefault_domain\fP mapping rule. It contains V4 instances
--
2.51.0

View file

@ -0,0 +1,40 @@
From ff580d9cf86202d45454a6b6f53accc22cb40b62 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Sun, 19 Oct 2025 18:14:29 +0300
Subject: [PATCH] bail if prompter is not specified but required
GSSAPI gss_init_sec_context() may trigger credential re-initialization
if the cred in ccache is expired. If automatic FAST armor is in use,
we'd request Anonymous PKINIT and use it as an armor and this will
enable seeing pre-authentication methods which require armor presence.
OTP is one of such methods and its use requires prompter to be set,
but GSSAPI cannot specify a prompter and thus we should fail any
pre-auth where a prompter wasn't passed.
PKINIT PKCS11 and SAM-2 preauth methods use KRB5_LIBOS_CANTREADPWD while PKINIT
and gic_pwd.c use EIO. Use EIO here because we technically attempt to read a
PIN rather than a password.
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
---
src/lib/krb5/krb/preauth_otp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/lib/krb5/krb/preauth_otp.c b/src/lib/krb5/krb/preauth_otp.c
index 07ffc15c2..48003da62 100644
--- a/src/lib/krb5/krb/preauth_otp.c
+++ b/src/lib/krb5/krb/preauth_otp.c
@@ -479,6 +479,9 @@ doprompt(krb5_context context, krb5_prompter_fct prompter, void *prompter_data,
krb5_error_code retval;
krb5_prompt_type prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
+ if (prompter == NULL)
+ return EIO;
+
if (prompttxt == NULL || out == NULL)
return EINVAL;
--
2.51.0

View file

@ -1,409 +0,0 @@
From 18d45e4b48c363f631b1acd7dac5902351bf1a0e Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 4 Dec 2018 15:22:55 -0500
Subject: [PATCH] Add dns_canonicalize_hostname=fallback support
Turn dns_canonicalize_hostname into a tristate variable, allowing the
value "fallback" as well as the true/false booleans. If it is set to
fallback, delay DNS canonicalization and attempt it only in
krb5_get_credentials() if the KDC responds that the requested server
principal name is unknown.
[ghudson@mit.edu: added TGS tests; refactored code; edited commit
message and documentation]
ticket: 8765 (new)
(cherry picked from commit 6c20cb1c89acaa03db897182a3b28d5f8f284907)
---
doc/admin/conf_files/krb5_conf.rst | 4 ++
src/include/k5-int.h | 8 ++-
src/include/k5-trace.h | 3 ++
src/lib/krb5/krb/get_creds.c | 79 ++++++++++++++++++++++++++----
src/lib/krb5/krb/init_ctx.c | 27 +++++++++-
src/lib/krb5/krb/t_copy_context.c | 2 +-
src/lib/krb5/os/os-proto.h | 4 ++
src/lib/krb5/os/sn2princ.c | 19 +++++--
src/tests/gcred.c | 5 +-
src/tests/t_sn2princ.py | 34 ++++++++++++-
10 files changed, 167 insertions(+), 18 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 7b4389f6b..e9f7e8c59 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -201,6 +201,10 @@ The libdefaults section may contain any of the following relations:
means that short hostnames will not be canonicalized to
fully-qualified hostnames. The default value is true.
+ If this option is set to ``fallback`` (new in release 1.18), DNS
+ canonicalization will only be performed the server hostname is not
+ found with the original name when requesting credentials.
+
**dns_lookup_kdc**
Indicate whether DNS SRV records should be used to locate the KDCs
and other servers for a realm, if they are not listed in the
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 255cee822..1e6a739e9 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -1159,6 +1159,12 @@ k5_plugin_register_dyn(krb5_context context, int interface_id,
void
k5_plugin_free_context(krb5_context context);
+enum dns_canonhost {
+ CANONHOST_FALSE = 0,
+ CANONHOST_TRUE = 1,
+ CANONHOST_FALLBACK = 2
+};
+
struct _kdb5_dal_handle; /* private, in kdb5.h */
typedef struct _kdb5_dal_handle kdb5_dal_handle;
struct _kdb_log_context;
@@ -1222,7 +1228,7 @@ struct _krb5_context {
krb5_boolean allow_weak_crypto;
krb5_boolean ignore_acceptor_hostname;
- krb5_boolean dns_canonicalize_hostname;
+ enum dns_canonhost dns_canonicalize_hostname;
krb5_trace_callback trace_callback;
void *trace_callback_data;
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
index 2aa379b76..f3ed6a45d 100644
--- a/src/include/k5-trace.h
+++ b/src/include/k5-trace.h
@@ -191,6 +191,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_FAST_REQUIRED(c) \
TRACE(c, "Using FAST due to KRB5_FAST_REQUIRED flag")
+#define TRACE_GET_CREDS_FALLBACK(c, hostname) \
+ TRACE(c, "Falling back to canonicalized server hostname {str}", hostname)
+
#define TRACE_GIC_PWD_CHANGED(c) \
TRACE(c, "Getting initial TGT with changed password")
#define TRACE_GIC_PWD_CHANGEPW(c, tries) \
diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c
index 69900adfa..0a04d68b9 100644
--- a/src/lib/krb5/krb/get_creds.c
+++ b/src/lib/krb5/krb/get_creds.c
@@ -39,6 +39,7 @@
#include "k5-int.h"
#include "int-proto.h"
+#include "os-proto.h"
#include "fast.h"
/*
@@ -1249,6 +1250,26 @@ krb5_tkt_creds_step(krb5_context context, krb5_tkt_creds_context ctx,
return EINVAL;
}
+static krb5_error_code
+try_get_creds(krb5_context context, krb5_flags options, krb5_ccache ccache,
+ krb5_creds *in_creds, krb5_creds *creds_out)
+{
+ krb5_error_code code;
+ krb5_tkt_creds_context ctx = NULL;
+
+ code = krb5_tkt_creds_init(context, ccache, in_creds, options, &ctx);
+ if (code)
+ goto cleanup;
+ code = krb5_tkt_creds_get(context, ctx);
+ if (code)
+ goto cleanup;
+ code = krb5_tkt_creds_get_creds(context, ctx, creds_out);
+
+cleanup:
+ krb5_tkt_creds_free(context, ctx);
+ return code;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_get_credentials(krb5_context context, krb5_flags options,
krb5_ccache ccache, krb5_creds *in_creds,
@@ -1256,7 +1277,10 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
{
krb5_error_code code;
krb5_creds *ncreds = NULL;
- krb5_tkt_creds_context ctx = NULL;
+ krb5_creds canon_creds, store_creds;
+ krb5_principal_data canon_server;
+ krb5_data canon_components[2];
+ char *hostname = NULL, *canon_hostname = NULL;
*out_creds = NULL;
@@ -1265,22 +1289,59 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
if (ncreds == NULL)
goto cleanup;
- /* Make and execute a krb5_tkt_creds context to get the credential. */
- code = krb5_tkt_creds_init(context, ccache, in_creds, options, &ctx);
- if (code != 0)
+ code = try_get_creds(context, options, ccache, in_creds, ncreds);
+ if (!code) {
+ *out_creds = ncreds;
+ return 0;
+ }
+
+ /* Possibly try again with the canonicalized hostname, if the server is
+ * host-based and we are configured for fallback canonicalization. */
+ if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
goto cleanup;
- code = krb5_tkt_creds_get(context, ctx);
- if (code != 0)
+ if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK)
goto cleanup;
- code = krb5_tkt_creds_get_creds(context, ctx, ncreds);
- if (code != 0)
+ if (in_creds->server->type != KRB5_NT_SRV_HST ||
+ in_creds->server->length != 2)
goto cleanup;
+ hostname = k5memdup0(in_creds->server->data[1].data,
+ in_creds->server->data[1].length, &code);
+ if (hostname == NULL)
+ goto cleanup;
+ code = k5_expand_hostname(context, hostname, TRUE, &canon_hostname);
+ if (code)
+ goto cleanup;
+
+ TRACE_GET_CREDS_FALLBACK(context, canon_hostname);
+
+ /* Make shallow copies of in_creds and its server to alter the hostname. */
+ canon_components[0] = in_creds->server->data[0];
+ canon_components[1] = string2data(canon_hostname);
+ canon_server = *in_creds->server;
+ canon_server.data = canon_components;
+ canon_creds = *in_creds;
+ canon_creds.server = &canon_server;
+
+ code = try_get_creds(context, options | KRB5_GC_NO_STORE, ccache,
+ &canon_creds, ncreds);
+ if (code)
+ goto cleanup;
+
+ if (!(options & KRB5_GC_NO_STORE)) {
+ /* Store the creds under the originally requested server name. The
+ * ccache layer will also store them under the ticket server name. */
+ store_creds = *ncreds;
+ store_creds.server = in_creds->server;
+ (void)krb5_cc_store_cred(context, ccache, &store_creds);
+ }
+
*out_creds = ncreds;
ncreds = NULL;
cleanup:
+ free(hostname);
+ free(canon_hostname);
krb5_free_creds(context, ncreds);
- krb5_tkt_creds_free(context, ctx);
return code;
}
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 947e50400..d263d5cc5 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -101,6 +101,30 @@ get_boolean(krb5_context ctx, const char *name, int def_val, int *boolean_out)
return retval;
}
+static krb5_error_code
+get_tristate(krb5_context ctx, const char *name, const char *third_option,
+ int third_option_val, int def_val, int *val_out)
+{
+ krb5_error_code retval;
+ char *str;
+ int match;
+
+ retval = profile_get_boolean(ctx->profile, KRB5_CONF_LIBDEFAULTS, name,
+ NULL, def_val, val_out);
+ if (retval != PROF_BAD_BOOLEAN)
+ return retval;
+ retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS, name,
+ NULL, NULL, &str);
+ if (retval)
+ return retval;
+ match = (strcasecmp(third_option, str) == 0);
+ free(str);
+ if (!match)
+ return EINVAL;
+ *val_out = third_option_val;
+ return 0;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_init_context(krb5_context *context)
{
@@ -213,7 +237,8 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
goto cleanup;
ctx->ignore_acceptor_hostname = tmp;
- retval = get_boolean(ctx, KRB5_CONF_DNS_CANONICALIZE_HOSTNAME, 1, &tmp);
+ retval = get_tristate(ctx, KRB5_CONF_DNS_CANONICALIZE_HOSTNAME, "fallback",
+ CANONHOST_FALLBACK, 1, &tmp);
if (retval)
goto cleanup;
ctx->dns_canonicalize_hostname = tmp;
diff --git a/src/lib/krb5/krb/t_copy_context.c b/src/lib/krb5/krb/t_copy_context.c
index fa810be8a..a6e48cd25 100644
--- a/src/lib/krb5/krb/t_copy_context.c
+++ b/src/lib/krb5/krb/t_copy_context.c
@@ -145,7 +145,7 @@ main(int argc, char **argv)
ctx->udp_pref_limit = 2345;
ctx->use_conf_ktypes = TRUE;
ctx->ignore_acceptor_hostname = TRUE;
- ctx->dns_canonicalize_hostname = FALSE;
+ ctx->dns_canonicalize_hostname = CANONHOST_FALSE;
free(ctx->plugin_base_dir);
check((ctx->plugin_base_dir = strdup("/a/b/c/d")) != NULL);
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
index 634e82d70..066d30221 100644
--- a/src/lib/krb5/os/os-proto.h
+++ b/src/lib/krb5/os/os-proto.h
@@ -83,6 +83,10 @@ struct sendto_callback_info {
void *data;
};
+krb5_error_code k5_expand_hostname(krb5_context context, const char *host,
+ krb5_boolean is_fallback,
+ char **canonhost_out);
+
krb5_error_code k5_locate_server(krb5_context, const krb5_data *realm,
struct serverlist *serverlist,
enum locate_service_type svc,
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c
index 5932fd9b3..98d2600aa 100644
--- a/src/lib/krb5/os/sn2princ.c
+++ b/src/lib/krb5/os/sn2princ.c
@@ -53,19 +53,23 @@ use_reverse_dns(krb5_context context)
return value;
}
-krb5_error_code KRB5_CALLCONV
-krb5_expand_hostname(krb5_context context, const char *host,
- char **canonhost_out)
+krb5_error_code
+k5_expand_hostname(krb5_context context, const char *host,
+ krb5_boolean is_fallback, char **canonhost_out)
{
struct addrinfo *ai = NULL, hint;
char namebuf[NI_MAXHOST], *copy, *p;
int err;
const char *canonhost;
+ krb5_boolean use_dns;
*canonhost_out = NULL;
canonhost = host;
- if (context->dns_canonicalize_hostname) {
+ use_dns = (context->dns_canonicalize_hostname == CANONHOST_TRUE ||
+ (is_fallback &&
+ context->dns_canonicalize_hostname == CANONHOST_FALLBACK));
+ if (use_dns) {
/* Try a forward lookup of the hostname. */
memset(&hint, 0, sizeof(hint));
hint.ai_flags = AI_CANONNAME;
@@ -112,6 +116,13 @@ cleanup:
return (*canonhost_out == NULL) ? ENOMEM : 0;
}
+krb5_error_code KRB5_CALLCONV
+krb5_expand_hostname(krb5_context context, const char *host,
+ char **canonhost_out)
+{
+ return k5_expand_hostname(context, host, FALSE, canonhost_out);
+}
+
/* If hostname appears to have a :port or :instance trailer (used in MSSQLSvc
* principals), return a pointer to the separator. Otherwise return NULL. */
static const char *
diff --git a/src/tests/gcred.c b/src/tests/gcred.c
index b14e4fc9a..cac524c51 100644
--- a/src/tests/gcred.c
+++ b/src/tests/gcred.c
@@ -66,6 +66,7 @@ main(int argc, char **argv)
krb5_principal client, server;
krb5_ccache ccache;
krb5_creds in_creds, *creds;
+ krb5_ticket *ticket;
krb5_flags options = 0;
char *name;
int c;
@@ -102,9 +103,11 @@ main(int argc, char **argv)
in_creds.client = client;
in_creds.server = server;
check(krb5_get_credentials(ctx, options, ccache, &in_creds, &creds));
- check(krb5_unparse_name(ctx, creds->server, &name));
+ check(krb5_decode_ticket(&creds->ticket, &ticket));
+ check(krb5_unparse_name(ctx, ticket->server, &name));
printf("%s\n", name);
+ krb5_free_ticket(ctx, ticket);
krb5_free_unparsed_name(ctx, name);
krb5_free_creds(ctx, creds);
krb5_free_principal(ctx, client);
diff --git a/src/tests/t_sn2princ.py b/src/tests/t_sn2princ.py
index 1ffda51f4..fe435a2d5 100755
--- a/src/tests/t_sn2princ.py
+++ b/src/tests/t_sn2princ.py
@@ -7,10 +7,15 @@ conf = {'domain_realm': {'kerberos.org': 'R1',
'mit.edu': 'R3'}}
no_rdns_conf = {'libdefaults': {'rdns': 'false'}}
no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}}
+fallback_canon_conf = {'libdefaults':
+ {'rdns': 'false',
+ 'dns_canonicalize_hostname': 'fallback'}}
-realm = K5Realm(create_kdb=False, krb5_conf=conf)
+realm = K5Realm(realm='R1', create_host=False, krb5_conf=conf)
no_rdns = realm.special_env('no_rdns', False, krb5_conf=no_rdns_conf)
no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf)
+fallback_canon = realm.special_env('fallback_canon', False,
+ krb5_conf=fallback_canon_conf)
def testbase(host, nametype, princhost, princrealm, env=None):
# Run the sn2princ harness with a specified host and name type and
@@ -37,6 +42,10 @@ def testu(host, princhost, princrealm):
# Test with the unknown name type.
testbase(host, 'unknown', princhost, princrealm)
+def testfc(host, princhost, princrealm):
+ # Test with the host-based name type with canonicalization fallback.
+ testbase(host, 'srv-hst', princhost, princrealm, env=fallback_canon)
+
# With the unknown principal type, we do not canonicalize or downcase,
# but we do remove a trailing period and look up the realm.
mark('unknown type')
@@ -71,6 +80,29 @@ if offline:
oname = 'ptr-mismatch.kerberos.org'
fname = 'www.kerberos.org'
+# Test fallback canonicalization krb5_sname_to_principal() results
+# (same as dns_canonicalize_hostname=false).
+mark('dns_canonicalize_host=fallback')
+testfc(oname, oname, 'R1')
+
+# Test fallback canonicalization in krb5_get_credentials().
+oprinc = 'host/' + oname
+fprinc = 'host/' + fname
+shutil.copy(realm.ccache, realm.ccache + '.save')
+realm.addprinc(fprinc)
+# oprinc doesn't exist, so we get the canonicalized fprinc as a fallback.
+msgs = ('Falling back to canonicalized server hostname ' + fname,)
+realm.run(['./gcred', 'srv-hst', oprinc], env=fallback_canon,
+ expected_msg=fprinc, expected_trace=msgs)
+realm.addprinc(oprinc)
+# oprinc now exists, but we still get the fprinc ticket from the cache.
+realm.run(['./gcred', 'srv-hst', oprinc], env=fallback_canon,
+ expected_msg=fprinc)
+# Without the cached result, we sould get oprinc in preference to fprinc.
+os.rename(realm.ccache + '.save', realm.ccache)
+realm.run(['./gcred', 'srv-hst', oprinc], env=fallback_canon,
+ expected_msg=oprinc)
+
# Verify forward resolution before testing for it.
try:
ai = socket.getaddrinfo(oname, None, 0, 0, 0, socket.AI_CANONNAME)

View file

@ -1,183 +0,0 @@
From 461e3a4d81c73db832401592d417489dc0151a2c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 15 Jan 2019 16:16:57 -0500
Subject: [PATCH] Add function and enctype flag for deprecations
krb5int_c_deprecated_enctype() checks for the ETYPE_DEPRECATED flag on
enctypes. All ENCTYPE_WEAK enctypes are currently deprecated; not all
deprecated enctypes are considered weak. Deprecations follow RFC 6649
and RFC 8429.
(cherry picked from commit 484a6e7712f9b66e782b2520f07b0883889e116f)
---
src/include/k5-int.h | 1 +
src/lib/crypto/krb/crypto_int.h | 9 ++++++++-
src/lib/crypto/krb/enctype_util.c | 7 +++++++
src/lib/crypto/krb/etypes.c | 19 ++++++++++---------
src/lib/crypto/libk5crypto.exports | 1 +
src/lib/krb5_32.def | 3 +++
6 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 8f9329c59..255cee822 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2077,6 +2077,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **);
krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype);
krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype);
+krb5_boolean KRB5_CALLCONV krb5int_c_deprecated_enctype(krb5_enctype);
krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out);
krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *,
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index e5099291e..6c1c77cac 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -114,7 +114,14 @@ struct krb5_keytypes {
unsigned int ssf;
};
-#define ETYPE_WEAK 1
+/*
+ * "Weak" means the enctype is believed to be vulnerable to practical attacks,
+ * and will be disabled unless allow_weak_crypto is set to true. "Deprecated"
+ * means the enctype has been deprecated by the IETF, and affects display and
+ * logging.
+ */
+#define ETYPE_WEAK (1 << 0)
+#define ETYPE_DEPRECATED (1 << 1)
extern const struct krb5_keytypes krb5int_enctypes_list[];
extern const int krb5int_enctypes_length;
diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c
index b1b40e7ec..e394f4e19 100644
--- a/src/lib/crypto/krb/enctype_util.c
+++ b/src/lib/crypto/krb/enctype_util.c
@@ -51,6 +51,13 @@ krb5int_c_weak_enctype(krb5_enctype etype)
return (ktp != NULL && (ktp->flags & ETYPE_WEAK) != 0);
}
+krb5_boolean KRB5_CALLCONV
+krb5int_c_deprecated_enctype(krb5_enctype etype)
+{
+ const struct krb5_keytypes *ktp = find_enctype(etype);
+ return ktp != NULL && (ktp->flags & ETYPE_DEPRECATED) != 0;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2,
krb5_boolean *similar)
diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c
index 53d4a5c79..8f44c37e7 100644
--- a/src/lib/crypto/krb/etypes.c
+++ b/src/lib/crypto/krb/etypes.c
@@ -33,6 +33,7 @@
that the keytypes are all near each other. I'd rather not make
that assumption. */
+/* Deprecations come from RFC 6649 and RFC 8249. */
const struct krb5_keytypes krb5int_enctypes_list[] = {
{ ENCTYPE_DES_CBC_CRC,
"des-cbc-crc", { 0 }, "DES cbc mode with CRC-32",
@@ -42,7 +43,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES_CBC_MD4,
"des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4",
&krb5int_enc_des, &krb5int_hash_md4,
@@ -51,7 +52,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD4_DES,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES_CBC_MD5,
"des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5",
&krb5int_enc_des, &krb5int_hash_md5,
@@ -60,7 +61,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES_CBC_RAW,
"des-cbc-raw", { 0 }, "DES cbc mode raw",
&krb5int_enc_des, NULL,
@@ -69,7 +70,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
0,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES3_CBC_RAW,
"des3-cbc-raw", { 0 }, "Triple DES cbc mode raw",
&krb5int_enc_des3, NULL,
@@ -78,7 +79,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
NULL, /*PRF*/
0,
- ETYPE_WEAK, 112 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 112 },
{ ENCTYPE_DES3_CBC_SHA1,
"des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" },
@@ -89,7 +90,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_DES3,
- 0 /*flags*/, 112 },
+ ETYPE_DEPRECATED, 112 },
{ ENCTYPE_DES_HMAC_SHA1,
"des-hmac-sha1", { 0 }, "DES with HMAC/sha1",
@@ -99,7 +100,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des,
NULL, /*PRF*/
0,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
/* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we
* consider its strength degraded and assign it an SSF value of 64. */
@@ -113,7 +114,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- 0 /*flags*/, 64 },
+ ETYPE_DEPRECATED, 64 },
{ ENCTYPE_ARCFOUR_HMAC_EXP,
"arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" },
"Exportable ArcFour with HMAC/md5",
@@ -124,7 +125,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- ETYPE_WEAK, 40
+ ETYPE_WEAK | ETYPE_DEPRECATED, 40
},
{ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 82eb5f30c..90afdf5f7 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -109,3 +109,4 @@ k5_allow_weak_pbkdf2iter
krb5_c_prfplus
krb5_c_derive_prfplus
k5_enctype_to_ssf
+krb5int_c_deprecated_enctype
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index c35022931..e6a487593 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -487,3 +487,6 @@ EXPORTS
encode_krb5_pa_spake @444 ; PRIVATE
decode_krb5_pa_spake @445 ; PRIVATE
k5_free_pa_spake @446 ; PRIVATE
+
+; new in 1.18
+ krb5int_c_deprecated_enctype @450 ; PRIVATE

View file

@ -1,294 +0,0 @@
From 306c0260dca7809c90dfa9e8889a6bd2401cee84 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 22 Nov 2018 00:27:35 -0500
Subject: [PATCH] Add tests for KCM ccache type
Using a trivial Python implementation of a KCM server, run the
t_ccache.py tests against the KCM ccache type.
(cherry picked from commit f0bcb86131e385b2603ccf0f3c7d65aa3891b220)
---
src/tests/kcmserver.py | 246 +++++++++++++++++++++++++++++++++++++++++
src/tests/t_ccache.py | 9 +-
2 files changed, 254 insertions(+), 1 deletion(-)
create mode 100644 src/tests/kcmserver.py
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
new file mode 100644
index 000000000..57432e5a7
--- /dev/null
+++ b/src/tests/kcmserver.py
@@ -0,0 +1,246 @@
+# This is a simple KCM test server, used to exercise the KCM ccache
+# client code. It will generally throw an uncaught exception if the
+# client sends anything unexpected, so is unsuitable for production.
+# (It also imposes no namespace or access constraints, and blocks
+# while reading requests and writing responses.)
+
+# This code knows nothing about how to marshal and unmarshal principal
+# names and credentials as is required in the KCM protocol; instead,
+# it just remembers the marshalled forms and replays them to the
+# client when asked. This works because marshalled creds and
+# principal names are always the last part of marshalled request
+# arguments, and because we don't need to implement remove_cred (which
+# would need to know how to match a cred tag against previously stored
+# credentials).
+
+# The following code is useful for debugging if anything appears to be
+# going wrong in the server, since daemon output is generally not
+# visible in Python test scripts.
+#
+# import sys, traceback
+# def ehook(etype, value, tb):
+# with open('/tmp/exception', 'w') as f:
+# traceback.print_exception(etype, value, tb, file=f)
+# sys.excepthook = ehook
+
+import select
+import socket
+import struct
+import sys
+
+caches = {}
+cache_uuidmap = {}
+defname = b'default'
+next_unique = 1
+next_uuid = 1
+
+class KCMOpcodes(object):
+ GEN_NEW = 3
+ INITIALIZE = 4
+ DESTROY = 5
+ STORE = 6
+ GET_PRINCIPAL = 8
+ GET_CRED_UUID_LIST = 9
+ GET_CRED_BY_UUID = 10
+ REMOVE_CRED = 11
+ GET_CACHE_UUID_LIST = 18
+ GET_CACHE_BY_UUID = 19
+ GET_DEFAULT_CACHE = 20
+ SET_DEFAULT_CACHE = 21
+ GET_KDC_OFFSET = 22
+ SET_KDC_OFFSET = 23
+
+
+class KRB5Errors(object):
+ KRB5_CC_END = -1765328242
+ KRB5_CC_NOSUPP = -1765328137
+ KRB5_FCC_NOFILE = -1765328189
+
+
+def make_uuid():
+ global next_uuid
+ uuid = bytes(12) + struct.pack('>L', next_uuid)
+ next_uuid = next_uuid + 1
+ return uuid
+
+
+class Cache(object):
+ def __init__(self, name):
+ self.name = name
+ self.princ = None
+ self.uuid = make_uuid()
+ self.cred_uuids = []
+ self.creds = {}
+ self.time_offset = 0
+
+
+def get_cache(name):
+ if name in caches:
+ return caches[name]
+ cache = Cache(name)
+ caches[name] = cache
+ cache_uuidmap[cache.uuid] = cache
+ return cache
+
+
+def unmarshal_name(argbytes):
+ offset = argbytes.find(b'\0')
+ return argbytes[0:offset], argbytes[offset+1:]
+
+
+def op_gen_new(argbytes):
+ # Does not actually check for uniqueness.
+ global next_unique
+ name = b'unique' + str(next_unique).encode('ascii')
+ next_unique += 1
+ return 0, name + b'\0'
+
+
+def op_initialize(argbytes):
+ name, princ = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ cache.princ = princ
+ cache.cred_uuids = []
+ cache.creds = {}
+ cache.time_offset = 0
+ return 0, b''
+
+
+def op_destroy(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ del cache_uuidmap[cache.uuid]
+ del caches[name]
+ return 0, b''
+
+
+def op_store(argbytes):
+ name, cred = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ uuid = make_uuid()
+ cache.creds[uuid] = cred
+ cache.cred_uuids.append(uuid)
+ return 0, b''
+
+
+def op_get_principal(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ if cache.princ is None:
+ return KRB5Errors.KRB5_FCC_NOFILE, b''
+ return 0, cache.princ + b'\0'
+
+
+def op_get_cred_uuid_list(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ return 0, b''.join(cache.cred_uuids)
+
+
+def op_get_cred_by_uuid(argbytes):
+ name, uuid = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ if uuid not in cache.creds:
+ return KRB5Errors.KRB5_CC_END, b''
+ return 0, cache.creds[uuid]
+
+
+def op_remove_cred(argbytes):
+ return KRB5Errors.KRB5_CC_NOSUPP, b''
+
+
+def op_get_cache_uuid_list(argbytes):
+ return 0, b''.join(cache_uuidmap.keys())
+
+
+def op_get_cache_by_uuid(argbytes):
+ uuid = argbytes
+ if uuid not in cache_uuidmap:
+ return KRB5Errors.KRB5_CC_END, b''
+ return 0, cache_uuidmap[uuid].name + b'\0'
+
+
+def op_get_default_cache(argbytes):
+ return 0, defname + b'\0'
+
+
+def op_set_default_cache(argbytes):
+ global defname
+ defname, rest = unmarshal_name(argbytes)
+ return 0, b''
+
+
+def op_get_kdc_offset(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ return 0, struct.pack('>l', cache.time_offset)
+
+
+def op_set_kdc_offset(argbytes):
+ name, obytes = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ cache.time_offset, = struct.unpack('>l', obytes)
+ return 0, b''
+
+
+ophandlers = {
+ KCMOpcodes.GEN_NEW : op_gen_new,
+ KCMOpcodes.INITIALIZE : op_initialize,
+ KCMOpcodes.DESTROY : op_destroy,
+ KCMOpcodes.STORE : op_store,
+ KCMOpcodes.GET_PRINCIPAL : op_get_principal,
+ KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list,
+ KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid,
+ KCMOpcodes.REMOVE_CRED : op_remove_cred,
+ KCMOpcodes.GET_CACHE_UUID_LIST : op_get_cache_uuid_list,
+ KCMOpcodes.GET_CACHE_BY_UUID : op_get_cache_by_uuid,
+ KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache,
+ KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache,
+ KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset,
+ KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset
+}
+
+# Read and respond to a request from the socket s.
+def service_request(s):
+ lenbytes = b''
+ while len(lenbytes) < 4:
+ lenbytes += s.recv(4 - len(lenbytes))
+ if lenbytes == b'':
+ return False
+
+ reqlen, = struct.unpack('>L', lenbytes)
+ req = b''
+ while len(req) < reqlen:
+ req += s.recv(reqlen - len(req))
+
+ majver, minver, op = struct.unpack('>BBH', req[:4])
+ argbytes = req[4:]
+ code, payload = ophandlers[op](argbytes)
+
+ # The KCM response is the code (4 bytes) and the response payload.
+ # The Heimdal IPC response is the length of the KCM response (4
+ # bytes), a status code which is essentially always 0 (4 bytes),
+ # and the KCM response.
+ kcm_response = struct.pack('>l', code) + payload
+ hipc_response = struct.pack('>LL', len(kcm_response), 0) + kcm_response
+ s.sendall(hipc_response)
+ return True
+
+
+server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+server.bind(sys.argv[1])
+server.listen(5)
+select_input = [server,]
+sys.stderr.write('starting...\n')
+sys.stderr.flush()
+
+while True:
+ iready, oready, xready = select.select(select_input, [], [])
+ for s in iready:
+ if s == server:
+ client, addr = server.accept()
+ select_input.append(client)
+ else:
+ if not service_request(s):
+ select_input.remove(s)
+ s.close()
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
index fcf1a611e..66804afa5 100755
--- a/src/tests/t_ccache.py
+++ b/src/tests/t_ccache.py
@@ -22,7 +22,10 @@
from k5test import *
-realm = K5Realm(create_host=False)
+kcm_socket_path = os.path.join(os.getcwd(), 'testdir', 'kcm')
+conf = {'libdefaults': {'kcm_socket': kcm_socket_path,
+ 'kcm_mach_service': '-'}}
+realm = K5Realm(create_host=False, krb5_conf=conf)
keyctl = which('keyctl')
out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1)
@@ -122,6 +125,10 @@ def collection_test(realm, ccname):
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
+kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
+realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
+ 'starting...')
+collection_test(realm, 'KCM:')
if test_keyring:
def cleanup_keyring(anchor, name):
out = realm.run(['keyctl', 'list', anchor])

View file

@ -1,94 +0,0 @@
From 3dd99db324de1492444aab3e5468aea5f1767c6d Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 30 Dec 2018 16:40:28 -0500
Subject: [PATCH] Address some optimized-out memset() calls
Ilja Van Sprundel reported a list of memset() calls which gcc
optimizes out. In krb_auth_su.c, use zap() to clear the password, and
remove two memset() calls when there is no password to clear. In
iakerb.c, remove an unnecessary memset() before setting the only two
fields of the IAKERB header structure. In svr_principal.c, use
krb5_free_key_keyblock_contents() instead of hand-freeing key data.
In asn1_k_encode.c, remove an unnecessary memset() of the kdc_req_hack
shell before returning.
(cherry picked from commit 1057b0befec1f1c0e9d4da5521a58496e2dc0997)
---
src/clients/ksu/krb_auth_su.c | 4 +---
src/lib/gssapi/krb5/iakerb.c | 1 -
src/lib/kadm5/srv/svr_principal.c | 10 ++--------
src/lib/krb5/asn.1/asn1_k_encode.c | 1 -
4 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c
index 7af48195c..e39685fff 100644
--- a/src/clients/ksu/krb_auth_su.c
+++ b/src/clients/ksu/krb_auth_su.c
@@ -183,21 +183,19 @@ krb5_boolean ksu_get_tgt_via_passwd(context, client, options, zero_password,
if (code ) {
com_err(prog_name, code, _("while reading password for '%s'\n"),
client_name);
- memset(password, 0, sizeof(password));
return (FALSE);
}
if ( pwsize == 0) {
fprintf(stderr, _("No password given\n"));
*zero_password = TRUE;
- memset(password, 0, sizeof(password));
return (FALSE);
}
code = krb5_get_init_creds_password(context, &creds, client, password,
krb5_prompter_posix, NULL, 0, NULL,
options);
- memset(password, 0, sizeof(password));
+ zap(password, sizeof(password));
if (code) {
diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
index bb1072fe4..47c161ec9 100644
--- a/src/lib/gssapi/krb5/iakerb.c
+++ b/src/lib/gssapi/krb5/iakerb.c
@@ -262,7 +262,6 @@ iakerb_make_token(iakerb_ctx_id_t ctx,
/*
* Assemble the IAKERB-HEADER from the realm and cookie
*/
- memset(&iah, 0, sizeof(iah));
iah.target_realm = *realm;
iah.cookie = cookie;
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 21c53ece1..9ab2c5a74 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -2093,14 +2093,8 @@ static int decrypt_key_data(krb5_context context,
ret = krb5_dbe_decrypt_key_data(context, NULL, &key_data[i], &keys[i],
NULL);
if (ret) {
- for (; i >= 0; i--) {
- if (keys[i].contents) {
- memset (keys[i].contents, 0, keys[i].length);
- free( keys[i].contents );
- }
- }
-
- memset(keys, 0, n_key_data*sizeof(krb5_keyblock));
+ for (; i >= 0; i--)
+ krb5_free_keyblock_contents(context, &keys[i]);
free(keys);
return ret;
}
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 65c84be2f..81a34bac9 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -528,7 +528,6 @@ decode_kdc_req_body(const taginfo *t, const uint8_t *asn1, size_t len,
if (ret) {
free_kdc_req_body(b);
free(h.server_realm.data);
- memset(&h, 0, sizeof(h));
return ret;
}
b->server->realm = h.server_realm;

View file

@ -1,55 +0,0 @@
From 26dc343d4e59ef0f80e1ecca09b40f120b79d809 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 3 Jan 2019 17:19:32 +0100
Subject: [PATCH] Avoid allocating a register in zap() assembly
See https://bugs.llvm.org/show_bug.cgi?id=15495
Also add explicit_bzero() (glibc, FreeBSD) and explicit_memset()
(NetBSD) as alternatives.
[ghudson@mit.edu: added explicit_bzero() and explicit_memset()]
(cherry picked from commit 7391e8b541061d0f584193b4a53365b64364b0e8)
---
src/configure.in | 2 +-
src/include/k5-platform.h | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/configure.in b/src/configure.in
index 93aec682e..7c309a26b 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -421,7 +421,7 @@ AC_PROG_LEX
AC_C_CONST
AC_HEADER_DIRENT
AC_FUNC_STRERROR_R
-AC_CHECK_FUNCS(strdup setvbuf seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror timegm)
+AC_CHECK_FUNCS(strdup setvbuf seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror timegm explicit_bzero explicit_memset)
AC_CHECK_FUNC(mkstemp,
[MKSTEMP_ST_OBJ=
diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h
index 997b655e1..1fcd68e8c 100644
--- a/src/include/k5-platform.h
+++ b/src/include/k5-platform.h
@@ -1023,6 +1023,10 @@ static inline void zap(void *ptr, size_t len)
if (len > 0)
memset_s(ptr, len, 0, len);
}
+#elif defined(HAVE_EXPLICIT_BZERO)
+# define zap(ptr, len) explicit_bzero(ptr, len)
+#elif defined(HAVE_EXPLICIT_MEMSET)
+# define zap(ptr, len) explicit_memset(ptr, 0, len)
#elif defined(__GNUC__) || defined(__clang__)
/*
* Use an asm statement which declares a memory clobber to force the memset to
@@ -1032,7 +1036,7 @@ static inline void zap(void *ptr, size_t len)
{
if (len > 0)
memset(ptr, 0, len);
- __asm__ __volatile__("" : : "r" (ptr) : "memory");
+ __asm__ __volatile__("" : : "g" (ptr) : "memory");
}
#else
/*

View file

@ -1,88 +0,0 @@
From 27bc3f5a90533af509202d851374ea40f3982864 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 22 Apr 2019 14:26:42 -0400
Subject: [PATCH] Check more errors in OpenSSL crypto backend
In krb5int_hmac_keyblock() and krb5int_pbkdf2_hmac(), check for errors
from previously unchecked OpenSSL function calls and return
KRB5_CRYPTO_INTERNAL if they fail.
HMAC_Init() is deprecated in OpenSSL 1.0 and later; as we are
modifying the call to check for errors, call HMAC_Init_ex() instead.
ticket: 8799 (new)
(cherry picked from commit 2298e5c2ff1122bcaff715129f5b746e77c3f42a)
---
src/lib/crypto/openssl/hmac.c | 18 +++++++++---------
src/lib/crypto/openssl/pbkdf2.c | 9 +++++----
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index d94d9ac94..769a50c00 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -121,7 +121,7 @@ krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
const krb5_crypto_iov *data, size_t num_data,
krb5_data *output)
{
- unsigned int i = 0, md_len = 0;
+ unsigned int i = 0, md_len = 0, ok;
unsigned char md[EVP_MAX_MD_SIZE];
HMAC_CTX *ctx;
size_t hashsize, blocksize;
@@ -141,22 +141,22 @@ krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
if (ctx == NULL)
return ENOMEM;
- HMAC_Init(ctx, keyblock->contents, keyblock->length, map_digest(hash));
- for (i = 0; i < num_data; i++) {
+ ok = HMAC_Init_ex(ctx, keyblock->contents, keyblock->length,
+ map_digest(hash), NULL);
+ for (i = 0; ok && i < num_data; i++) {
const krb5_crypto_iov *iov = &data[i];
if (SIGN_IOV(iov))
- HMAC_Update(ctx, (uint8_t *)iov->data.data, iov->data.length);
+ ok = HMAC_Update(ctx, (uint8_t *)iov->data.data, iov->data.length);
}
- HMAC_Final(ctx, md, &md_len);
- if ( md_len <= output->length) {
+ if (ok)
+ ok = HMAC_Final(ctx, md, &md_len);
+ if (ok && md_len <= output->length) {
output->length = md_len;
memcpy(output->data, md, output->length);
}
HMAC_CTX_free(ctx);
- return 0;
-
-
+ return ok ? 0 : KRB5_CRYPTO_INTERNAL;
}
krb5_error_code
diff --git a/src/lib/crypto/openssl/pbkdf2.c b/src/lib/crypto/openssl/pbkdf2.c
index 00c2116fc..732ec6405 100644
--- a/src/lib/crypto/openssl/pbkdf2.c
+++ b/src/lib/crypto/openssl/pbkdf2.c
@@ -35,6 +35,7 @@ krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash,
const krb5_data *pass, const krb5_data *salt)
{
const EVP_MD *md = NULL;
+ int ok;
/* Get the message digest handle corresponding to the hash. */
if (hash == &krb5int_hash_sha1)
@@ -46,8 +47,8 @@ krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash,
if (md == NULL)
return KRB5_CRYPTO_INTERNAL;
- PKCS5_PBKDF2_HMAC(pass->data, pass->length, (unsigned char *)salt->data,
- salt->length, count, md, out->length,
- (unsigned char *)out->data);
- return 0;
+ ok = PKCS5_PBKDF2_HMAC(pass->data, pass->length,
+ (unsigned char *)salt->data, salt->length, count,
+ md, out->length, (unsigned char *)out->data);
+ return ok ? 0 : KRB5_CRYPTO_INTERNAL;
}

View file

@ -1,31 +0,0 @@
From 18dd4d5c622238d1607671198cf2b2ddec9abda5 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 2 Apr 2019 14:18:57 -0400
Subject: [PATCH] Clarify header comment for krb5_cc_start_seq_get()
Previously this comment seemed to suggest that applications needed to
block all other access to the ccache (including by other processes)
during iteration.
(cherry picked from commit f4f51a25dd38601357e2f64b17b51eb23f45a53e)
---
src/include/krb5/krb5.hin | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 3ff86d7ff..346e796a5 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -2491,8 +2491,10 @@ krb5_cc_get_principal(krb5_context context, krb5_ccache cache,
*
* krb5_cc_end_seq_get() must be called to complete the retrieve operation.
*
- * @note If @a cache is modified between the time of the call to this function
- * and the time of the final krb5_cc_end_seq_get(), the results are undefined.
+ * @note If the cache represented by @a cache is modified between the time of
+ * the call to this function and the time of the final krb5_cc_end_seq_get(),
+ * these changes may not be reflected in the results of krb5_cc_next_cred()
+ * calls.
*
* @retval 0 Success; otherwise - Kerberos error codes
*/

View file

@ -1,484 +0,0 @@
From 297ad5039231e655eaae7c142991326fd863e70a Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 15 Nov 2018 13:40:43 -0500
Subject: [PATCH] Clear forwardable flag instead of denying request
If the client requests a forwardable or proxiable ticket and the
option cannot be honored by policy, issue a non-forwardable or
non-proxiable ticket rather than denying the request.
Add a test script for testing KDC request options and populate it with
tests for the forwardable and proxiable flags.
ticket: 7871
(cherry picked from commit 08e948cce2c79a3604066fcf7a64fc527456f83d)
---
src/kdc/do_as_req.c | 19 ++------
src/kdc/do_tgs_req.c | 56 ++++-----------------
src/kdc/kdc_util.c | 82 ++++++++++++++++++-------------
src/kdc/kdc_util.h | 9 ++--
src/kdc/tgs_policy.c | 8 +--
src/tests/Makefile.in | 1 +
src/tests/gcred.c | 28 ++++++++---
src/tests/t_kdcoptions.py | 100 ++++++++++++++++++++++++++++++++++++++
8 files changed, 189 insertions(+), 114 deletions(-)
create mode 100644 src/tests/t_kdcoptions.py
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 588c1375a..8a96c12a9 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -192,13 +192,6 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
au_state->stage = ENCR_REP;
- if ((errcode = validate_forwardable(state->request, *state->client,
- *state->server, state->kdc_time,
- &state->status))) {
- errcode += ERROR_TABLE_BASE_krb5;
- goto egress;
- }
-
errcode = check_indicators(kdc_context, state->server,
state->auth_indicators);
if (errcode) {
@@ -708,12 +701,11 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
}
/* Copy options that request the corresponding ticket flags. */
- state->enc_tkt_reply.flags = OPTS2FLAGS(state->request->kdc_options);
+ state->enc_tkt_reply.flags = get_ticket_flags(state->request->kdc_options,
+ state->client, state->server,
+ NULL);
state->enc_tkt_reply.times.authtime = state->authtime;
- setflag(state->enc_tkt_reply.flags, TKT_FLG_INITIAL);
- setflag(state->enc_tkt_reply.flags, TKT_FLG_ENC_PA_REP);
-
/*
* It should be noted that local policy may affect the
* processing of any of these flags. For example, some
@@ -732,10 +724,9 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
state->enc_tkt_reply.transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
state->enc_tkt_reply.transited.tr_contents = empty_string;
- if (isflagset(state->request->kdc_options, KDC_OPT_POSTDATED)) {
- setflag(state->enc_tkt_reply.flags, TKT_FLG_INVALID);
+ if (isflagset(state->request->kdc_options, KDC_OPT_POSTDATED))
state->enc_tkt_reply.times.starttime = state->request->from;
- } else
+ else
state->enc_tkt_reply.times.starttime = state->kdc_time;
kdc_get_ticket_endtime(kdc_active_realm,
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 587342a6c..1da099318 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -378,15 +378,16 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
else
ticket_reply.server = request->server; /* XXX careful for realm... */
- enc_tkt_reply.flags = OPTS2FLAGS(request->kdc_options);
- enc_tkt_reply.flags |= COPY_TKT_FLAGS(header_enc_tkt->flags);
+ enc_tkt_reply.flags = get_ticket_flags(request->kdc_options, client,
+ server, header_enc_tkt);
enc_tkt_reply.times.starttime = 0;
- if (isflagset(server->attributes, KRB5_KDB_OK_AS_DELEGATE))
- setflag(enc_tkt_reply.flags, TKT_FLG_OK_AS_DELEGATE);
-
- /* Indicate support for encrypted padata (RFC 6806). */
- setflag(enc_tkt_reply.flags, TKT_FLG_ENC_PA_REP);
+ /* OK_TO_AUTH_AS_DELEGATE must be set on the service requesting S4U2Self
+ * for forwardable tickets to be issued. */
+ if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION) &&
+ !is_referral &&
+ !isflagset(server->attributes, KRB5_KDB_OK_TO_AUTH_AS_DELEGATE))
+ clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
/* don't use new addresses unless forwarded, see below */
@@ -401,37 +402,6 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
* realms may refuse to issue renewable tickets
*/
- if (isflagset(request->kdc_options, KDC_OPT_FORWARDABLE)) {
-
- if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
- /*
- * If S4U2Self principal is not forwardable, then mark ticket as
- * unforwardable. This behaviour matches Windows, but it is
- * different to the MIT AS-REQ path, which returns an error
- * (KDC_ERR_POLICY) if forwardable tickets cannot be issued.
- *
- * Consider this block the S4U2Self equivalent to
- * validate_forwardable().
- */
- if (client != NULL &&
- isflagset(client->attributes, KRB5_KDB_DISALLOW_FORWARDABLE))
- clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
- /*
- * Forwardable flag is propagated along referral path.
- */
- else if (!isflagset(header_enc_tkt->flags, TKT_FLG_FORWARDABLE))
- clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
- /*
- * OK_TO_AUTH_AS_DELEGATE must be set on the service requesting
- * S4U2Self in order for forwardable tickets to be returned.
- */
- else if (!is_referral &&
- !isflagset(server->attributes,
- KRB5_KDB_OK_TO_AUTH_AS_DELEGATE))
- clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
- }
- }
-
if (isflagset(request->kdc_options, KDC_OPT_FORWARDED) ||
isflagset(request->kdc_options, KDC_OPT_PROXY)) {
@@ -440,16 +410,10 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
enc_tkt_reply.caddrs = request->addresses;
reply_encpart.caddrs = request->addresses;
}
- /* We don't currently handle issuing anonymous tickets based on
- * non-anonymous ones, so just ignore the option. */
- if (isflagset(request->kdc_options, KDC_OPT_REQUEST_ANONYMOUS) &&
- !isflagset(header_enc_tkt->flags, TKT_FLG_ANONYMOUS))
- clear(enc_tkt_reply.flags, TKT_FLG_ANONYMOUS);
- if (isflagset(request->kdc_options, KDC_OPT_POSTDATED)) {
- setflag(enc_tkt_reply.flags, TKT_FLG_INVALID);
+ if (isflagset(request->kdc_options, KDC_OPT_POSTDATED))
enc_tkt_reply.times.starttime = request->from;
- } else
+ else
enc_tkt_reply.times.starttime = kdc_time;
if (isflagset(request->kdc_options, KDC_OPT_VALIDATE)) {
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 96c88edc1..f2741090e 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -697,29 +697,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
return(KDC_ERR_CANNOT_POSTDATE);
}
- /*
- * A Windows KDC will return KDC_ERR_PREAUTH_REQUIRED instead of
- * KDC_ERR_POLICY in the following case:
- *
- * - KDC_OPT_FORWARDABLE is set in KDCOptions but local
- * policy has KRB5_KDB_DISALLOW_FORWARDABLE set for the
- * client, and;
- * - KRB5_KDB_REQUIRES_PRE_AUTH is set for the client but
- * preauthentication data is absent in the request.
- *
- * Hence, this check most be done after the check for preauth
- * data, and is now performed by validate_forwardable() (the
- * contents of which were previously below).
- */
-
- /* Client and server must allow proxiable tickets */
- if (isflagset(request->kdc_options, KDC_OPT_PROXIABLE) &&
- (isflagset(client.attributes, KRB5_KDB_DISALLOW_PROXIABLE) ||
- isflagset(server.attributes, KRB5_KDB_DISALLOW_PROXIABLE))) {
- *status = "PROXIABLE NOT ALLOWED";
- return(KDC_ERR_POLICY);
- }
-
/* Check to see if client is locked out */
if (isflagset(client.attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
*status = "CLIENT LOCKED OUT";
@@ -752,19 +729,54 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
return 0;
}
-int
-validate_forwardable(krb5_kdc_req *request, krb5_db_entry client,
- krb5_db_entry server, krb5_timestamp kdc_time,
- const char **status)
+/*
+ * Compute ticket flags based on the request, the client and server DB entry
+ * (which may prohibit forwardable or proxiable tickets), and the header
+ * ticket. client may be NULL for a TGS request (although it may be set, such
+ * as for an S4U2Self request). header_enc may be NULL for an AS request.
+ */
+krb5_flags
+get_ticket_flags(krb5_flags reqflags, krb5_db_entry *client,
+ krb5_db_entry *server, krb5_enc_tkt_part *header_enc)
{
- *status = NULL;
- if (isflagset(request->kdc_options, KDC_OPT_FORWARDABLE) &&
- (isflagset(client.attributes, KRB5_KDB_DISALLOW_FORWARDABLE) ||
- isflagset(server.attributes, KRB5_KDB_DISALLOW_FORWARDABLE))) {
- *status = "FORWARDABLE NOT ALLOWED";
- return(KDC_ERR_POLICY);
- } else
- return 0;
+ krb5_flags flags;
+
+ /* Indicate support for encrypted padata (RFC 6806), and set flags based on
+ * request options and the header ticket. */
+ flags = OPTS2FLAGS(reqflags) | TKT_FLG_ENC_PA_REP;
+ if (reqflags & KDC_OPT_POSTDATED)
+ flags |= TKT_FLG_INVALID;
+ if (header_enc != NULL)
+ flags |= COPY_TKT_FLAGS(header_enc->flags);
+ if (header_enc == NULL)
+ flags |= TKT_FLG_INITIAL;
+
+ /* For TGS requests, indicate if the service is marked ok-as-delegate. */
+ if (header_enc != NULL && (server->attributes & KRB5_KDB_OK_AS_DELEGATE))
+ flags |= TKT_FLG_OK_AS_DELEGATE;
+
+ /* Unset PROXIABLE if it is disallowed. */
+ if (client != NULL && (client->attributes & KRB5_KDB_DISALLOW_PROXIABLE))
+ flags &= ~TKT_FLG_PROXIABLE;
+ if (server->attributes & KRB5_KDB_DISALLOW_PROXIABLE)
+ flags &= ~TKT_FLG_PROXIABLE;
+ if (header_enc != NULL && !(header_enc->flags & TKT_FLG_PROXIABLE))
+ flags &= ~TKT_FLG_PROXIABLE;
+
+ /* Unset FORWARDABLE if it is disallowed. */
+ if (client != NULL && (client->attributes & KRB5_KDB_DISALLOW_FORWARDABLE))
+ flags &= ~TKT_FLG_FORWARDABLE;
+ if (server->attributes & KRB5_KDB_DISALLOW_FORWARDABLE)
+ flags &= ~TKT_FLG_FORWARDABLE;
+ if (header_enc != NULL && !(header_enc->flags & TKT_FLG_FORWARDABLE))
+ flags &= ~TKT_FLG_FORWARDABLE;
+
+ /* We don't currently handle issuing anonymous tickets based on
+ * non-anonymous ones. */
+ if (header_enc != NULL && !(header_enc->flags & TKT_FLG_ANONYMOUS))
+ flags &= ~TKT_FLG_ANONYMOUS;
+
+ return flags;
}
/* Return KRB5KDC_ERR_POLICY if indicators does not contain the required auth
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 25077cbf5..1314bdd58 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -85,16 +85,15 @@ validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
krb5_db_entry, krb5_timestamp,
const char **, krb5_pa_data ***);
-int
-validate_forwardable(krb5_kdc_req *, krb5_db_entry,
- krb5_db_entry, krb5_timestamp,
- const char **);
-
int
validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
krb5_ticket *, krb5_timestamp,
const char **, krb5_pa_data ***);
+krb5_flags
+get_ticket_flags(krb5_flags reqflags, krb5_db_entry *client,
+ krb5_db_entry *server, krb5_enc_tkt_part *header_enc);
+
krb5_error_code
check_indicators(krb5_context context, krb5_db_entry *server,
krb5_data *const *indicators);
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
index 907fcd330..554345ba5 100644
--- a/src/kdc/tgs_policy.c
+++ b/src/kdc/tgs_policy.c
@@ -63,9 +63,9 @@ static check_tgs_svc_pol_fn * const svc_pol_fns[] = {
};
static const struct tgsflagrule tgsflagrules[] = {
- { (KDC_OPT_FORWARDED | KDC_OPT_FORWARDABLE), TKT_FLG_FORWARDABLE,
+ { KDC_OPT_FORWARDED, TKT_FLG_FORWARDABLE,
"TGT NOT FORWARDABLE", KDC_ERR_BADOPTION },
- { (KDC_OPT_PROXY | KDC_OPT_PROXIABLE), TKT_FLG_PROXIABLE,
+ { KDC_OPT_PROXY, TKT_FLG_PROXIABLE,
"TGT NOT PROXIABLE", KDC_ERR_BADOPTION },
{ (KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED), TKT_FLG_MAY_POSTDATE,
"TGT NOT POSTDATABLE", KDC_ERR_BADOPTION },
@@ -98,12 +98,8 @@ check_tgs_opts(krb5_kdc_req *req, krb5_ticket *tkt, const char **status)
}
static const struct tgsflagrule svcdenyrules[] = {
- { KDC_OPT_FORWARDABLE, KRB5_KDB_DISALLOW_FORWARDABLE,
- "NON-FORWARDABLE TICKET", KDC_ERR_POLICY },
{ KDC_OPT_RENEWABLE, KRB5_KDB_DISALLOW_RENEWABLE,
"NON-RENEWABLE TICKET", KDC_ERR_POLICY },
- { KDC_OPT_PROXIABLE, KRB5_KDB_DISALLOW_PROXIABLE,
- "NON-PROXIABLE TICKET", KDC_ERR_POLICY },
{ KDC_OPT_ALLOW_POSTDATE, KRB5_KDB_DISALLOW_POSTDATED,
"NON-POSTDATABLE TICKET", KDC_ERR_CANNOT_POSTDATE },
{ KDC_OPT_ENC_TKT_IN_SKEY, KRB5_KDB_DISALLOW_DUP_SKEY,
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index c96c5d6b7..d2a37c616 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -171,6 +171,7 @@ check-pytests: unlockiter
$(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_u2u.py $(PYTESTFLAGS)
+ $(RUNPYTEST) $(srcdir)/t_kdcoptions.py $(PYTESTFLAGS)
clean:
$(RM) adata etinfo forward gcred hist hooks hrealm icinterleave icred
diff --git a/src/tests/gcred.c b/src/tests/gcred.c
index cb0ae6af5..b14e4fc9a 100644
--- a/src/tests/gcred.c
+++ b/src/tests/gcred.c
@@ -66,20 +66,32 @@ main(int argc, char **argv)
krb5_principal client, server;
krb5_ccache ccache;
krb5_creds in_creds, *creds;
+ krb5_flags options = 0;
char *name;
+ int c;
check(krb5_init_context(&ctx));
- /* Parse arguments. */
- assert(argc == 3);
- check(krb5_parse_name(ctx, argv[2], &server));
- if (strcmp(argv[1], "unknown") == 0)
+ while ((c = getopt(argc, argv, "f")) != -1) {
+ switch (c) {
+ case 'f':
+ options |= KRB5_GC_FORWARDABLE;
+ break;
+ default:
+ abort();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ assert(argc == 2);
+ check(krb5_parse_name(ctx, argv[1], &server));
+ if (strcmp(argv[0], "unknown") == 0)
server->type = KRB5_NT_UNKNOWN;
- else if (strcmp(argv[1], "principal") == 0)
+ else if (strcmp(argv[0], "principal") == 0)
server->type = KRB5_NT_PRINCIPAL;
- else if (strcmp(argv[1], "srv-inst") == 0)
+ else if (strcmp(argv[0], "srv-inst") == 0)
server->type = KRB5_NT_SRV_INST;
- else if (strcmp(argv[1], "srv-hst") == 0)
+ else if (strcmp(argv[0], "srv-hst") == 0)
server->type = KRB5_NT_SRV_HST;
else
abort();
@@ -89,7 +101,7 @@ main(int argc, char **argv)
memset(&in_creds, 0, sizeof(in_creds));
in_creds.client = client;
in_creds.server = server;
- check(krb5_get_credentials(ctx, 0, ccache, &in_creds, &creds));
+ check(krb5_get_credentials(ctx, options, ccache, &in_creds, &creds));
check(krb5_unparse_name(ctx, creds->server, &name));
printf("%s\n", name);
diff --git a/src/tests/t_kdcoptions.py b/src/tests/t_kdcoptions.py
new file mode 100644
index 000000000..7ec57508c
--- /dev/null
+++ b/src/tests/t_kdcoptions.py
@@ -0,0 +1,100 @@
+from k5test import *
+import re
+
+# KDC option test coverage notes:
+#
+# FORWARDABLE here
+# FORWARDED no test
+# PROXIABLE here
+# PROXY no test
+# ALLOW_POSTDATE no test
+# POSTDATED no test
+# RENEWABLE t_renew.py
+# CNAME_IN_ADDL_TKT gssapi/t_s4u.py
+# CANONICALIZE t_kdb.py and various other tests
+# REQUEST_ANONYMOUS t_pkinit.py
+# DISABLE_TRANSITED_CHECK no test
+# RENEWABLE_OK t_renew.py
+# ENC_TKT_IN_SKEY t_u2u.py
+# RENEW t_renew.py
+# VALIDATE no test
+
+# Run klist -f and return the flags on the ticket for svcprinc.
+def get_flags(realm, svcprinc):
+ grab_flags = False
+ for line in realm.run([klist, '-f']).splitlines():
+ if grab_flags:
+ return re.findall(r'Flags: ([a-zA-Z]*)', line)[0]
+ grab_flags = line.endswith(svcprinc)
+
+
+# Get the flags on the ticket for svcprinc, and check for an expected
+# element and an expected-absent element, either of which can be None.
+def check_flags(realm, svcprinc, expected_flag, expected_noflag):
+ flags = get_flags(realm, svcprinc)
+ if expected_flag is not None and not expected_flag in flags:
+ fail('expected flag ' + expected_flag)
+ if expected_noflag is not None and expected_noflag in flags:
+ fail('did not expect flag ' + expected_noflag)
+
+
+# Run kinit with the given flags, and check the flags on the resulting
+# TGT.
+def kinit_check_flags(realm, flags, expected_flag, expected_noflag):
+ realm.kinit(realm.user_princ, password('user'), flags)
+ check_flags(realm, realm.krbtgt_princ, expected_flag, expected_noflag)
+
+
+# Run kinit with kflags. Then get credentials for the host principal
+# with gflags, and check the flags on the resulting ticket.
+def gcred_check_flags(realm, kflags, gflags, expected_flag, expected_noflag):
+ realm.kinit(realm.user_princ, password('user'), kflags)
+ realm.run(['./gcred'] + gflags + ['unknown', realm.host_princ])
+ check_flags(realm, realm.host_princ, expected_flag, expected_noflag)
+
+
+realm = K5Realm()
+
+mark('proxiable (AS)')
+kinit_check_flags(realm, [], None, 'P')
+kinit_check_flags(realm, ['-p'], 'P', None)
+realm.run([kadminl, 'modprinc', '-allow_proxiable', realm.user_princ])
+kinit_check_flags(realm, ['-p'], None, 'P')
+realm.run([kadminl, 'modprinc', '+allow_proxiable', realm.user_princ])
+realm.run([kadminl, 'modprinc', '-allow_proxiable', realm.krbtgt_princ])
+kinit_check_flags(realm, ['-p'], None, 'P')
+realm.run([kadminl, 'modprinc', '+allow_proxiable', realm.krbtgt_princ])
+
+mark('proxiable (TGS)')
+gcred_check_flags(realm, [], [], None, 'P')
+gcred_check_flags(realm, ['-p'], [], 'P', None)
+
+# Not tested: PROXIABLE option set with a non-proxiable TGT (because
+# there is no krb5_get_credentials() flag to request this; would
+# expect a non-proxiable ticket).
+
+# Not tested: proxiable TGT but PROXIABLE flag not set (because we
+# internally set the PROXIABLE option when using a proxiable TGT;
+# would expect a non-proxiable ticket).
+
+mark('forwardable (AS)')
+kinit_check_flags(realm, [], None, 'F')
+kinit_check_flags(realm, ['-f'], 'F', None)
+realm.run([kadminl, 'modprinc', '-allow_forwardable', realm.user_princ])
+kinit_check_flags(realm, ['-f'], None, 'F')
+realm.run([kadminl, 'modprinc', '+allow_forwardable', realm.user_princ])
+realm.run([kadminl, 'modprinc', '-allow_forwardable', realm.krbtgt_princ])
+kinit_check_flags(realm, ['-f'], None, 'F')
+realm.run([kadminl, 'modprinc', '+allow_forwardable', realm.krbtgt_princ])
+
+mark('forwardable (TGS)')
+realm.kinit(realm.user_princ, password('user'))
+gcred_check_flags(realm, [], [], None, 'F')
+gcred_check_flags(realm, [], ['-f'], None, 'F')
+gcred_check_flags(realm, ['-f'], [], 'F', None)
+
+# Not tested: forwardable TGT but FORWARDABLE flag not set (because we
+# internally set the FORWARDABLE option when using a forwardable TGT;
+# would expect a non-proxiable ticket).
+
+success('KDC option tests')

View file

@ -1,29 +0,0 @@
From 908eb6dde51917bb50d388a1769c50eede68fc10 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 16 Apr 2019 10:47:35 -0400
Subject: [PATCH] Fix config realm change logic in FILE remove_cred
Use data_eq_string() to check the server realm, and do not check if
cred->server is NULL since it is not expected to be (and
k5_marshal_cred() would have already crashed if it were).
ticket: 8792
(cherry picked from commit e5367fcddd53dc4db0c1fd2279e91eda3791960a)
---
src/lib/krb5/ccache/cc_file.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c
index 09da38fa9..a3f67766e 100644
--- a/src/lib/krb5/ccache/cc_file.c
+++ b/src/lib/krb5/ccache/cc_file.c
@@ -1058,8 +1058,7 @@ delete_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
/* For config entries, also change the realm so that other implementations
* won't match them. */
- if (cred->server != NULL && cred->server->realm.length > 0 &&
- strcmp(cred->server->realm.data, "X-CACHECONF:") == 0)
+ if (data_eq_string(cred->server->realm, "X-CACHECONF:"))
memcpy(cred->server->realm.data, "X-RMED-CONF:", 12);
k5_marshal_cred(&overwrite, fcursor->version, cred);

View file

@ -1,33 +0,0 @@
From 050acb871c242931b3fb51c59461f22555046d19 Mon Sep 17 00:00:00 2001
From: Corene Casper <C.Casper@Dell.com>
Date: Sat, 16 Feb 2019 00:49:26 -0500
Subject: [PATCH] Fix memory leak in 'none' replay cache type
Commit 0f06098e2ab419d02e89a1ca6bc9f2828f6bdb1e fixed part of a memory
leak in the 'none' replay cache type by freeing the outer container,
but we also need to free the mutex.
[ghudson@mit.edu: wrote commit message]
ticket: 8783
tags: pullup
target_version: 1.17-next
target_version: 1.16-next
(cherry picked from commit af2a3115cb8feb5174151b4b40223ae45aa9db17)
---
src/lib/krb5/rcache/rc_none.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lib/krb5/rcache/rc_none.c b/src/lib/krb5/rcache/rc_none.c
index e30aed09f..0b2274df7 100644
--- a/src/lib/krb5/rcache/rc_none.c
+++ b/src/lib/krb5/rcache/rc_none.c
@@ -50,6 +50,7 @@ krb5_rc_none_noargs(krb5_context ctx, krb5_rcache rc)
static krb5_error_code KRB5_CALLCONV
krb5_rc_none_close(krb5_context ctx, krb5_rcache rc)
{
+ k5_mutex_destroy(&rc->lock);
free (rc);
return 0;
}

View file

@ -1,30 +0,0 @@
From b2002f8286c0f77e57c7387123328a31125cda2e Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 18 Apr 2019 13:39:37 -0400
Subject: [PATCH] Fix potential close(-1) in cc_file.c
As part of error handling in d3b39a8bac6206b5ea78b0bf6a2958c1df0b0dd5,
an error path in delete_cred() may result in close(-1). While this
shouldn't be a prolblem in practice (just returning EBADF), it does
upset Coverity.
ticket: 8792
(cherry picked from commit 5ccfbaf2f0c8871d2f0ea87ad4b21cc33392ca2c)
---
src/lib/krb5/ccache/cc_file.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c
index a3f67766e..bf58c1d45 100644
--- a/src/lib/krb5/ccache/cc_file.c
+++ b/src/lib/krb5/ccache/cc_file.c
@@ -1122,7 +1122,8 @@ delete_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
}
cleanup:
- close(fd);
+ if (fd >= 0)
+ close(fd);
zapfree(on_disk, expected.len);
k5_buf_free(&expected);
k5_buf_free(&overwrite);

View file

@ -1,599 +0,0 @@
From 57ce492d6700ca6417cc43f3e97e0186b2cdfa90 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 1 Apr 2019 14:28:48 -0400
Subject: [PATCH] Implement krb5_cc_remove_cred for remaining types
Previously, only KCM and MSLA implemented credential removal. Add
support for FILE (and therefore DIR), MEMORY, and KEYRING.
The FILE logic is similar Heimdal's implementation, with additional
logic for skipping removed creds during iteration. In addition to
setting endtime to 0 and changing the realm for config entries as
Heimdal does, we set authtime to -1 to make deleted entries
distinguishable from gssproxy encrypted creds and config entries.
For MEMORY, leave behind empty list elements when removing a cred will
leave behind an empty list element, in case an iterator holds a
pointer to that element.
[ghudson@mit.edu: edited commit message; made minor style and comment
changes; fixed memory leaks detected by asan]
ticket: 8792 (new)
(cherry picked from commit d3b39a8bac6206b5ea78b0bf6a2958c1df0b0dd5)
---
src/lib/krb5/ccache/cc_file.c | 177 ++++++++++++++++++++++++++++---
src/lib/krb5/ccache/cc_keyring.c | 89 +++++++++++-----
src/lib/krb5/ccache/cc_memory.c | 36 +++++--
src/lib/krb5/ccache/t_cc.c | 129 +++++++++++++++++++++-
4 files changed, 381 insertions(+), 50 deletions(-)
diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c
index 9263a0054..09da38fa9 100644
--- a/src/lib/krb5/ccache/cc_file.c
+++ b/src/lib/krb5/ccache/cc_file.c
@@ -744,6 +744,14 @@ cleanup:
return set_errmsg_filename(context, ret, data->filename);
}
+/* Return true if cred is a removed entry (assuming that no legitimate cred
+ * entries will have authtime=-1 and endtime=0). */
+static inline krb5_boolean
+cred_removed(krb5_creds *c)
+{
+ return c->times.endtime == 0 && c->times.authtime == -1;
+}
+
/* Get the next credential from the cache file. */
static krb5_error_code KRB5_CALLCONV
fcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
@@ -765,19 +773,30 @@ fcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
goto cleanup;
file_locked = TRUE;
- /* Load a marshalled cred into memory. */
- ret = get_size(context, fcursor->fp, &maxsize);
- if (ret)
- goto cleanup;
- ret = load_cred(context, fcursor->fp, fcursor->version, maxsize, &buf);
- if (ret)
- goto cleanup;
- ret = k5_buf_status(&buf);
- if (ret)
- goto cleanup;
+ for (;;) {
+ /* Load a marshalled cred into memory. */
+ ret = get_size(context, fcursor->fp, &maxsize);
+ if (ret)
+ goto cleanup;
+ ret = load_cred(context, fcursor->fp, fcursor->version, maxsize, &buf);
+ if (ret)
+ goto cleanup;
+ ret = k5_buf_status(&buf);
+ if (ret)
+ goto cleanup;
- /* Unmarshal it from buf into creds. */
- ret = k5_unmarshal_cred(buf.data, buf.len, fcursor->version, creds);
+ /* Unmarshal it from buf into creds. */
+ ret = k5_unmarshal_cred(buf.data, buf.len, fcursor->version, creds);
+ if (ret)
+ goto cleanup;
+
+ /* Keep going if this entry has been removed; otherwise stop. */
+ if (!cred_removed(creds))
+ break;
+
+ k5_buf_truncate(&buf, 0);
+ krb5_free_cred_contents(context, creds);
+ }
cleanup:
if (file_locked)
@@ -1002,12 +1021,142 @@ cleanup:
return set_errmsg_filename(context, ret ? ret : ret2, data->filename);
}
-/* Non-functional stub for removing a cred from the cache file. */
+/*
+ * Overwrite cred in the ccache file with an entry that should not match any
+ * reasonable search. Deletion is not guaranteed. This method is originally
+ * from Heimdal, with the addition of setting authtime to -1.
+ */
+static krb5_error_code
+delete_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
+ krb5_creds *cred)
+{
+ krb5_error_code ret;
+ krb5_fcc_cursor *fcursor = *cursor;
+ fcc_data *data = cache->data;
+ struct k5buf expected = EMPTY_K5BUF, overwrite = EMPTY_K5BUF;
+ int fd = -1;
+ uint8_t *on_disk = NULL;
+ ssize_t rwret;
+ off_t start_offset;
+
+ k5_buf_init_dynamic_zap(&expected);
+ k5_buf_init_dynamic_zap(&overwrite);
+
+ /* Re-marshal cred to get its byte representation in the file. */
+ k5_marshal_cred(&expected, fcursor->version, cred);
+ ret = k5_buf_status(&expected);
+ if (ret)
+ goto cleanup;
+
+ /*
+ * Mark the cred expired so that it will be skipped over by any future
+ * match checks. Heimdal only sets endtime, but we also set authtime to
+ * distinguish from gssproxy's creds.
+ */
+ cred->times.endtime = 0;
+ cred->times.authtime = -1;
+
+ /* For config entries, also change the realm so that other implementations
+ * won't match them. */
+ if (cred->server != NULL && cred->server->realm.length > 0 &&
+ strcmp(cred->server->realm.data, "X-CACHECONF:") == 0)
+ memcpy(cred->server->realm.data, "X-RMED-CONF:", 12);
+
+ k5_marshal_cred(&overwrite, fcursor->version, cred);
+ ret = k5_buf_status(&overwrite);
+ if (ret)
+ goto cleanup;
+
+ if (expected.len != overwrite.len) {
+ ret = KRB5_CC_FORMAT;
+ goto cleanup;
+ }
+
+ /* Get a non-O_APPEND handle to the raw file. */
+ fd = open(data->filename, O_RDWR | O_BINARY | O_CLOEXEC);
+ if (fd == -1) {
+ ret = interpret_errno(context, errno);
+ goto cleanup;
+ }
+
+ start_offset = ftell(fcursor->fp);
+ if (start_offset == -1) {
+ ret = interpret_errno(context, errno);
+ goto cleanup;
+ }
+ start_offset -= expected.len;
+
+ /* Read the bytes at the entry to be overwritten. */
+ if (lseek(fd, start_offset, SEEK_SET) == -1) {
+ ret = interpret_errno(context, errno);
+ goto cleanup;
+ }
+ on_disk = k5alloc(expected.len, &ret);
+ if (ret != 0)
+ goto cleanup;
+ rwret = read(fd, on_disk, expected.len);
+ if (rwret < 0) {
+ ret = interpret_errno(context, errno);
+ goto cleanup;
+ } else if ((size_t)rwret != expected.len) {
+ ret = KRB5_CC_FORMAT;
+ goto cleanup;
+ }
+
+ /*
+ * If the bytes have changed, either someone else removed the same cred or
+ * the cache was reinitialized. Either way the cred is no longer present,
+ * so return successfully.
+ */
+ if (memcmp(on_disk, expected.data, expected.len) != 0)
+ goto cleanup;
+
+ /* Write out the altered entry. */
+ if (lseek(fd, start_offset, SEEK_SET) == -1) {
+ ret = interpret_errno(context, errno);
+ goto cleanup;
+ }
+ rwret = write(fd, overwrite.data, overwrite.len);
+ if (rwret < 0) {
+ ret = interpret_errno(context, errno);
+ goto cleanup;
+ }
+
+cleanup:
+ close(fd);
+ zapfree(on_disk, expected.len);
+ k5_buf_free(&expected);
+ k5_buf_free(&overwrite);
+ return ret;
+}
+
+/* Remove the given creds from the ccache file. */
static krb5_error_code KRB5_CALLCONV
fcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
krb5_creds *creds)
{
- return KRB5_CC_NOSUPP;
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_creds cur;
+
+ ret = krb5_cc_start_seq_get(context, cache, &cursor);
+ if (ret)
+ return ret;
+
+ for (;;) {
+ ret = krb5_cc_next_cred(context, cache, &cursor, &cur);
+ if (ret)
+ break;
+
+ if (krb5int_cc_creds_match_request(context, flags, creds, &cur))
+ ret = delete_cred(context, cache, &cursor, &cur);
+ krb5_free_cred_contents(context, &cur);
+ if (ret)
+ break;
+ }
+
+ krb5_cc_end_seq_get(context, cache, &cursor);
+ return (ret == KRB5_CC_END) ? 0 : ret;
}
static krb5_error_code KRB5_CALLCONV
diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c
index 8419f6ebf..98723fe2e 100644
--- a/src/lib/krb5/ccache/cc_keyring.c
+++ b/src/lib/krb5/ccache/cc_keyring.c
@@ -1032,40 +1032,44 @@ krcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
memset(creds, 0, sizeof(krb5_creds));
- /* The cursor has the entire list of keys. (Note that we don't support
- * remove_cred.) */
+ /* The cursor has the entire list of keys. */
krcursor = *cursor;
if (krcursor == NULL)
return KRB5_CC_END;
- /* If we're pointing past the end of the keys array, there are no more. */
- if (krcursor->currkey >= krcursor->numkeys)
- return KRB5_CC_END;
+ while (krcursor->currkey < krcursor->numkeys) {
+ /* If we're pointing at the entry with the principal, or at the key
+ * with the time offsets, skip it. */
+ if (krcursor->keys[krcursor->currkey] == krcursor->princ_id ||
+ krcursor->keys[krcursor->currkey] == krcursor->offsets_id) {
+ krcursor->currkey++;
+ continue;
+ }
- /* If we're pointing at the entry with the principal, or at the key
- * with the time offsets, skip it. */
- while (krcursor->keys[krcursor->currkey] == krcursor->princ_id ||
- krcursor->keys[krcursor->currkey] == krcursor->offsets_id) {
+ /* Read the key; the right size buffer will be allocated and
+ * returned. */
+ psize = keyctl_read_alloc(krcursor->keys[krcursor->currkey],
+ &payload);
+ if (psize != -1) {
+ krcursor->currkey++;
+
+ /* Unmarshal the cred using the file ccache version 4 format. */
+ ret = k5_unmarshal_cred(payload, psize, 4, creds);
+ free(payload);
+ return ret;
+ } else if (errno != ENOKEY && errno != EACCES) {
+ DEBUG_PRINT(("Error reading key %d: %s\n",
+ krcursor->keys[krcursor->currkey], strerror(errno)));
+ return KRB5_FCC_NOFILE;
+ }
+
+ /* The current key was unlinked, probably by a remove_cred call; move
+ * on to the next one. */
krcursor->currkey++;
- /* Check if we have now reached the end */
- if (krcursor->currkey >= krcursor->numkeys)
- return KRB5_CC_END;
}
- /* Read the key; the right size buffer will be allocated and returned. */
- psize = keyctl_read_alloc(krcursor->keys[krcursor->currkey], &payload);
- if (psize == -1) {
- DEBUG_PRINT(("Error reading key %d: %s\n",
- krcursor->keys[krcursor->currkey],
- strerror(errno)));
- return KRB5_FCC_NOFILE;
- }
- krcursor->currkey++;
-
- /* Unmarshal the credential using the file ccache version 4 format. */
- ret = k5_unmarshal_cred(payload, psize, 4, creds);
- free(payload);
- return ret;
+ /* No more keys in keyring. */
+ return KRB5_CC_END;
}
/* Release an iteration cursor. */
@@ -1248,12 +1252,41 @@ krcc_retrieve(krb5_context context, krb5_ccache id,
creds);
}
-/* Non-functional stub for removing a cred from the cache keyring. */
+/* Remove a credential from the cache keyring. */
static krb5_error_code KRB5_CALLCONV
krcc_remove_cred(krb5_context context, krb5_ccache cache,
krb5_flags flags, krb5_creds *creds)
{
- return KRB5_CC_NOSUPP;
+ krb5_error_code ret;
+ krcc_data *data = cache->data;
+ krb5_cc_cursor cursor;
+ krb5_creds c;
+ krcc_cursor krcursor;
+ key_serial_t key;
+ krb5_boolean match;
+
+ ret = krcc_start_seq_get(context, cache, &cursor);
+ if (ret)
+ return ret;
+
+ for (;;) {
+ ret = krcc_next_cred(context, cache, &cursor, &c);
+ if (ret)
+ break;
+ match = krb5int_cc_creds_match_request(context, flags, creds, &c);
+ krb5_free_cred_contents(context, &c);
+ if (match) {
+ krcursor = cursor;
+ key = krcursor->keys[krcursor->currkey - 1];
+ if (keyctl_unlink(key, data->cache_id) == -1) {
+ ret = errno;
+ break;
+ }
+ }
+ }
+
+ krcc_end_seq_get(context, cache, &cursor);
+ return (ret == KRB5_CC_END) ? 0 : ret;
}
/* Set flags on the cache. (We don't care about any flags.) */
diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c
index 114ef6913..edf6fcc26 100644
--- a/src/lib/krb5/ccache/cc_memory.c
+++ b/src/lib/krb5/ccache/cc_memory.c
@@ -405,14 +405,23 @@ krb5_mcc_next_cred(krb5_context context, krb5_ccache id,
*/
k5_cc_mutex_lock(context, &d->lock);
if (mcursor->generation != d->generation) {
- k5_cc_mutex_unlock(context, &d->lock);
- return KRB5_CC_END;
+ retval = KRB5_CC_END;
+ goto done;
+ }
+
+ /* Skip over removed creds. */
+ while (mcursor->next_link != NULL && mcursor->next_link->creds == NULL)
+ mcursor->next_link = mcursor->next_link->next;
+ if (mcursor->next_link == NULL) {
+ retval = KRB5_CC_END;
+ goto done;
}
retval = k5_copy_creds_contents(context, mcursor->next_link->creds, creds);
if (retval == 0)
mcursor->next_link = mcursor->next_link->next;
+done:
k5_cc_mutex_unlock(context, &d->lock);
return retval;
}
@@ -592,16 +601,31 @@ krb5_mcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields,
}
/*
- * Non-functional stub implementation for krb5_mcc_remove
+ * Modifies:
+ * the memory cache
*
- * Errors:
- * KRB5_CC_NOSUPP - not implemented
+ * Effects:
+ * Remove the given creds from the ccache.
*/
static krb5_error_code KRB5_CALLCONV
krb5_mcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
krb5_creds *creds)
{
- return KRB5_CC_NOSUPP;
+ krb5_mcc_data *data = (krb5_mcc_data *)cache->data;
+ krb5_mcc_link *l;
+
+ k5_cc_mutex_lock(context, &data->lock);
+
+ for (l = data->link; l != NULL; l = l->next) {
+ if (l->creds != NULL &&
+ krb5int_cc_creds_match_request(context, flags, creds, l->creds)) {
+ krb5_free_creds(context, l->creds);
+ l->creds = NULL;
+ }
+ }
+
+ k5_cc_mutex_unlock(context, &data->lock);
+ return 0;
}
diff --git a/src/lib/krb5/ccache/t_cc.c b/src/lib/krb5/ccache/t_cc.c
index cd4569c4c..954f2f465 100644
--- a/src/lib/krb5/ccache/t_cc.c
+++ b/src/lib/krb5/ccache/t_cc.c
@@ -36,7 +36,7 @@
#define KRB5_OK 0
-krb5_creds test_creds;
+krb5_creds test_creds, test_creds2;
int debug=0;
@@ -144,6 +144,10 @@ init_test_cred(krb5_context context)
a->length = 2;
test_creds.authdata[1] = a;
+ memcpy(&test_creds2, &test_creds, sizeof(test_creds));
+ kret = krb5_build_principal(context, &test_creds2.server, sizeof(REALM),
+ REALM, "server-comp1", "server-comp3", NULL);
+
cleanup:
if(kret) {
if (test_creds.client) {
@@ -170,6 +174,7 @@ free_test_cred(krb5_context context)
krb5_free_principal(context, test_creds.client);
krb5_free_principal(context, test_creds.server);
+ krb5_free_principal(context, test_creds2.server);
if(test_creds.authdata) {
krb5_free_authdata(context, test_creds.authdata);
@@ -199,6 +204,44 @@ free_test_cred(krb5_context context)
#define CHECK_FAIL(experr, kret, msg) \
if (experr != kret) { CHECK(kret, msg);}
+static void
+check_num_entries(krb5_context context, krb5_ccache cache, int expected,
+ unsigned linenum)
+{
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_creds creds;
+ int count = 0;
+
+ ret = krb5_cc_start_seq_get(context, cache, &cursor);
+ if (ret != 0) {
+ com_err("", ret, "(on line %d) - krb5_cc_start_seq_get", linenum);
+ fflush(stderr);
+ exit(1);
+ }
+
+ while (1) {
+ ret = krb5_cc_next_cred(context, cache, &cursor, &creds);
+ if (ret)
+ break;
+
+ count++;
+ krb5_free_cred_contents(context, &creds);
+ }
+ krb5_cc_end_seq_get(context, cache, &cursor);
+ if (ret != KRB5_CC_END) {
+ CHECK(ret, "counting entries in ccache");
+ }
+
+ if (count != expected) {
+ com_err("", KRB5_FCC_INTERNAL,
+ "(on line %d) - count didn't match (expected %d, got %d)",
+ linenum, expected, count);
+ fflush(stderr);
+ exit(1);
+ }
+}
+
static void
cc_test(krb5_context context, const char *name, krb5_flags flags)
{
@@ -207,6 +250,7 @@ cc_test(krb5_context context, const char *name, krb5_flags flags)
krb5_error_code kret;
krb5_cc_cursor cursor;
krb5_principal tmp;
+ krb5_flags matchflags = KRB5_TC_MATCH_IS_SKEY;
const char *c_name;
char newcache[300];
@@ -311,9 +355,90 @@ cc_test(krb5_context context, const char *name, krb5_flags flags)
kret = krb5_cc_destroy(context, id2);
CHECK(kret, "destroy id2");
+ /* ----------------------------------------------------- */
+ /* Test credential removal */
+ kret = krb5_cc_resolve(context, name, &id);
+ CHECK(kret, "resolving for remove");
+
+ kret = krb5_cc_initialize(context, id, test_creds.client);
+ CHECK(kret, "initialize for remove");
+ check_num_entries(context, id, 0, __LINE__);
+
+ kret = krb5_cc_store_cred(context, id, &test_creds);
+ CHECK(kret, "store for remove (first pass)");
+ check_num_entries(context, id, 1, __LINE__); /* 1 */
+
+ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds);
+ CHECK(kret, "removing credential (first pass)");
+ check_num_entries(context, id, 0, __LINE__); /* empty */
+
+ kret = krb5_cc_store_cred(context, id, &test_creds);
+ CHECK(kret, "first store for remove (second pass)");
+ check_num_entries(context, id, 1, __LINE__); /* 1 */
+
+ kret = krb5_cc_store_cred(context, id, &test_creds2);
+ CHECK(kret, "second store for remove (second pass)");
+ check_num_entries(context, id, 2, __LINE__); /* 1, 2 */
+
+ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds2);
+ CHECK(kret, "first remove (second pass)");
+ check_num_entries(context, id, 1, __LINE__); /* 1 */
+
+ kret = krb5_cc_store_cred(context, id, &test_creds2);
+ CHECK(kret, "third store for remove (second pass)");
+ check_num_entries(context, id, 2, __LINE__); /* 1, 2 */
+
+ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds);
+ CHECK(kret, "second remove (second pass)");
+ check_num_entries(context, id, 1, __LINE__); /* 2 */
+
+ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds2);
+ CHECK(kret, "third remove (second pass)");
+ check_num_entries(context, id, 0, __LINE__); /* empty */
+
+ kret = krb5_cc_destroy(context, id);
+ CHECK(kret, "destruction for remove");
+
+ /* Test removal with iteration. */
+ kret = krb5_cc_resolve(context, name, &id);
+ CHECK(kret, "resolving for remove-iter");
+
+ kret = krb5_cc_initialize(context, id, test_creds.client);
+ CHECK(kret, "initialize for remove-iter");
+
+ kret = krb5_cc_store_cred(context, id, &test_creds);
+ CHECK(kret, "first store for remove-iter");
+
+ kret = krb5_cc_store_cred(context, id, &test_creds2);
+ CHECK(kret, "second store for remove-iter");
+
+ kret = krb5_cc_start_seq_get(context, id, &cursor);
+ CHECK(kret, "start_seq_get for remove-iter");
+
+ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds);
+ CHECK(kret, "remove for remove-iter");
+
+ while (1) {
+ /* The removed credential may or may not be present in the cache -
+ * either behavior is technically correct. */
+ kret = krb5_cc_next_cred(context, id, &cursor, &creds);
+ if (kret == KRB5_CC_END)
+ break;
+ CHECK(kret, "next_cred for remove-iter: %s");
+
+ CHECK(creds.times.endtime == 0, "no-lifetime cred");
+
+ krb5_free_cred_contents(context, &creds);
+ }
+
+ kret = krb5_cc_end_seq_get(context, id, &cursor);
+ CHECK(kret, "end_seq_get for remove-iter");
+
+ kret = krb5_cc_destroy(context, id);
+ CHECK(kret, "destruction for remove-iter");
+
free(save_type);
free_test_cred(context);
-
}
/*

View file

@ -1,28 +0,0 @@
From c06d20bf241059059cc3ffd810a44e310ff9970d Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 15 Jan 2019 13:41:16 -0500
Subject: [PATCH] In kpropd, debug-log proper ticket enctype names
This change replaces the last call of krb5_enctype_to_string() in our
sources with krb5_enctype_to_name(), ensuring that we log consistently
to users using readily discoverable strings.
(cherry picked from commit 30e12a2ecdf7e2a034a91626a03b5c9909e4c68d)
---
src/kprop/kpropd.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
index 4cc035dc6..0c7bffa24 100644
--- a/src/kprop/kpropd.c
+++ b/src/kprop/kpropd.c
@@ -1279,7 +1279,8 @@ kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp,
exit(1);
}
- retval = krb5_enctype_to_string(*etype, etypebuf, sizeof(etypebuf));
+ retval = krb5_enctype_to_name(*etype, FALSE, etypebuf,
+ sizeof(etypebuf));
if (retval) {
com_err(progname, retval, _("while unparsing ticket etype"));
exit(1);

View file

@ -1,54 +0,0 @@
From 6a316b681a2e0b6917285b9a0cdde605d463288b Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 14 Jan 2019 17:14:42 -0500
Subject: [PATCH] In rd_req_dec, always log non-permitted enctypes
The buffer specified in negotiate_etype() is too small for use with
the AES enctypes when used with krb5_enctype_to_string(), so switch to
using krb5_enctype_to_name().
(cherry picked from commit bf75ebf583a51bf00005a96d17924818d19377be)
---
src/lib/krb5/krb/rd_req_dec.c | 5 ++---
src/tests/gssapi/t_enctypes.py | 5 +++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
index 4cd429a11..e75192fee 100644
--- a/src/lib/krb5/krb/rd_req_dec.c
+++ b/src/lib/krb5/krb/rd_req_dec.c
@@ -864,9 +864,8 @@ negotiate_etype(krb5_context context,
if (permitted == FALSE) {
char enctype_name[30];
- if (krb5_enctype_to_string(desired_etypes[i],
- enctype_name,
- sizeof(enctype_name)) == 0)
+ if (krb5_enctype_to_name(desired_etypes[i], FALSE, enctype_name,
+ sizeof(enctype_name)) == 0)
k5_setmsg(context, KRB5_NOPERM_ETYPE,
_("Encryption type %s not permitted"), enctype_name);
return KRB5_NOPERM_ETYPE;
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index ee43ff028..5d9f80e04 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -85,7 +85,8 @@ test('both aes128', 'aes128-cts', 'aes128-cts',
# If only the acceptor constrains the permitted session enctypes to
# aes128, subkey negotiation fails because the acceptor considers the
# aes256 session key to be non-permitted.
-test_err('acc aes128', None, 'aes128-cts', 'Encryption type not permitted')
+test_err('acc aes128', None, 'aes128-cts',
+ 'Encryption type aes256-cts-hmac-sha1-96 not permitted')
# If the initiator constrains the permitted session enctypes to des3,
# no acceptor subkey will be generated because we can't upgrade to a
@@ -128,7 +129,7 @@ test('upgrade init des3+rc4', 'des3 rc4', None,
# is only for the sake of the kernel, since we could upgrade to an
# aes128 subkey, but it's the current semantics.)
test_err('upgrade acc aes128', None, 'aes128-cts',
- 'Encryption type ArcFour with HMAC/md5 not permitted')
+ 'Encryption type arcfour-hmac not permitted')
# If the acceptor permits rc4 but prefers aes128, it will negotiate an
# upgrade to aes128.

View file

@ -1,296 +0,0 @@
From 2a8005296c3da39f6d0c6ecd48b950447897af91 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 8 Jan 2019 17:42:35 -0500
Subject: [PATCH] Make etype names in KDC logs human-readable
Introduce enctype_name() as a wrapper over krb5_enctype_to_name for
converting between registered constants and names. Adjust signatures
and rewrite ktypes2str() and rep_etypes2str() to operate on dynamic
buffers.
ticket: 8772 (new)
(cherry picked from commit a649279727490687d54becad91fde8cf7429d951)
---
src/kdc/kdc_log.c | 42 +++++++--------
src/kdc/kdc_util.c | 131 +++++++++++++++++++++++----------------------
src/kdc/kdc_util.h | 6 +--
3 files changed, 90 insertions(+), 89 deletions(-)
diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c
index 4eec50373..b160ba21a 100644
--- a/src/kdc/kdc_log.c
+++ b/src/kdc/kdc_log.c
@@ -65,7 +65,7 @@ log_as_req(krb5_context context,
{
const char *fromstring = 0;
char fromstringbuf[70];
- char ktypestr[128];
+ char *ktypestr = NULL;
const char *cname2 = cname ? cname : "<unknown client>";
const char *sname2 = sname ? sname : "<unknown server>";
@@ -74,26 +74,29 @@ log_as_req(krb5_context context,
fromstringbuf, sizeof(fromstringbuf));
if (!fromstring)
fromstring = "<unknown>";
- ktypes2str(ktypestr, sizeof(ktypestr),
- request->nktypes, request->ktype);
+
+ ktypestr = ktypes2str(request->ktype, request->nktypes);
if (status == NULL) {
/* success */
- char rep_etypestr[128];
- rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
+ char *rep_etypestr = rep_etypes2str(reply);
krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, "
"%s for %s"),
- ktypestr, fromstring, (unsigned int)authtime,
- rep_etypestr, cname2, sname2);
+ ktypestr ? ktypestr : "", fromstring,
+ (unsigned int)authtime,
+ rep_etypestr ? rep_etypestr : "", cname2, sname2);
+ free(rep_etypestr);
} else {
/* fail */
krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: %s: %s for %s%s%s"),
- ktypestr, fromstring, status,
- cname2, sname2, emsg ? ", " : "", emsg ? emsg : "");
+ ktypestr ? ktypestr : "", fromstring, status, cname2,
+ sname2, emsg ? ", " : "", emsg ? emsg : "");
}
krb5_db_audit_as_req(context, request,
local_addr->address, remote_addr->address,
client, server, authtime, errcode);
+
+ free(ktypestr);
}
/*
@@ -122,10 +125,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
unsigned int c_flags,
const char *status, krb5_error_code errcode, const char *emsg)
{
- char ktypestr[128];
+ char *ktypestr = NULL, *rep_etypestr = NULL;
const char *fromstring = 0;
char fromstringbuf[70];
- char rep_etypestr[128];
char *cname = NULL, *sname = NULL, *altcname = NULL;
char *logcname = NULL, *logsname = NULL, *logaltcname = NULL;
@@ -134,11 +136,6 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
fromstringbuf, sizeof(fromstringbuf));
if (!fromstring)
fromstring = "<unknown>";
- ktypes2str(ktypestr, sizeof(ktypestr), request->nktypes, request->ktype);
- if (!errcode)
- rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
- else
- rep_etypestr[0] = 0;
unparse_and_limit(ctx, cprinc, &cname);
logcname = (cname != NULL) ? cname : "<unknown client>";
@@ -151,10 +148,14 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
name (useful), and doesn't log ktypestr (probably not
important). */
if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) {
+ ktypestr = ktypes2str(request->ktype, request->nktypes);
+ rep_etypestr = rep_etypes2str(reply);
krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s "
"%s for %s%s%s"),
- ktypestr, fromstring, status, (unsigned int)authtime,
- rep_etypestr, !errcode ? "," : "", logcname, logsname,
+ ktypestr ? ktypestr : "", fromstring, status,
+ (unsigned int)authtime,
+ rep_etypestr ? rep_etypestr : "",
+ !errcode ? "," : "", logcname, logsname,
errcode ? ", " : "", errcode ? emsg : "");
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION))
krb5_klog_syslog(LOG_INFO,
@@ -171,9 +172,8 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
fromstring, status, (unsigned int)authtime,
logcname, logsname, logaltcname);
- /* OpenSolaris: audit_krb5kdc_tgs_req(...) or
- audit_krb5kdc_tgs_req_2ndtktmm(...) */
-
+ free(rep_etypestr);
+ free(ktypestr);
krb5_free_unparsed_name(ctx, cname);
krb5_free_unparsed_name(ctx, sname);
krb5_free_unparsed_name(ctx, altcname);
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 0155c28c6..f5c581c82 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1043,84 +1043,87 @@ void limit_string(char *name)
return;
}
-/*
- * L10_2 = log10(2**x), rounded up; log10(2) ~= 0.301.
- */
-#define L10_2(x) ((int)(((x * 301) + 999) / 1000))
-
-/*
- * Max length of sprintf("%ld") for an int of type T; includes leading
- * minus sign and terminating NUL.
- */
-#define D_LEN(t) (L10_2(sizeof(t) * CHAR_BIT) + 2)
-
-void
-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype)
+/* Wrapper of krb5_enctype_to_name() to include the PKINIT types. */
+static krb5_error_code
+enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
{
- int i;
- char stmp[D_LEN(krb5_enctype) + 1];
- char *p;
+ char *name;
- if (nktypes < 0
- || len < (sizeof(" etypes {...}") + D_LEN(int))) {
- *s = '\0';
- return;
- }
+ if (buflen == 0)
+ return EINVAL;
+ *buf = '\0'; /* ensure these are always valid C-strings */
- snprintf(s, len, "%d etypes {", nktypes);
- for (i = 0; i < nktypes; i++) {
- snprintf(stmp, sizeof(stmp), "%s%ld", i ? " " : "", (long)ktype[i]);
- if (strlen(s) + strlen(stmp) + sizeof("}") > len)
- break;
- strlcat(s, stmp, len);
- }
- if (i < nktypes) {
- /*
- * We broke out of the loop. Try to truncate the list.
- */
- p = s + strlen(s);
- while (p - s + sizeof("...}") > len) {
- while (p > s && *p != ' ' && *p != '{')
- *p-- = '\0';
- if (p > s && *p == ' ') {
- *p-- = '\0';
- continue;
- }
- }
- strlcat(s, "...", len);
- }
- strlcat(s, "}", len);
- return;
+ /* rfc4556 recommends that clients wishing to indicate support for these
+ * pkinit algorithms include them in the etype field of the AS-REQ. */
+ if (ktype == ENCTYPE_DSA_SHA1_CMS)
+ name = "id-dsa-with-sha1-CmsOID";
+ else if (ktype == ENCTYPE_MD5_RSA_CMS)
+ name = "md5WithRSAEncryption-CmsOID";
+ else if (ktype == ENCTYPE_SHA1_RSA_CMS)
+ name = "sha-1WithRSAEncryption-CmsOID";
+ else if (ktype == ENCTYPE_RC2_CBC_ENV)
+ name = "rc2-cbc-EnvOID";
+ else if (ktype == ENCTYPE_RSA_ENV)
+ name = "rsaEncryption-EnvOID";
+ else if (ktype == ENCTYPE_RSA_ES_OAEP_ENV)
+ name = "id-RSAES-OAEP-EnvOID";
+ else if (ktype == ENCTYPE_DES3_CBC_ENV)
+ name = "des-ede3-cbc-EnvOID";
+ else
+ return krb5_enctype_to_name(ktype, FALSE, buf, buflen);
+
+ if (strlcpy(name, buf, buflen) >= buflen)
+ return ENOMEM;
+ return 0;
}
-void
-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep)
+char *
+ktypes2str(krb5_enctype *ktype, int nktypes)
{
- char stmp[sizeof("ses=") + D_LEN(krb5_enctype)];
+ struct k5buf buf;
+ int i;
+ char name[64];
- if (len < (3 * D_LEN(krb5_enctype)
- + sizeof("etypes {rep= tkt= ses=}"))) {
- *s = '\0';
- return;
+ if (nktypes < 0)
+ return NULL;
+
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add_fmt(&buf, "%d etypes {", nktypes);
+ for (i = 0; i < nktypes; i++) {
+ enctype_name(ktype[i], name, sizeof(name));
+ k5_buf_add_fmt(&buf, "%s%s(%ld)", i ? ", " : "", name, (long)ktype[i]);
}
+ k5_buf_add(&buf, "}");
+ return buf.data;
+}
- snprintf(s, len, "etypes {rep=%ld", (long)rep->enc_part.enctype);
+char *
+rep_etypes2str(krb5_kdc_rep *rep)
+{
+ struct k5buf buf;
+ char name[64];
+ krb5_enctype etype;
+
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add(&buf, "etypes {rep=");
+ enctype_name(rep->enc_part.enctype, name, sizeof(name));
+ k5_buf_add_fmt(&buf, "%s(%ld)", name, (long)rep->enc_part.enctype);
if (rep->ticket != NULL) {
- snprintf(stmp, sizeof(stmp),
- " tkt=%ld", (long)rep->ticket->enc_part.enctype);
- strlcat(s, stmp, len);
+ etype = rep->ticket->enc_part.enctype;
+ enctype_name(etype, name, sizeof(name));
+ k5_buf_add_fmt(&buf, ", tkt=%s(%ld)", name, (long)etype);
}
- if (rep->ticket != NULL
- && rep->ticket->enc_part2 != NULL
- && rep->ticket->enc_part2->session != NULL) {
- snprintf(stmp, sizeof(stmp), " ses=%ld",
- (long)rep->ticket->enc_part2->session->enctype);
- strlcat(s, stmp, len);
+ if (rep->ticket != NULL && rep->ticket->enc_part2 != NULL &&
+ rep->ticket->enc_part2->session != NULL) {
+ etype = rep->ticket->enc_part2->session->enctype;
+ enctype_name(etype, name, sizeof(name));
+ k5_buf_add_fmt(&buf, ", ses=%s(%ld)", name, (long)etype);
}
- strlcat(s, "}", len);
- return;
+
+ k5_buf_add(&buf, "}");
+ return buf.data;
}
static krb5_error_code
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 6ec645fc3..25077cbf5 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -110,11 +110,9 @@ select_session_keytype (kdc_realm_t *kdc_active_realm,
void limit_string (char *name);
-void
-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype);
+char *ktypes2str(krb5_enctype *ktype, int nktypes);
-void
-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep);
+char *rep_etypes2str(krb5_kdc_rep *rep);
/* authind.c */
krb5_boolean

View file

@ -1,250 +0,0 @@
From 6d265afd53ead9290948b5ba07438b6a91939bfd Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 10 Jan 2019 16:34:54 -0500
Subject: [PATCH] Mark deprecated enctypes when used
Preface ETYPE_DEPRECATED enctypes with "DEPRECATED:" in klist output,
KDC logs, and kadmin interactions. Also complain in krb5kdc when the
stash file has a deprecated enctype or a deprecated enctype is
requested with -k.
ticket: 8773 (new)
(cherry picked from commit 8d8e68283b599e680f9fe45eff8af397e827bd6c)
---
src/clients/klist/klist.c | 14 ++++++++++----
src/kadmin/cli/kadmin.c | 6 +++++-
src/kdc/kdc_util.c | 9 +++++++++
src/kdc/main.c | 19 +++++++++++++++++++
src/tests/gssapi/t_enctypes.py | 15 +++++++++------
src/tests/t_keyrollover.py | 8 +++++---
src/tests/t_sesskeynego.py | 4 ++--
7 files changed, 59 insertions(+), 16 deletions(-)
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index 70adb54e8..8c307151a 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -571,11 +571,17 @@ static char *
etype_string(krb5_enctype enctype)
{
static char buf[100];
- krb5_error_code ret;
+ char *bp = buf;
+ size_t deplen, buflen = sizeof(buf);
- ret = krb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf));
- if (ret)
- snprintf(buf, sizeof(buf), "etype %d", enctype);
+ if (krb5int_c_deprecated_enctype(enctype)) {
+ deplen = strlcpy(bp, "DEPRECATED:", buflen);
+ buflen -= deplen;
+ bp += deplen;
+ }
+
+ if (krb5_enctype_to_name(enctype, FALSE, bp, buflen))
+ snprintf(bp, buflen, "etype %d", enctype);
return buf;
}
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
index ed581ee79..cc74921bf 100644
--- a/src/kadmin/cli/kadmin.c
+++ b/src/kadmin/cli/kadmin.c
@@ -1451,12 +1451,16 @@ kadmin_getprinc(int argc, char *argv[])
for (i = 0; i < dprinc.n_key_data; i++) {
krb5_key_data *key_data = &dprinc.key_data[i];
char enctype[BUFSIZ], salttype[BUFSIZ];
+ char *deprecated = "";
if (krb5_enctype_to_name(key_data->key_data_type[0], FALSE,
enctype, sizeof(enctype)))
snprintf(enctype, sizeof(enctype), _("<Encryption type 0x%x>"),
key_data->key_data_type[0]);
- printf("Key: vno %d, %s", key_data->key_data_kvno, enctype);
+ if (krb5int_c_deprecated_enctype(key_data->key_data_type[0]))
+ deprecated = "DEPRECATED:";
+ printf("Key: vno %d, %s%s", key_data->key_data_kvno, deprecated,
+ enctype);
if (key_data->key_data_ver > 1 &&
key_data->key_data_type[1] != KRB5_KDB_SALTTYPE_NORMAL) {
if (krb5_salttype_to_string(key_data->key_data_type[1],
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index f5c581c82..96c88edc1 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1048,11 +1048,20 @@ static krb5_error_code
enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
{
char *name;
+ size_t len;
if (buflen == 0)
return EINVAL;
*buf = '\0'; /* ensure these are always valid C-strings */
+ if (krb5int_c_deprecated_enctype(ktype)) {
+ len = strlcpy(buf, "DEPRECATED:", buflen);
+ if (len >= buflen)
+ return ENOMEM;
+ buflen -= len;
+ buf += len;
+ }
+
/* rfc4556 recommends that clients wishing to indicate support for these
* pkinit algorithms include them in the etype field of the AS-REQ. */
if (ktype == ENCTYPE_DSA_SHA1_CMS)
diff --git a/src/kdc/main.c b/src/kdc/main.c
index 663fd6303..60092a0df 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -210,12 +210,23 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
char *svalue = NULL;
const char *hierarchy[4];
krb5_kvno mkvno = IGNORE_VNO;
+ char ename[32];
memset(rdp, 0, sizeof(kdc_realm_t));
if (!realm) {
kret = EINVAL;
goto whoops;
}
+
+ if (def_enctype != ENCTYPE_UNKNOWN &&
+ krb5int_c_deprecated_enctype(def_enctype)) {
+ if (krb5_enctype_to_name(def_enctype, FALSE, ename, sizeof(ename)))
+ ename[0] = '\0';
+ fprintf(stderr,
+ _("Requested master password enctype %s in %s is DEPRECATED!"),
+ ename, realm);
+ }
+
hierarchy[0] = KRB5_CONF_REALMS;
hierarchy[1] = realm;
hierarchy[3] = NULL;
@@ -370,6 +381,14 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
goto whoops;
}
+ if (krb5int_c_deprecated_enctype(rdp->realm_mkey.enctype)) {
+ if (krb5_enctype_to_name(rdp->realm_mkey.enctype, FALSE, ename,
+ sizeof(ename)))
+ ename[0] = '\0';
+ fprintf(stderr, _("Stash file %s uses DEPRECATED enctype %s!"),
+ rdp->realm_stash, ename);
+ }
+
if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc,
&rdp->realm_mkey))) {
kdc_err(rdp->realm_context, kret,
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index 5d9f80e04..ca3d32d21 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -9,8 +9,11 @@ from k5test import *
aes256 = 'aes256-cts-hmac-sha1-96'
aes128 = 'aes128-cts-hmac-sha1-96'
des3 = 'des3-cbc-sha1'
+d_des3 = 'DEPRECATED:des3-cbc-sha1'
des3raw = 'des3-cbc-raw'
+d_des3raw = 'DEPRECATED:des3-cbc-raw'
rc4 = 'arcfour-hmac'
+d_rc4 = 'DEPRECATED:arcfour-hmac'
# These tests make assumptions about the default enctype lists, so set
# them explicitly rather than relying on the library defaults.
@@ -92,7 +95,7 @@ test_err('acc aes128', None, 'aes128-cts',
# no acceptor subkey will be generated because we can't upgrade to a
# CFX enctype.
test('init des3', 'des3', None,
- tktenc=aes256, tktsession=des3,
+ tktenc=aes256, tktsession=d_des3,
proto='rfc1964', isubkey=des3raw, asubkey=None)
# Force the ticket session key to be rc4, so we can test some subkey
@@ -103,7 +106,7 @@ realm.run([kadminl, 'setstr', realm.host_princ, 'session_enctypes', 'rc4'])
# [aes256 aes128 des3] and the acceptor should upgrade to an aes256
# subkey.
test('upgrade noargs', None, None,
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='cfx', isubkey=rc4, asubkey=aes256)
# If the initiator won't permit rc4 as a session key, it won't be able
@@ -113,14 +116,14 @@ test_err('upgrade init aes', 'aes', None, 'no support for encryption type')
# If the initiator permits rc4 but prefers aes128, it will send an
# upgrade list of [aes128] and the acceptor will upgrade to aes128.
test('upgrade init aes128+rc4', 'aes128-cts rc4', None,
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='cfx', isubkey=rc4, asubkey=aes128)
# If the initiator permits rc4 but prefers des3, it will send an
# upgrade list of [des3], but the acceptor won't generate a subkey
# because des3 isn't a CFX enctype.
test('upgrade init des3+rc4', 'des3 rc4', None,
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='rfc1964', isubkey=rc4, asubkey=None)
# If the acceptor permits only aes128, subkey negotiation will fail
@@ -134,14 +137,14 @@ test_err('upgrade acc aes128', None, 'aes128-cts',
# If the acceptor permits rc4 but prefers aes128, it will negotiate an
# upgrade to aes128.
test('upgrade acc aes128 rc4', None, 'aes128-cts rc4',
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='cfx', isubkey=rc4, asubkey=aes128)
# In this test, the initiator and acceptor each prefer an AES enctype
# to rc4, but they can't agree on which one, so no subkey is
# generated.
test('upgrade mismatch', 'aes128-cts rc4', 'aes256-cts rc4',
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='rfc1964', isubkey=rc4, asubkey=None)
success('gss_krb5_set_allowable_enctypes tests')
diff --git a/src/tests/t_keyrollover.py b/src/tests/t_keyrollover.py
index 7c8d828f0..4af6804f2 100755
--- a/src/tests/t_keyrollover.py
+++ b/src/tests/t_keyrollover.py
@@ -22,8 +22,9 @@ realm.run([kvno, princ1])
realm.run([kadminl, 'purgekeys', realm.krbtgt_princ])
# Make sure an old TGT fails after purging old TGS key.
realm.run([kvno, princ2], expected_code=1)
-msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): des-cbc-crc, des-cbc-crc' % \
- (realm.realm, realm.realm)
+ddes = "DEPRECATED:des-cbc-crc"
+msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): %s, %s' % \
+ (realm.realm, realm.realm, ddes, ddes)
realm.run([klist, '-e'], expected_msg=msg)
# Check that new key actually works.
@@ -48,7 +49,8 @@ realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts',
realm.krbtgt_princ])
realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ])
out = realm.run([kadminl, 'getprinc', realm.krbtgt_princ])
-if 'vno 1, aes256' not in out or 'vno 1, des3' not in out:
+if 'vno 1, aes256-cts' not in out or \
+ 'vno 1, DEPRECATED:des3-cbc-sha1' not in out:
fail('keyrollover: setup for TGS enctype test failed')
# Now present the DES3 ticket to the KDC and make sure it's rejected.
realm.run([kvno, realm.host_princ], expected_code=1)
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
index 448092387..da02f224a 100755
--- a/src/tests/t_sesskeynego.py
+++ b/src/tests/t_sesskeynego.py
@@ -62,11 +62,11 @@ test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
# 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term.
realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
'rc4-hmac,aes128-cts,aes256-cts'])
-test_kvno(realm, 'arcfour-hmac', 'aes256-cts-hmac-sha1-96')
+test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
# 3c: Test des-cbc-crc default assumption.
realm.run([kadminl, 'delstr', 'server', 'session_enctypes'])
-test_kvno(realm, 'des-cbc-crc', 'aes256-cts-hmac-sha1-96')
+test_kvno(realm, 'DEPRECATED:des-cbc-crc', 'aes256-cts-hmac-sha1-96')
realm.stop()
# Last go: test that we can disable the des-cbc-crc assumption

View file

@ -1,33 +0,0 @@
From ec9e4597188234e402cd318aebe0fa0a3587a993 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 14 Feb 2019 11:50:35 -0500
Subject: [PATCH] Properly size #ifdef in k5_cccol_lock()
The cleanup code only could get executed in the USE_CCAPI_V3 case, so
move it inside that block. Reported by Coverity.
(cherry picked from commit 444a15f9cf82b9a6c1bca3f20307f82fee91c228)
---
src/lib/krb5/ccache/ccbase.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
index 8198f2b9b..2702bef69 100644
--- a/src/lib/krb5/ccache/ccbase.c
+++ b/src/lib/krb5/ccache/ccbase.c
@@ -511,7 +511,6 @@ krb5_cccol_lock(krb5_context context)
#endif
#ifdef USE_CCAPI_V3
ret = krb5_stdccv3_context_lock(context);
-#endif
if (ret) {
k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
k5_cc_mutex_unlock(context, &krb5int_cc_file_mutex);
@@ -519,6 +518,7 @@ krb5_cccol_lock(krb5_context context)
k5_cc_mutex_unlock(context, &cccol_lock);
return ret;
}
+#endif
k5_mutex_unlock(&cc_typelist_lock);
return ret;
}

File diff suppressed because it is too large Load diff

View file

@ -1,34 +0,0 @@
From 1f214b1265bde1d8f6c9b99af0755ca8f5463385 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 3 Apr 2019 16:01:22 -0400
Subject: [PATCH] Remove ccapi-related comments in configure.ac
These suggested ccapi is buildable on non-Windows, and empirically it
is not.
(cherry picked from commit eb48b176bccf3634b9c82f588dce85125a5c4bd8)
---
src/configure.in | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/configure.in b/src/configure.in
index 7c309a26b..8d781a7c8 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1450,7 +1450,6 @@ V5_AC_OUTPUT_MAKEFILE(.
lib/crypto/crypto_tests
lib/krb5 lib/krb5/error_tables lib/krb5/asn.1 lib/krb5/ccache
-dnl lib/krb5/ccache/ccapi
lib/krb5/keytab lib/krb5/krb lib/krb5/rcache lib/krb5/os
lib/krb5/unicode
@@ -1463,8 +1462,6 @@ dnl lib/krb5/ccache/ccapi
lib/krad
lib/apputils
-dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test
-
kdc kprop config-files build-tools man doc include
plugins/certauth/test

View file

@ -1,430 +0,0 @@
From 32a6caec15bafd37fdf5746c08cf1a385166020e Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 3 Apr 2019 14:58:19 -0400
Subject: [PATCH] Remove confvalidator utility
This utility has not been maintained with encryption types and salt
changes, which suggests it is unused.
(cherry picked from commit 482a366793d9338e9edb504b407d7704a4bb2f8f)
---
src/util/confvalidator/README | 25 ----
src/util/confvalidator/confparser.py | 144 -------------------
src/util/confvalidator/rules.yml | 13 --
src/util/confvalidator/validator.conf | 2 -
src/util/confvalidator/validator.py | 194 --------------------------
5 files changed, 378 deletions(-)
delete mode 100644 src/util/confvalidator/README
delete mode 100644 src/util/confvalidator/confparser.py
delete mode 100644 src/util/confvalidator/rules.yml
delete mode 100644 src/util/confvalidator/validator.conf
delete mode 100644 src/util/confvalidator/validator.py
diff --git a/src/util/confvalidator/README b/src/util/confvalidator/README
deleted file mode 100644
index 7bf7a106a..000000000
--- a/src/util/confvalidator/README
+++ /dev/null
@@ -1,25 +0,0 @@
-validator.py is a command line tool for identifying invalid attributes, values and some formating problems in Kerberos configuration files.
-The list of the valid attributes is created based on the “configuration variables” section in k5-int.h and user defined attributes from the rules file.
-
-Usage:
-
-validator.py path [-d defPath] [-r rulesPath] [-c validatorConfPath]
-
-Options:
-
-path the path to the configuration file to validate
-
--d defPath path to the k5-int.h file. Starting from the 1.7 release this header holds the profile attribute names in the form #define KRB5_CONF_xxx ”ZZZ”.
-
--r rulesPath - path the rules file in yaml format. It may be used to manage the list of the valid attributes and to define the additional validation rules.
-
--c validatorConfPath the same as -r and -d options, but in validator configuration file format.
-
-Example:
-
-python validator.py src/config-files/krb5.conf -r rules.yml -d src/include/k5-int.h
-or
-python validator.py src/config-files/krb5.conf -c validator.conf
-
-For more details please refer to the sample files validator.conf and rules.yml
-
diff --git a/src/util/confvalidator/confparser.py b/src/util/confvalidator/confparser.py
deleted file mode 100644
index 2fea142a5..000000000
--- a/src/util/confvalidator/confparser.py
+++ /dev/null
@@ -1,144 +0,0 @@
-'''
-Created on Jan 31, 2010
-
-@author: tsitkova
-'''
-import re
-import copy
-import yaml
-
-class ConfParser(object):
- def __init__(self, path):
- self.configuration = self._parse(path)
-
- def walk(self):
- for trio in self._walk(self.configuration):
- yield trio
-
- def _parse(self, path):
- comment_pattern = re.compile(r'(\s*[#].*)')
- section_pattern = re.compile(r'^\s*\[(?P<section>\w+)\]\s+$')
- empty_pattern = re.compile(r'^\s*$')
- equalsign_pattern = re.compile(r'=')
-
- section = None
- parser_stack = list()
- result = dict()
- value = None
- f = open(path, 'r')
- for (ln,line) in enumerate(f):
- line = comment_pattern.sub('', line)
- line = equalsign_pattern.sub(' = ',line,count=1)
- if empty_pattern.match(line) is not None:
- continue
- m = section_pattern.match(line)
- if m is not None:
- section = m.group('section')
- value = dict()
- result[section] = value
- continue
- if section is None:
- msg = 'Failed to determine section for line #%i' % ln
- raise ValueError(msg)
- try:
- value = self._parseLine(value, line, parser_stack)
- except:
- print 'Error while parsing line %i: %s' % (ln+1, line)
- raise
- f.close()
-
- if len(parser_stack):
- raise 'Parsing error.'
-
- return result
-
- def _parseLine(self, value, content, stack):
- token_pattern = re.compile(r'(?P<token>\S+)(?=\s+)')
- attr = None
- token_stack = list()
-
- for m in token_pattern.finditer(content):
- token = m.group('token')
- if not self._validate(token):
- raise ValueError('Invalid token %s' % token)
- if token == '=':
- if len(token_stack) == 0:
- raise ValueError('Failed to find attribute.')
- elif len(token_stack) == 1:
- attr = token_stack.pop()
- else:
- value[attr] = token_stack[:-1]
- attr = token_stack[-1]
- token_stack = list()
- elif token == '{':
- if attr is None:
- raise ValueError('Failed to find attribute.')
- stack.append((attr,value))
- value = dict()
- elif token == '}':
- if len(stack) == 0:
- raise ValueError('Failed to parse: unbalanced braces')
- if len(token_stack):
- if attr is None:
- raise ValueError('Missing attribute')
- value[attr] = token_stack
- attr = None
- token_stack = list()
- (attr,parent_value) = stack.pop()
- parent_value[attr] = value
- value = parent_value
- else:
- token_stack.append(token)
- if len(token_stack):
- if attr is None:
- raise ValueError('Missing attribute')
- value[attr] = token_stack
-
- return value
-
- def _validate(self, token):
- result = True
- for s in ['{','}']:
- if s in token and s != token:
- result = False
-
- return result
-
- def _walk(self, parsedData, path='root'):
- dirs = list()
- av = list()
- for (key, value) in parsedData.iteritems():
- if type(value) == dict:
- new_path = path + '.' + key
- for trio in self._walk(value, new_path):
- yield trio
- dirs.append(key)
- else:
- av.append((key,value))
- yield (path, dirs, av)
-
-
-
-class ConfParserTest(ConfParser):
- def __init__(self):
- self.conf_path = '../tests/krb5.conf'
- super(ConfParserTest, self).__init__(self.conf_path)
-
- def run_tests(self):
- self._test_walk()
-
- def _test_parse(self):
- result = self._parse(self.conf_path)
- print yaml.dump(result)
-
- def _test_walk(self):
- configuration = self._parse(self.conf_path)
- for (path,dirs,av) in self.walk():
- print path,dirs,av
-
-
-
-
-if __name__ == '__main__':
- tester = ConfParserTest()
- tester.run_tests()
diff --git a/src/util/confvalidator/rules.yml b/src/util/confvalidator/rules.yml
deleted file mode 100644
index c6ccc89fe..000000000
--- a/src/util/confvalidator/rules.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Extend the list of the allowed enctypes and salts as needed
-Types:
- supported_enctypes:
- '(aes256-cts-hmac-sha1-96|aes256-cts|aes128-cts-hmac-sha1-96|aes128-cts|des3-hmac-sha1|des3-cbc-raw|des3-cbc-sha1|des3-hmac-sha1|rc4-hmac|arcfour-hmac-md5)(:(normal|v4))?$'
- default_tgs_enctypes:
- '(aes256-cts-hmac-sha1-96|aes256-cts|aes128-cts-hmac-sha1-96|aes128-cts|des3-hmac-sha1|des3-cbc-raw|des3-cbc-sha1|des3-hmac-sha1|rc4-hmac|arcfour-hmac-md5)'
- default_tkt_enctypes:
- '(aes256-cts-hmac-sha1-96|aes256-cts|aes128-cts-hmac-sha1-96|aes128-cts|des3-hmac-sha1|des3-cbc-raw|des3-cbc-sha1|des3-hmac-sha1|rc4-hmac|arcfour-hmac-md5)'
-
-# Add all valid profile attributes that are not listed in k5-int.h
-Attributes:
- - logging
- - dbmodules
diff --git a/src/util/confvalidator/validator.conf b/src/util/confvalidator/validator.conf
deleted file mode 100644
index 71e205c3b..000000000
--- a/src/util/confvalidator/validator.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-RulesPath=./rules.yml
-HfilePath=../../include/k5-int.h
diff --git a/src/util/confvalidator/validator.py b/src/util/confvalidator/validator.py
deleted file mode 100644
index d739bc091..000000000
--- a/src/util/confvalidator/validator.py
+++ /dev/null
@@ -1,194 +0,0 @@
-'''
-Created on Jan 25, 2010
-
-@author: tsitkova
-'''
-import os
-import sys
-import re
-import yaml
-from optparse import OptionParser
-from confparser import ConfParser
-
-class Rule(object):
- def __init__(self):
- pass
-
- def validate(self,node):
- (path,dirs,avs) = node
-
-
-class Validator(object):
- def __init__(self, kerberosPath, confPath=None, rulesPath=None, hfilePath=None):
- self.parser = ConfParser(kerberosPath)
- if confPath is not None:
- content = self._readConfigFile(confPath)
- rulesPath = content['RulesPath']
- hfilePath = content['HfilePath']
- if rulesPath is not None and hfilePath is not None:
- self.rules = self._loadRules(rulesPath)
- self.validKeys = SupportedKeys(hfilePath).validKeys.union(self.rules['Attributes'])
- else:
- raise ValueError('Invalid arguments for validator: no path to rules and definition files')
-
- self._attribute_pattern = re.compile(r'^\w+$')
- self._lowercase_pattern = re.compile(r'[a-z]')
-
- def _readConfigFile(self,path):
- f = open(path)
- result = dict()
- for line in f:
- line = line.rstrip()
- fields = line.split('=')
- result[fields[0]] = fields[1]
-
- return result
-
- def _loadRules(self, path):
- f = open(path)
- rules = yaml.load(f)
- f.close()
-
- return rules
-
- def validate(self):
- typeInfo = self.rules['Types']
-
- for node in self.parser.walk():
- self._validateTypes(node, typeInfo)
- self._validateAttrubutes(node, self.validKeys)
- # self._validateRealm(node)
-
-
- def _validateTypes(self, node, typeInfo):
- (path, dirs, avs) = node
- for (key, value) in avs:
- valid_type_pattern = typeInfo.get(key)
- if valid_type_pattern is not None:
- for t in value:
- if re.match(valid_type_pattern, t) is None:
- print 'Wrong type %s for attribute %s.%s' % (t,path,key)
-
- def _validateAttrubutes(self, node, validKeys):
- (path, dirs, avs) = node
- attributes = list()
- for attr in dirs:
- if self._attribute_pattern.match(attr) is not None:
- attributes.append(attr)
- for (attr, value) in avs:
- if self._attribute_pattern.match(attr) is not None:
- attributes.append(attr)
-
- for attr in attributes:
- if attr not in validKeys:
- print 'Unrecognized attribute %s at %s' % (attr, path)
-
-# def _validateRealm(self, node):
-# (path, dirs, avs) = node
-# if path == 'root.realms':
-# for attr in dirs:
-# if self._lowercase_pattern.search(attr) is not None:
-# print 'Lower case letter in realm attribute: %s at %s' % (attr, path)
-
-class SupportedKeys(object):
- def __init__(self, path):
- self.validKeys = self.getKeysFromHfile(path)
-
- def getKeysFromHfile(self, path):
- pattern = re.compile(r'^[#]define KRB5_CONF_\w+\s+["](\w+)["]')
- f = open(path)
- result = set()
- for l in f:
- l = l.rstrip()
- m = pattern.match(l)
- if m is not None:
- result.add(m.groups()[0])
- f.close()
-
- return result
-
-
-class ValidatorTest(Validator):
- def __init__(self):
- self.kerberosPath = '../tests/kdc1.conf'
- self.rulesPath = '../tests/rules.yml'
- self.hfilePath = '../tests/k5-int.h'
- self.confPath = '../tests/validator.conf'
-
- super(ValidatorTest, self).__init__(self.kerberosPath,
- rulesPath=self.rulesPath,
- hfilePath=self.hfilePath)
-
- def run_tests(self):
- self._test_validate()
-
- def _test__loadRules(self):
- result = self._loadRules(self.rulesPath)
- print result
-
- def _test_validate(self):
- self.validate()
-
- def _test__readConfigFile(self):
- result = self._readConfigFile(self.confPath)
- print result
-
-class SupportedKeysTest(SupportedKeys):
- def __init__(self):
- self.path = '../tests/k5-int.h'
-
- def run_tests(self):
- self._test_getKeysFromHFile()
-
- def _test_getKeysFromHFile(self):
- result = set()
- krb5keys = self.getKeysFromHfile(self.path)
- for key in krb5keys:
- print key
- result.update(key)
- print len(krb5keys)
-
- return result
-
-def _test():
- tester = ValidatorTest()
- krb5keys = tester.run_tests()
-
-if __name__ == '__main__':
- TEST = False
- if TEST:
- _test()
- sys.exit()
-
-
- usage = "\n\t%prog path [-d defPath] [-r rulesPath] [-c validatorConfPath]"
- description = 'Description: validates kerberos configuration file'
- parser = OptionParser(usage = usage, description = description)
- parser.add_option("-c", dest="confPath",
- help='path to validator config file')
- parser.add_option("-d", dest="hfilePath",
- help='path to h-file with attribute definition')
- parser.add_option("-r", dest="rulesPath",
- help='path to file with validation rules')
- (options, args) = parser.parse_args()
-
- if len(args) != 1 and len(sys.argv) <= 3:
- print '\n%s' % parser.get_usage()
- sys.exit()
-
- validator = None
- if options.confPath is not None:
- validator = Validator(args[0], confPath=options.confPath)
- elif options.hfilePath is not None and options.rulesPath is not None:
- validator = Validator(args[0], hfilePath=options.hfilePath, rulesPath=options.rulesPath)
- else:
- print '\nMust specify either configuration file or paths to rules and definitions files'
- print '%s' % parser.get_usage()
- sys.exit()
-
- validator.validate()
-
-
-
-
-

File diff suppressed because it is too large Load diff

View file

@ -1,466 +0,0 @@
From a2fc99321c797c1534f6314d17560c622ec93418 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 4 Apr 2019 16:14:46 -0400
Subject: [PATCH] Remove kadmin RPC support for setting v4 key
ticket: 8794 (new)
(cherry picked from commit 752187a441ed0f301f1a8adb1fea843080ac8c97)
---
src/kadmin/server/kadm_rpc_svc.c | 7 --
src/kadmin/server/ovsec_kadmd.c | 2 +-
src/kadmin/server/server_stubs.c | 50 ---------
src/lib/kadm5/admin.h | 3 -
src/lib/kadm5/admin_xdr.h | 1 -
src/lib/kadm5/clnt/Makefile.in | 2 +-
src/lib/kadm5/clnt/client_principal.c | 22 ----
src/lib/kadm5/clnt/client_rpc.c | 8 --
src/lib/kadm5/clnt/libkadm5clnt_mit.exports | 2 -
src/lib/kadm5/kadm_rpc.h | 16 +--
src/lib/kadm5/kadm_rpc_xdr.c | 19 ----
src/lib/kadm5/srv/Makefile.in | 2 +-
src/lib/kadm5/srv/libkadm5srv_mit.exports | 2 -
src/lib/kadm5/srv/svr_principal.c | 118 --------------------
14 files changed, 6 insertions(+), 248 deletions(-)
diff --git a/src/kadmin/server/kadm_rpc_svc.c b/src/kadmin/server/kadm_rpc_svc.c
index 41fc88ac8..d343e2c25 100644
--- a/src/kadmin/server/kadm_rpc_svc.c
+++ b/src/kadmin/server/kadm_rpc_svc.c
@@ -53,7 +53,6 @@ void kadm_1(rqstp, transp)
mpol_arg modify_policy_2_arg;
gpol_arg get_policy_2_arg;
setkey_arg setkey_principal_2_arg;
- setv4key_arg setv4key_principal_2_arg;
cprinc3_arg create_principal3_2_arg;
chpass3_arg chpass_principal3_2_arg;
chrand3_arg chrand_principal3_2_arg;
@@ -134,12 +133,6 @@ void kadm_1(rqstp, transp)
local = (bool_t (*)()) chpass_principal_2_svc;
break;
- case SETV4KEY_PRINCIPAL:
- xdr_argument = xdr_setv4key_arg;
- xdr_result = xdr_generic_ret;
- local = (bool_t (*)()) setv4key_principal_2_svc;
- break;
-
case SETKEY_PRINCIPAL:
xdr_argument = xdr_setkey_arg;
xdr_result = xdr_generic_ret;
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 6a6b21401..3737791b6 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -227,7 +227,7 @@ log_badverf(gss_name_t client_name, gss_name_t server_name,
{14, "GET_PRINCS"},
{15, "GET_POLS"},
{16, "SETKEY_PRINCIPAL"},
- {17, "SETV4KEY_PRINCIPAL"},
+ /* 17 was "SETV4KEY_PRINCIPAL" */
{18, "CREATE_PRINCIPAL3"},
{19, "CHPASS_PRINCIPAL3"},
{20, "CHRAND_PRINCIPAL3"},
diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c
index cfef97fec..d5a25e502 100644
--- a/src/kadmin/server/server_stubs.c
+++ b/src/kadmin/server/server_stubs.c
@@ -893,56 +893,6 @@ exit_func:
return TRUE;
}
-bool_t
-setv4key_principal_2_svc(setv4key_arg *arg, generic_ret *ret,
- struct svc_req *rqstp)
-{
- char *prime_arg = NULL;
- gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER;
- kadm5_server_handle_t handle;
- const char *errmsg = NULL;
-
- ret->code = stub_setup(arg->api_version, rqstp, arg->princ, &handle,
- &ret->api_version, &client_name, &service_name,
- &prime_arg);
- if (ret->code)
- goto exit_func;
-
- ret->code = check_lockdown_keys(handle, arg->princ);
- if (ret->code != KADM5_OK) {
- if (ret->code == KADM5_PROTECT_KEYS) {
- log_unauth("kadm5_setv4key_principal", prime_arg, &client_name,
- &service_name, rqstp);
- ret->code = KADM5_AUTH_SETKEY;
- }
- } else if (!(CHANGEPW_SERVICE(rqstp)) &&
- stub_auth(handle, OP_SETKEY, arg->princ, NULL, NULL, NULL)) {
- ret->code = kadm5_setv4key_principal(handle, arg->princ,
- arg->keyblock);
- } else {
- log_unauth("kadm5_setv4key_principal", prime_arg,
- &client_name, &service_name, rqstp);
- ret->code = KADM5_AUTH_SETKEY;
- }
-
- if (ret->code != KADM5_AUTH_SETKEY) {
- if (ret->code != 0)
- errmsg = krb5_get_error_message(handle->context, ret->code);
-
- log_done("kadm5_setv4key_principal", prime_arg, errmsg,
- &client_name, &service_name, rqstp);
-
- if (errmsg != NULL)
- krb5_free_error_message(handle->context, errmsg);
- }
-
-exit_func:
- stub_cleanup(handle, prime_arg, &client_name, &service_name);
- return TRUE;
-}
-
-
bool_t
setkey_principal_2_svc(setkey_arg *arg, generic_ret *ret,
struct svc_req *rqstp)
diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h
index b765148b3..7268be44e 100644
--- a/src/lib/kadm5/admin.h
+++ b/src/lib/kadm5/admin.h
@@ -394,9 +394,6 @@ kadm5_ret_t kadm5_randkey_principal_3(void *server_handle,
krb5_key_salt_tuple *ks_tuple,
krb5_keyblock **keyblocks,
int *n_keys);
-kadm5_ret_t kadm5_setv4key_principal(void *server_handle,
- krb5_principal principal,
- krb5_keyblock *keyblock);
kadm5_ret_t kadm5_setkey_principal(void *server_handle,
krb5_principal principal,
diff --git a/src/lib/kadm5/admin_xdr.h b/src/lib/kadm5/admin_xdr.h
index 2d22611e7..9da98451e 100644
--- a/src/lib/kadm5/admin_xdr.h
+++ b/src/lib/kadm5/admin_xdr.h
@@ -37,7 +37,6 @@ bool_t xdr_mprinc_arg(XDR *xdrs, mprinc_arg *objp);
bool_t xdr_rprinc_arg(XDR *xdrs, rprinc_arg *objp);
bool_t xdr_chpass_arg(XDR *xdrs, chpass_arg *objp);
bool_t xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp);
-bool_t xdr_setv4key_arg(XDR *xdrs, setv4key_arg *objp);
bool_t xdr_setkey_arg(XDR *xdrs, setkey_arg *objp);
bool_t xdr_setkey3_arg(XDR *xdrs, setkey3_arg *objp);
bool_t xdr_setkey4_arg(XDR *xdrs, setkey4_arg *objp);
diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in
index a180e85cd..2bc385afe 100644
--- a/src/lib/kadm5/clnt/Makefile.in
+++ b/src/lib/kadm5/clnt/Makefile.in
@@ -3,7 +3,7 @@ BUILDTOP=$(REL)..$(S)..$(S)..
LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5
LIBBASE=kadm5clnt_mit
-LIBMAJOR=11
+LIBMAJOR=12
LIBMINOR=0
STOBJLISTS=../OBJS.ST OBJS.ST
SHLIB_EXPDEPS=\
diff --git a/src/lib/kadm5/clnt/client_principal.c b/src/lib/kadm5/clnt/client_principal.c
index 18714bf37..96d9d1932 100644
--- a/src/lib/kadm5/clnt/client_principal.c
+++ b/src/lib/kadm5/clnt/client_principal.c
@@ -273,28 +273,6 @@ kadm5_chpass_principal_3(void *server_handle,
return r.code;
}
-kadm5_ret_t
-kadm5_setv4key_principal(void *server_handle,
- krb5_principal princ,
- krb5_keyblock *keyblock)
-{
- setv4key_arg arg;
- generic_ret r = { 0, 0 };
- kadm5_server_handle_t handle = server_handle;
-
- CHECK_HANDLE(server_handle);
-
- arg.princ = princ;
- arg.keyblock = keyblock;
- arg.api_version = handle->api_version;
-
- if(princ == NULL || keyblock == NULL)
- return EINVAL;
- if (setv4key_principal_2(&arg, &r, handle->clnt))
- eret();
- return r.code;
-}
-
kadm5_ret_t
kadm5_setkey_principal(void *server_handle,
krb5_principal princ,
diff --git a/src/lib/kadm5/clnt/client_rpc.c b/src/lib/kadm5/clnt/client_rpc.c
index df5455fd8..d84d158b4 100644
--- a/src/lib/kadm5/clnt/client_rpc.c
+++ b/src/lib/kadm5/clnt/client_rpc.c
@@ -84,14 +84,6 @@ chpass_principal3_2(chpass3_arg *argp, generic_ret *res, CLIENT *clnt)
(xdrproc_t)xdr_generic_ret, (caddr_t)res, TIMEOUT);
}
-enum clnt_stat
-setv4key_principal_2(setv4key_arg *argp, generic_ret *res, CLIENT *clnt)
-{
- return clnt_call(clnt, SETV4KEY_PRINCIPAL,
- (xdrproc_t)xdr_setv4key_arg, (caddr_t)argp,
- (xdrproc_t)xdr_generic_ret, (caddr_t)res, TIMEOUT);
-}
-
enum clnt_stat
setkey_principal_2(setkey_arg *argp, generic_ret *res, CLIENT *clnt)
{
diff --git a/src/lib/kadm5/clnt/libkadm5clnt_mit.exports b/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
index f122b31ab..e41c8e4f7 100644
--- a/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
+++ b/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
@@ -44,7 +44,6 @@ kadm5_set_string
kadm5_setkey_principal
kadm5_setkey_principal_3
kadm5_setkey_principal_4
-kadm5_setv4key_principal
kadm5_unlock
krb5_aprof_finish
krb5_aprof_get_boolean
@@ -114,6 +113,5 @@ xdr_rprinc_arg
xdr_setkey3_arg
xdr_setkey4_arg
xdr_setkey_arg
-xdr_setv4key_arg
xdr_ui_4
kadm5_init_iprop
diff --git a/src/lib/kadm5/kadm_rpc.h b/src/lib/kadm5/kadm_rpc.h
index 8d7cf3b36..5099c6c14 100644
--- a/src/lib/kadm5/kadm_rpc.h
+++ b/src/lib/kadm5/kadm_rpc.h
@@ -82,13 +82,6 @@ struct chpass3_arg {
};
typedef struct chpass3_arg chpass3_arg;
-struct setv4key_arg {
- krb5_ui_4 api_version;
- krb5_principal princ;
- krb5_keyblock *keyblock;
-};
-typedef struct setv4key_arg setv4key_arg;
-
struct setkey_arg {
krb5_ui_4 api_version;
krb5_principal princ;
@@ -322,11 +315,9 @@ extern enum clnt_stat setkey_principal_2(setkey_arg *, generic_ret *,
CLIENT *);
extern bool_t setkey_principal_2_svc(setkey_arg *, generic_ret *,
struct svc_req *);
-#define SETV4KEY_PRINCIPAL 17
-extern enum clnt_stat setv4key_principal_2(setv4key_arg *, generic_ret *,
- CLIENT *);
-extern bool_t setv4key_principal_2_svc(setv4key_arg *, generic_ret *,
- struct svc_req *);
+
+/* 17 was SETV4KEY_PRINCIPAL (removed in 1.18). */
+
#define CREATE_PRINCIPAL3 18
extern enum clnt_stat create_principal3_2(cprinc3_arg *, generic_ret *,
CLIENT *);
@@ -380,7 +371,6 @@ extern bool_t xdr_gprincs_arg ();
extern bool_t xdr_gprincs_ret ();
extern bool_t xdr_chpass_arg ();
extern bool_t xdr_chpass3_arg ();
-extern bool_t xdr_setv4key_arg ();
extern bool_t xdr_setkey_arg ();
extern bool_t xdr_setkey3_arg ();
extern bool_t xdr_setkey4_arg ();
diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
index 2892d4147..745ee857e 100644
--- a/src/lib/kadm5/kadm_rpc_xdr.c
+++ b/src/lib/kadm5/kadm_rpc_xdr.c
@@ -710,25 +710,6 @@ xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp)
return (TRUE);
}
-bool_t
-xdr_setv4key_arg(XDR *xdrs, setv4key_arg *objp)
-{
- unsigned int n_keys = 1;
-
- if (!xdr_ui_4(xdrs, &objp->api_version)) {
- return (FALSE);
- }
- if (!xdr_krb5_principal(xdrs, &objp->princ)) {
- return (FALSE);
- }
- if (!xdr_array(xdrs, (caddr_t *) &objp->keyblock,
- &n_keys, ~0,
- sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
bool_t
xdr_setkey_arg(XDR *xdrs, setkey_arg *objp)
{
diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in
index 617d65666..89e6097cf 100644
--- a/src/lib/kadm5/srv/Makefile.in
+++ b/src/lib/kadm5/srv/Makefile.in
@@ -9,7 +9,7 @@ DEFINES = @HESIOD_DEFS@
##DOSLIBNAME = libkadm5srv.lib
LIBBASE=kadm5srv_mit
-LIBMAJOR=11
+LIBMAJOR=12
LIBMINOR=0
STOBJLISTS=../OBJS.ST OBJS.ST
diff --git a/src/lib/kadm5/srv/libkadm5srv_mit.exports b/src/lib/kadm5/srv/libkadm5srv_mit.exports
index 64ad5dd69..e3c04e690 100644
--- a/src/lib/kadm5/srv/libkadm5srv_mit.exports
+++ b/src/lib/kadm5/srv/libkadm5srv_mit.exports
@@ -45,7 +45,6 @@ kadm5_set_string
kadm5_setkey_principal
kadm5_setkey_principal_3
kadm5_setkey_principal_4
-kadm5_setv4key_principal
kadm5_unlock
kdb_delete_entry
kdb_free_entry
@@ -133,7 +132,6 @@ xdr_rprinc_arg
xdr_setkey3_arg
xdr_setkey4_arg
xdr_setkey_arg
-xdr_setv4key_arg
xdr_sstring_arg
xdr_ui_4
kadm5_init_iprop
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 9ab2c5a74..48cac0c11 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -1645,124 +1645,6 @@ done:
return ret;
}
-/*
- * kadm5_setv4key_principal:
- *
- * Set only ONE key of the principal, removing all others. This key
- * must have the DES_CBC_CRC enctype and is entered as having the
- * krb4 salttype. This is to enable things like kadmind4 to work.
- */
-kadm5_ret_t
-kadm5_setv4key_principal(void *server_handle,
- krb5_principal principal,
- krb5_keyblock *keyblock)
-{
- krb5_db_entry *kdb;
- osa_princ_ent_rec adb;
- krb5_timestamp now;
- kadm5_policy_ent_rec pol;
- krb5_keysalt keysalt;
- int i, kvno, ret;
- krb5_boolean have_pol = FALSE;
- kadm5_server_handle_t handle = server_handle;
- krb5_key_data tmp_key_data;
- krb5_keyblock *act_mkey;
-
- memset( &tmp_key_data, 0, sizeof(tmp_key_data));
-
- CHECK_HANDLE(server_handle);
-
- krb5_clear_error_message(handle->context);
-
- if (principal == NULL || keyblock == NULL)
- return EINVAL;
- if (hist_princ && /* this will be NULL when initializing the databse */
- ((krb5_principal_compare(handle->context,
- principal, hist_princ)) == TRUE))
- return KADM5_PROTECT_PRINCIPAL;
-
- if (keyblock->enctype != ENCTYPE_DES_CBC_CRC)
- return KADM5_SETV4KEY_INVAL_ENCTYPE;
-
- if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
- return(ret);
-
- for (kvno = 0, i=0; i<kdb->n_key_data; i++)
- if (kdb->key_data[i].key_data_kvno > kvno)
- kvno = kdb->key_data[i].key_data_kvno;
-
- if (kdb->key_data != NULL)
- cleanup_key_data(handle->context, kdb->n_key_data, kdb->key_data);
-
- kdb->key_data = calloc(1, sizeof(krb5_key_data));
- if (kdb->key_data == NULL)
- return ENOMEM;
- kdb->n_key_data = 1;
- keysalt.type = KRB5_KDB_SALTTYPE_V4;
- /* XXX data.magic? */
- keysalt.data.length = 0;
- keysalt.data.data = NULL;
-
- ret = kdb_get_active_mkey(handle, NULL, &act_mkey);
- if (ret)
- goto done;
-
- /* use tmp_key_data as temporary location and reallocate later */
- ret = krb5_dbe_encrypt_key_data(handle->context, act_mkey, keyblock,
- &keysalt, kvno + 1, kdb->key_data);
- if (ret) {
- goto done;
- }
-
- kdb->attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
-
- ret = krb5_timeofday(handle->context, &now);
- if (ret)
- goto done;
-
- if ((adb.aux_attributes & KADM5_POLICY)) {
- ret = get_policy(handle, adb.policy, &pol, &have_pol);
- if (ret)
- goto done;
- }
- if (have_pol) {
- if (pol.pw_max_life)
- kdb->pw_expiration = ts_incr(now, pol.pw_max_life);
- else
- kdb->pw_expiration = 0;
- } else {
- kdb->pw_expiration = 0;
- }
-
- ret = krb5_dbe_update_last_pwd_change(handle->context, kdb, now);
- if (ret)
- goto done;
-
- /* unlock principal on this KDC */
- kdb->fail_auth_count = 0;
-
- /* key data changed, let the database provider know */
- kdb->mask = KADM5_KEY_DATA | KADM5_FAIL_AUTH_COUNT;
-
- if ((ret = kdb_put_entry(handle, kdb, &adb)))
- goto done;
-
- ret = KADM5_OK;
-done:
- for (i = 0; i < tmp_key_data.key_data_ver; i++) {
- if (tmp_key_data.key_data_contents[i]) {
- memset (tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]);
- free (tmp_key_data.key_data_contents[i]);
- }
- }
-
- kdb_free_entry(handle, kdb, &adb);
- if (have_pol)
- kadm5_free_policy_ent(handle->lhandle, &pol);
-
- return ret;
-}
-
kadm5_ret_t
kadm5_setkey_principal(void *server_handle,
krb5_principal principal,

View file

@ -1,385 +0,0 @@
From 34bde16a10c0cf0f05732376b955af0302af155d Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 22 Jan 2019 18:34:58 -0500
Subject: [PATCH] Remove ovsec_adm_export dump format support
Dumping only suported single-DES principals. While importing still
functioned, it would only have been useful for extremely old (1.3-era)
KDCs.
ticket: 8798 (new)
(cherry picked from commit 23b93fd48bc445005436c5be98a7269b599b1800)
---
doc/admin/admin_commands/kdb5_util.rst | 11 +--
doc/admin/database.rst | 14 ----
src/kadmin/dbutil/dump.c | 109 ++-----------------------
src/kadmin/dbutil/kdb5_util.c | 4 +-
src/man/kdb5_util.man | 13 +--
src/tests/Makefile.in | 6 --
src/tests/t_dump.py | 8 --
7 files changed, 13 insertions(+), 152 deletions(-)
diff --git a/doc/admin/admin_commands/kdb5_util.rst b/doc/admin/admin_commands/kdb5_util.rst
index fee68261a..7dd54f797 100644
--- a/doc/admin/admin_commands/kdb5_util.rst
+++ b/doc/admin/admin_commands/kdb5_util.rst
@@ -136,7 +136,7 @@ dump
.. _kdb5_util_dump:
- **dump** [**-b7**\|\ **-ov**\|\ **-r13**\|\ **-r18**]
+ **dump** [**-b7**\|\ **-r13**\|\ **-r18**]
[**-verbose**] [**-mkey_convert**] [**-new_mkey_file**
*mkey_file*] [**-rev**] [**-recurse**] [*filename*
[*principals*...]]
@@ -151,9 +151,6 @@ load_dump version 7". If filename is not specified, or is the string
load_dump version 4"). This was the dump format produced on
releases prior to 1.2.2.
-**-ov**
- causes the dump to be in "ovsec_adm_export" format.
-
**-r13**
causes the dump to be in the Kerberos 5 1.3 format ("kdb5_util
load_dump version 5"). This was the dump format produced on
@@ -204,7 +201,7 @@ load
.. _kdb5_util_load:
- **load** [**-b7**\|\ **-ov**\|\ **-r13**\|\ **-r18**] [**-hash**]
+ **load** [**-b7**\|\ **-r13**\|\ **-r18**] [**-hash**]
[**-verbose**] [**-update**] *filename*
Loads a database dump from the named file into the named database. If
@@ -222,10 +219,6 @@ Options:
("kdb5_util load_dump version 4"). This was the dump format
produced on releases prior to 1.2.2.
-**-ov**
- requires the database to be in "ovsec_adm_import" format. Must be
- used with the **-update** option.
-
**-r13**
requires the database to be in Kerberos 5 1.3 format ("kdb5_util
load_dump version 5"). This was the dump format produced on
diff --git a/doc/admin/database.rst b/doc/admin/database.rst
index 2b02af3a0..113a680a6 100644
--- a/doc/admin/database.rst
+++ b/doc/admin/database.rst
@@ -393,20 +393,6 @@ To dump a single principal and later load it, updating the database:
If the database file exists, and the *-update* flag was not
given, *kdb5_util* will overwrite the existing database.
-Using kdb5_util to upgrade a master KDC from krb5 1.1.x:
-
-::
-
- shell% kdb5_util dump old-kdb-dump
- shell% kdb5_util dump -ov old-kdb-dump.ov
- [Create a new KDC installation, using the old stash file/master password]
- shell% kdb5_util load old-kdb-dump
- shell% kdb5_util load -update old-kdb-dump.ov
-
-The use of old-kdb-dump.ov for an extra dump and load is necessary
-to preserve per-principal policy information, which is not included in
-the default dump format of krb5 1.1.x.
-
.. note::
Using kdb5_util to dump and reload the principal database is
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index 8301a33d0..19f2cc230 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -484,83 +484,6 @@ dump_r1_11_policy(void *data, osa_policy_ent_t entry)
fprintf(arg->ofile, "\n");
}
-static void
-print_key_data(FILE *f, krb5_key_data *kd)
-{
- int c;
-
- fprintf(f, "%d\t%d\t", kd->key_data_type[0], kd->key_data_length[0]);
- for (c = 0; c < kd->key_data_length[0]; c++)
- fprintf(f, "%02x ", kd->key_data_contents[0][c]);
-}
-
-/* Output osa_adb_princ_ent data in a printable serialized format, suitable for
- * ovsec_adm_import consumption. */
-static krb5_error_code
-dump_ov_princ(krb5_context context, krb5_db_entry *entry, const char *name,
- FILE *fp, krb5_boolean verbose, krb5_boolean omit_nra)
-{
- char *princstr;
- unsigned int x;
- int y, foundcrc;
- krb5_tl_data tl_data;
- osa_princ_ent_rec adb;
- XDR xdrs;
- krb5_key_data *key_data;
-
- tl_data.tl_data_type = KRB5_TL_KADM_DATA;
- if (krb5_dbe_lookup_tl_data(context, entry, &tl_data) ||
- tl_data.tl_data_length == 0)
- return 0;
-
- memset(&adb, 0, sizeof(adb));
- xdrmem_create(&xdrs, (caddr_t)tl_data.tl_data_contents,
- tl_data.tl_data_length, XDR_DECODE);
- if (!xdr_osa_princ_ent_rec(&xdrs, &adb)) {
- xdr_destroy(&xdrs);
- return KADM5_XDR_FAILURE;
- }
- xdr_destroy(&xdrs);
-
- krb5_unparse_name(context, entry->princ, &princstr);
- fprintf(fp, "princ\t%s\t", princstr);
- if (adb.policy == NULL)
- fputc('\t', fp);
- else
- fprintf(fp, "%s\t", adb.policy);
- fprintf(fp, "%lx\t%d\t%d\t%d", adb.aux_attributes, adb.old_key_len,
- adb.old_key_next, adb.admin_history_kvno);
-
- for (x = 0; x < adb.old_key_len; x++) {
- foundcrc = 0;
- for (y = 0; y < adb.old_keys[x].n_key_data; y++) {
- key_data = &adb.old_keys[x].key_data[y];
- if (key_data->key_data_type[0] != ENCTYPE_DES_CBC_CRC)
- continue;
- if (foundcrc) {
- fprintf(stderr, _("Warning! Multiple DES-CBC-CRC keys for "
- "principal %s; skipping duplicates.\n"),
- princstr);
- continue;
- }
- foundcrc++;
-
- fputc('\t', fp);
- print_key_data(fp, key_data);
- }
- if (!foundcrc) {
- fprintf(stderr, _("Warning! No DES-CBC-CRC key for principal %s, "
- "cannot generate OV-compatible record; "
- "skipping\n"), princstr);
- }
- }
-
- fputc('\n', fp);
- free(princstr);
- xdr_free(xdr_osa_princ_ent_rec, &adb);
- return 0;
-}
-
static krb5_error_code
dump_iterator(void *ptr, krb5_db_entry *entry)
{
@@ -1101,14 +1024,6 @@ process_k5beta7_record(krb5_context context, const char *fname, FILE *filep,
process_k5beta7_princ, process_k5beta7_policy);
}
-static int
-process_ov_record(krb5_context context, const char *fname, FILE *filep,
- krb5_boolean verbose, int *linenop)
-{
- return process_tagged(context, fname, filep, verbose, linenop,
- process_ov_principal, process_k5beta7_policy);
-}
-
static int
process_r1_8_record(krb5_context context, const char *fname, FILE *filep,
krb5_boolean verbose, int *linenop)
@@ -1135,16 +1050,6 @@ dump_version beta7_version = {
dump_k5beta7_policy,
process_k5beta7_record,
};
-dump_version ov_version = {
- "OpenV*Secure V1.0",
- "OpenV*Secure V1.0\t",
- 1,
- 0,
- 0,
- dump_ov_princ,
- dump_k5beta7_policy,
- process_ov_record
-};
dump_version r1_3_version = {
"Kerberos version 5 release 1.3",
"kdb5_util load_dump version 5\n",
@@ -1267,7 +1172,7 @@ current_dump_sno_in_ulog(krb5_context context, const char *ifile)
/*
* usage is:
- * dump_db [-b7] [-ov] [-r13] [-r18] [-verbose] [-mkey_convert]
+ * dump_db [-b7] [-r13] [-r18] [-verbose] [-mkey_convert]
* [-new_mkey_file mkey_file] [-rev] [-recurse]
* [filename [principals...]]
*/
@@ -1302,7 +1207,8 @@ dump_db(int argc, char **argv)
if (!strcmp(argv[aindex], "-b7")) {
dump = &beta7_version;
} else if (!strcmp(argv[aindex], "-ov")) {
- dump = &ov_version;
+ fprintf(stderr, _("OV dump format not supported\n"));
+ goto error;
} else if (!strcmp(argv[aindex], "-r13")) {
dump = &r1_3_version;
} else if (!strcmp(argv[aindex], "-r18")) {
@@ -1515,8 +1421,7 @@ restore_dump(krb5_context context, char *dumpfile, FILE *f,
}
/*
- * Usage: load_db [-ov] [-b7] [-r13] [-r18] [-verbose] [-update] [-hash]
- * filename
+ * Usage: load_db [-b7] [-r13] [-r18] [-verbose] [-update] [-hash] filename
*/
void
load_db(int argc, char **argv)
@@ -1540,7 +1445,8 @@ load_db(int argc, char **argv)
if (!strcmp(argv[aindex], "-b7")){
load = &beta7_version;
} else if (!strcmp(argv[aindex], "-ov")) {
- load = &ov_version;
+ fprintf(stderr, _("OV dump format not supported\n"));
+ goto error;
} else if (!strcmp(argv[aindex], "-r13")) {
load = &r1_3_version;
} else if (!strcmp(argv[aindex], "-r18")){
@@ -1605,9 +1511,6 @@ load_db(int argc, char **argv)
load = &r1_8_version;
} else if (strcmp(buf, r1_11_version.header) == 0) {
load = &r1_11_version;
- } else if (strncmp(buf, ov_version.header,
- strlen(ov_version.header)) == 0) {
- load = &ov_version;
} else {
fprintf(stderr, _("%s: dump header bad in %s\n"), progname,
dumpfile);
diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c
index accc959e0..e73e2c68e 100644
--- a/src/kadmin/dbutil/kdb5_util.c
+++ b/src/kadmin/dbutil/kdb5_util.c
@@ -85,10 +85,10 @@ void usage()
"\tcreate [-s]\n"
"\tdestroy [-f]\n"
"\tstash [-f keyfile]\n"
- "\tdump [-old|-ov|-b6|-b7|-r13|-r18] [-verbose]\n"
+ "\tdump [-old|-b6|-b7|-r13|-r18] [-verbose]\n"
"\t [-mkey_convert] [-new_mkey_file mkey_file]\n"
"\t [-rev] [-recurse] [filename [princs...]]\n"
- "\tload [-old|-ov|-b6|-b7|-r13|-r18] [-verbose] [-update] "
+ "\tload [-old|-b6|-b7|-r13|-r18] [-verbose] [-update] "
"filename\n"
"\tark [-e etype_list] principal\n"
"\tadd_mkey [-e etype] [-s]\n"
diff --git a/src/man/kdb5_util.man b/src/man/kdb5_util.man
index 5ebc68a57..9a36ef0df 100644
--- a/src/man/kdb5_util.man
+++ b/src/man/kdb5_util.man
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KDB5_UTIL" "8" " " "1.17" "MIT Kerberos"
+.TH "KDB5_UTIL" "8" " " "1.18" "MIT Kerberos"
.SH NAME
kdb5_util \- Kerberos database maintenance utility
.
@@ -136,7 +136,7 @@ kdc.conf(5)\&.
.SS dump
.INDENT 0.0
.INDENT 3.5
-\fBdump\fP [\fB\-b7\fP|\fB\-ov\fP|\fB\-r13\fP|\fB\-r18\fP]
+\fBdump\fP [\fB\-b7\fP|\fB\-r13\fP|\fB\-r18\fP]
[\fB\-verbose\fP] [\fB\-mkey_convert\fP] [\fB\-new_mkey_file\fP
\fImkey_file\fP] [\fB\-rev\fP] [\fB\-recurse\fP] [\fIfilename\fP
[\fIprincipals\fP\&...]]
@@ -154,9 +154,6 @@ causes the dump to be in the Kerberos 5 Beta 7 format ("kdb5_util
load_dump version 4"). This was the dump format produced on
releases prior to 1.2.2.
.TP
-\fB\-ov\fP
-causes the dump to be in "ovsec_adm_export" format.
-.TP
\fB\-r13\fP
causes the dump to be in the Kerberos 5 1.3 format ("kdb5_util
load_dump version 5"). This was the dump format produced on
@@ -203,7 +200,7 @@ doing a normal dump instead of a recursive traversal.
.SS load
.INDENT 0.0
.INDENT 3.5
-\fBload\fP [\fB\-b7\fP|\fB\-ov\fP|\fB\-r13\fP|\fB\-r18\fP] [\fB\-hash\fP]
+\fBload\fP [\fB\-b7\fP|\fB\-r13\fP|\fB\-r18\fP] [\fB\-hash\fP]
[\fB\-verbose\fP] [\fB\-update\fP] \fIfilename\fP
.UNINDENT
.UNINDENT
@@ -224,10 +221,6 @@ requires the database to be in the Kerberos 5 Beta 7 format
("kdb5_util load_dump version 4"). This was the dump format
produced on releases prior to 1.2.2.
.TP
-\fB\-ov\fP
-requires the database to be in "ovsec_adm_import" format. Must be
-used with the \fB\-update\fP option.
-.TP
\fB\-r13\fP
requires the database to be in Kerberos 5 1.3 format ("kdb5_util
load_dump version 5"). This was the dump format produced on
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index e27617ee2..c96c5d6b7 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -97,7 +97,6 @@ kdb_check: kdc.conf krb5.conf
$(RUN_DB_TEST) ../tests/create/kdb5_mkdums $(KTEST_OPTS)
$(RUN_DB_TEST) ../tests/verify/kdb5_verify $(KTEST_OPTS)
$(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump $(TEST_DB).dump
- $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump -ov $(TEST_DB).ovdump
$(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f
@echo "====> NOTE!"
@echo "The following 'create' command is needed due to a change"
@@ -105,16 +104,11 @@ kdb_check: kdc.conf krb5.conf
@echo ====
$(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) create -W
$(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load $(TEST_DB).dump
- $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load -update -ov $(TEST_DB).ovdump
$(RUN_DB_TEST) ../tests/verify/kdb5_verify $(KTEST_OPTS)
$(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump $(TEST_DB).dump2
- $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump -ov $(TEST_DB).ovdump2
sort $(TEST_DB).dump > $(TEST_DB).sort
sort $(TEST_DB).dump2 > $(TEST_DB).sort2
- sort $(TEST_DB).ovdump > $(TEST_DB).ovsort
- sort $(TEST_DB).ovdump2 > $(TEST_DB).ovsort2
cmp $(TEST_DB).sort $(TEST_DB).sort2
- cmp $(TEST_DB).ovsort $(TEST_DB).ovsort2
$(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f
$(RM) $(TEST_DB)* stash_file
diff --git a/src/tests/t_dump.py b/src/tests/t_dump.py
index d803d5602..5d692df99 100755
--- a/src/tests/t_dump.py
+++ b/src/tests/t_dump.py
@@ -73,7 +73,6 @@ for realm in multidb_realms(start_kdc=False):
srcdump_r18 = os.path.join(srcdumpdir, 'dump.r18')
srcdump_r13 = os.path.join(srcdumpdir, 'dump.r13')
srcdump_b7 = os.path.join(srcdumpdir, 'dump.b7')
- srcdump_ov = os.path.join(srcdumpdir, 'dump.ov')
# Load a dump file from the source directory.
realm.run([kdb5_util, 'destroy', '-f'])
@@ -86,17 +85,10 @@ for realm in multidb_realms(start_kdc=False):
dump_compare(realm, ['-r18'], srcdump_r18)
dump_compare(realm, ['-r13'], srcdump_r13)
dump_compare(realm, ['-b7'], srcdump_b7)
- dump_compare(realm, ['-ov'], srcdump_ov)
# Load each format of dump, check it, re-dump it, and compare.
load_dump_check_compare(realm, ['-r18'], srcdump_r18)
load_dump_check_compare(realm, ['-r13'], srcdump_r13)
load_dump_check_compare(realm, ['-b7'], srcdump_b7)
- # Loading the last (-b7 format) dump won't have loaded the
- # per-principal kadm data. Load that incrementally with -ov.
- realm.run([kadminl, 'getprinc', 'user'], expected_msg='Policy: [none]')
- realm.run([kdb5_util, 'load', '-update', '-ov', srcdump_ov])
- realm.run([kadminl, 'getprinc', 'user'], expected_msg='Policy: testpol')
-
success('Dump/load tests')

File diff suppressed because it is too large Load diff

1
ci.fmf Normal file
View file

@ -0,0 +1 @@
resultsdb-testcase: separate

8
gating.yaml Normal file
View file

@ -0,0 +1,8 @@
--- !Policy
product_versions:
- fedora-*
decision_contexts:
- bodhi_update_push_stable
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tests.functional}

View file

@ -6,9 +6,9 @@ AssertPathExists=!/var/kerberos/krb5kdc/kpropd.acl
[Service]
Type=forking
PIDFile=/var/run/kadmind.pid
PIDFile=/run/kadmind.pid
EnvironmentFile=-/etc/sysconfig/kadmin
ExecStart=/usr/sbin/kadmind -P /var/run/kadmind.pid $KADMIND_ARGS
ExecStart=/usr/sbin/kadmind -P /run/kadmind.pid $KADMIND_ARGS
ExecReload=/bin/kill -HUP $MAINPID
[Install]

View file

@ -4,6 +4,6 @@
monthly
rotate 12
postrotate
/bin/kill -HUP `cat /var/run/kadmind.pid 2>/dev/null` 2> /dev/null || true
systemctl reload kadmin.service || true
endscript
}

View file

@ -1,3 +1,7 @@
[libdefaults]
# Allow RC4 HMAC-MD5 for session keys (see CVE-2022-37966)
#allow_rc4 = true
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
@ -5,9 +9,12 @@
[realms]
EXAMPLE.COM = {
#master_key_type = aes256-cts
master_key_type = aes256-cts-hmac-sha384-192
acl_file = /var/kerberos/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
default_principal_flags = +preauth
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal
supported_enctypes = aes256-cts-hmac-sha384-192:normal aes128-cts-hmac-sha256-128:normal aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal camellia256-cts-cmac:normal camellia128-cts-cmac:normal arcfour-hmac-md5:normal
# Supported encryption types for FIPS mode:
#supported_enctypes = aes256-cts-hmac-sha384-192:normal aes128-cts-hmac-sha256-128:normal
}

View file

@ -1,21 +0,0 @@
From 1da0d2fdbd9cb2ded1913e05664986dce1e1a916 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:52:01 -0400
Subject: [PATCH] krb5-1.11-kpasswdtest.patch
---
src/kadmin/testing/proto/krb5.conf.proto | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto
index 00c442978..9c4bc1de7 100644
--- a/src/kadmin/testing/proto/krb5.conf.proto
+++ b/src/kadmin/testing/proto/krb5.conf.proto
@@ -9,6 +9,7 @@
__REALM__ = {
kdc = __KDCHOST__:1750
admin_server = __KDCHOST__:1751
+ kpasswd_server = __KDCHOST__:1752
database_module = foobar_db2_module_blah
}

View file

@ -1,44 +0,0 @@
From c95d33cc1c66122bc229beb65d36f988fbd05e59 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:57 -0400
Subject: [PATCH] krb5-1.11-run_user_0.patch
A hack: if we're looking at creating a ccache directory directly below
the /run/user/0 directory, and /run/user/0 doesn't exist, try to create
it, too.
---
src/lib/krb5/ccache/cc_dir.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
index 73f0fe62d..4850c0d07 100644
--- a/src/lib/krb5/ccache/cc_dir.c
+++ b/src/lib/krb5/ccache/cc_dir.c
@@ -61,6 +61,8 @@
#include <dirent.h>
+#define ROOT_SPECIAL_DCC_PARENT "/run/user/0"
+
extern const krb5_cc_ops krb5_dcc_ops;
extern const krb5_cc_ops krb5_fcc_ops;
@@ -237,6 +239,18 @@ verify_dir(krb5_context context, const char *dirname)
if (stat(dirname, &st) < 0) {
if (errno == ENOENT) {
+ if (strncmp(dirname, ROOT_SPECIAL_DCC_PARENT "/",
+ sizeof(ROOT_SPECIAL_DCC_PARENT)) == 0 &&
+ stat(ROOT_SPECIAL_DCC_PARENT, &st) < 0 &&
+ errno == ENOENT) {
+#ifdef USE_SELINUX
+ selabel = krb5int_push_fscreatecon_for(ROOT_SPECIAL_DCC_PARENT);
+#endif
+ status = mkdir(ROOT_SPECIAL_DCC_PARENT, S_IRWXU);
+#ifdef USE_SELINUX
+ krb5int_pop_fscreatecon(selabel);
+#endif
+ }
#ifdef USE_SELINUX
selabel = krb5int_push_fscreatecon_for(dirname);
#endif

View file

@ -1,37 +0,0 @@
From 4ddac573dfc8fea30b5f8750c8c0733c553afcfa Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:00 -0400
Subject: [PATCH] krb5-1.12-api.patch
Reference docs don't define what happens if you call krb5_realm_compare() with
malformed krb5_principal structures. Define a behavior which keeps it from
crashing if applications don't check ahead of time.
---
src/lib/krb5/krb/princ_comp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lib/krb5/krb/princ_comp.c b/src/lib/krb5/krb/princ_comp.c
index a6936107d..0ed78833b 100644
--- a/src/lib/krb5/krb/princ_comp.c
+++ b/src/lib/krb5/krb/princ_comp.c
@@ -36,6 +36,10 @@ realm_compare_flags(krb5_context context,
const krb5_data *realm1 = &princ1->realm;
const krb5_data *realm2 = &princ2->realm;
+ if (princ1 == NULL || princ2 == NULL)
+ return FALSE;
+ if (realm1 == NULL || realm2 == NULL)
+ return FALSE;
if (realm1->length != realm2->length)
return FALSE;
if (realm1->length == 0)
@@ -88,6 +92,9 @@ krb5_principal_compare_flags(krb5_context context,
krb5_principal upn2 = NULL;
krb5_boolean ret = FALSE;
+ if (princ1 == NULL || princ2 == NULL)
+ return FALSE;
+
if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) {
/* Treat UPNs as if they were real principals */
if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) {

View file

@ -1,22 +0,0 @@
From e62b5022c129229e86f40f97d2e1c71a01d7227b Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:32:09 -0400
Subject: [PATCH] krb5-1.12-ksu-path.patch
Set the default PATH to the one set by login.
---
src/clients/ksu/Makefile.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
index 5755bb58a..9d58f29b5 100644
--- a/src/clients/ksu/Makefile.in
+++ b/src/clients/ksu/Makefile.in
@@ -1,6 +1,6 @@
mydir=clients$(S)ksu
BUILDTOP=$(REL)..$(S)..
-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
+DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"'
KSU_LIBS=@KSU_LIBS@
PAM_LIBS=@PAM_LIBS@

View file

@ -1,75 +0,0 @@
From 10f64f13ee3d44a31bcdc124e9ce721bc17b3e00 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:44 -0400
Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch
Treat 'nsAccountLock: true' the same as 'loginDisabled: true'. Updated from
original version filed as RT#5891.
---
src/aclocal.m4 | 9 +++++++++
src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 17 +++++++++++++++++
.../kdb/ldap/libkdb_ldap/ldap_principal.c | 3 +++
3 files changed, 29 insertions(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index db18226ed..518b1a547 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1678,6 +1678,15 @@ if test "$with_ldap" = yes; then
AC_MSG_NOTICE(enabling OpenLDAP database backend module support)
OPENLDAP_PLUGIN=yes
fi
+AC_ARG_WITH([dirsrv-account-locking],
+[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module],
+[case "$withval" in
+ yes | no) ;;
+ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;;
+esac], with_dirsrv_account_locking=no)
+if test $with_dirsrv_account_locking = yes; then
+ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.])
+fi
])dnl
dnl
dnl If libkeyutils exists (on Linux) include it and use keyring ccache
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
index 5b9d1e9fa..4e7270065 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
@@ -1652,6 +1652,23 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context,
ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data);
if (ret)
goto cleanup;
+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
+ {
+ krb5_timestamp expiretime=0;
+ char *is_login_disabled=NULL;
+
+ /* LOGIN DISABLED */
+ ret = krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled,
+ &attr_present);
+ if (ret)
+ goto cleanup;
+ if (attr_present == TRUE) {
+ if (strcasecmp(is_login_disabled, "TRUE")== 0)
+ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+ free (is_login_disabled);
+ }
+ }
+#endif
ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname);
if (ret)
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
index d722dbfa6..5e8e9a897 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
@@ -54,6 +54,9 @@ char *principal_attributes[] = { "krbprincipalname",
"krbLastFailedAuth",
"krbLoginFailedCount",
"krbLastSuccessfulAuth",
+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
+ "nsAccountLock",
+#endif
"krbLastPwdChange",
"krbLastAdminUnlock",
"krbPrincipalAuthInd",

View file

@ -1,70 +0,0 @@
From fd8c1f7e68fd999c07ca47243ef85ac726f775ce Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:45:26 -0400
Subject: [PATCH] krb5-1.15-beta1-buildconf.patch
Build binaries in this package as RELRO PIEs, libraries as partial RELRO,
and install shared libraries with the execute bit set on them. Prune out
the -L/usr/lib* and PIE flags where they might leak out and affect
apps which just want to link with the libraries. FIXME: needs to check and
not just assume that the compiler supports using these flags.
---
src/build-tools/krb5-config.in | 7 +++++++
src/config/pre.in | 2 +-
src/config/shlib.conf | 5 +++--
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
index c17cb5eb5..1891dea99 100755
--- a/src/build-tools/krb5-config.in
+++ b/src/build-tools/krb5-config.in
@@ -226,6 +226,13 @@ if test -n "$do_libs"; then
-e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \
-e 's#\$(CFLAGS)##'`
+ if test `dirname $libdir` = /usr ; then
+ lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"`
+ fi
+ lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"`
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"`
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"`
+
if test $library = 'kdb'; then
lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
library=krb5
diff --git a/src/config/pre.in b/src/config/pre.in
index 917357df9..a8540ae2a 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
INSTALL_SCRIPT=@INSTALL_PROGRAM@
INSTALL_DATA=@INSTALL_DATA@
INSTALL_SHLIB=@INSTALL_SHLIB@
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
+INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755
## This is needed because autoconf will sometimes define @exec_prefix@ to be
## ${prefix}.
prefix=@prefix@
diff --git a/src/config/shlib.conf b/src/config/shlib.conf
index 3e4af6c02..2b20c3fda 100644
--- a/src/config/shlib.conf
+++ b/src/config/shlib.conf
@@ -423,7 +423,7 @@ mips-*-netbsd*)
# Linux ld doesn't default to stuffing the SONAME field...
# Use objdump -x to examine the fields of the library
# UNDEF_CHECK is suppressed by --enable-asan
- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)'
+ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK) -Wl,-z,relro -Wl,--warn-shared-textrel'
UNDEF_CHECK='-Wl,--no-undefined'
# $(EXPORT_CHECK) runs export-check.pl when in maintainer mode.
LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)'
@@ -435,7 +435,8 @@ mips-*-netbsd*)
SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
PROFFLAGS=-pg
PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)'
- CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)'
+ CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)'
+ INSTALL_SHLIB='${INSTALL} -m755'
CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)'
CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)'

View file

@ -1,181 +0,0 @@
From 15c0aec4315cc5cfae864b179848f043e2b100c6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] krb5-1.17 Become FIPS-aware
A lot of the FIPS error conditions from OpenSSL are incredibly
mysterious (at best, things return NULL unexpectedly; at worst,
internal assertions are tripped; most of the time, you just get
ENOMEM). In order to cope with this, we need to have some level of
awareness of what we can and can't safely call.
This will slow down some calls slightly (FIPS_mode() takes multiple
locks), but not for any crypto we care about - which is to say that
AES is fine.
---
src/lib/crypto/openssl/enc_provider/camellia.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/des.c | 9 +++++++++
src/lib/crypto/openssl/enc_provider/des3.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/rc4.c | 13 ++++++++++++-
src/lib/crypto/openssl/hash_provider/hash_evp.c | 4 ++++
src/lib/crypto/openssl/hmac.c | 6 +++++-
6 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 2da691329..f79679a0b 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
struct iov_cursor cursor;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
if (output->length < CAMELLIA_BLOCK_SIZE)
return KRB5_BAD_MSIZE;
@@ -331,6 +334,9 @@ static krb5_error_code
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
krb5_data *state)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
state->length = 16;
state->data = (void *) malloc(16);
if (state->data == NULL)
diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c
index a662db512..7d17d287e 100644
--- a/src/lib/crypto/openssl/enc_provider/des.c
+++ b/src/lib/crypto/openssl/enc_provider/des.c
@@ -85,6 +85,9 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -182,6 +188,9 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
DES_key_schedule sched;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c
index 1c439c2cd..8be555a8d 100644
--- a/src/lib/crypto/openssl/enc_provider/des3.c
+++ b/src/lib/crypto/openssl/enc_provider/des3.c
@@ -84,6 +84,9 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index 7f3c086ed..a3f2a7442 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -66,6 +66,9 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx = NULL;
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
arcstate = (state != NULL) ? (struct arcfour_state *) state->data : NULL;
if (arcstate != NULL) {
ctx = arcstate->ctx;
@@ -113,7 +116,12 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
static void
k5_arcfour_free_state(krb5_data *state)
{
- struct arcfour_state *arcstate = (struct arcfour_state *) state->data;
+ struct arcfour_state *arcstate;
+
+ if (FIPS_mode())
+ return;
+
+ arcstate = (struct arcfour_state *) state->data;
EVP_CIPHER_CTX_free(arcstate->ctx);
free(arcstate);
@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
{
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
/* Create a state structure with an uninitialized context. */
arcstate = calloc(1, sizeof(*arcstate));
if (arcstate == NULL)
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index 957ed8d9c..8c1fd7f59 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -64,12 +64,16 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
static krb5_error_code
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md4(), data, num_data, output);
}
static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md5(), data, num_data, output);
}
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index b2db6ec02..d94d9ac94 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
return EVP_sha256();
else if (!strncmp(hash->hash_name, "SHA-384",7))
return EVP_sha384();
- else if (!strncmp(hash->hash_name, "MD5", 3))
+
+ if (FIPS_mode())
+ return NULL;
+
+ if (!strncmp(hash->hash_name, "MD5", 3))
return EVP_md5();
else if (!strncmp(hash->hash_name, "MD4", 3))
return EVP_md4();

View file

@ -1,42 +0,0 @@
From e039796a0fbefac03a3fd888aef7d192e7c1437e Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 1 Apr 2019 13:13:09 -0400
Subject: [PATCH] krb5-1.17 FIPS-aware SPAKE group negotiation
---
src/plugins/preauth/spake/groups.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/plugins/preauth/spake/groups.c b/src/plugins/preauth/spake/groups.c
index a195cc195..8a913cb5a 100644
--- a/src/plugins/preauth/spake/groups.c
+++ b/src/plugins/preauth/spake/groups.c
@@ -56,6 +56,8 @@
#include "trace.h"
#include "groups.h"
+#include <openssl/crypto.h>
+
#define DEFAULT_GROUPS_CLIENT "edwards25519"
#define DEFAULT_GROUPS_KDC ""
@@ -102,6 +104,9 @@ find_gdef(int32_t group)
{
size_t i;
+ if (group == builtin_edwards25519.reg->id && FIPS_mode())
+ return NULL;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (groupdefs[i]->reg->id == group)
return groupdefs[i];
@@ -116,6 +121,9 @@ find_gnum(const char *name)
{
size_t i;
+ if (strcasecmp(name, builtin_edwards25519.reg->name) == 0 && FIPS_mode())
+ return 0;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (strcasecmp(name, groupdefs[i]->reg->name) == 0)
return groupdefs[i]->reg->id;

View file

@ -1,40 +0,0 @@
From e307112cfcc52474d07eac890825303655ef8b6f Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 4 Jan 2019 17:00:15 -0500
Subject: [PATCH] krb5-1.17 Use openssl's PRNG in FIPS mode
---
src/lib/crypto/krb/prng.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index cb9ca9b98..f0e9984ca 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -26,6 +26,8 @@
#include "crypto_int.h"
+#include <openssl/rand.h>
+
krb5_error_code KRB5_CALLCONV
krb5_c_random_seed(krb5_context context, krb5_data *data)
{
@@ -99,9 +101,16 @@ krb5_boolean
k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
{
const char *device;
-#if defined(__linux__) && defined(SYS_getrandom)
int r;
+ /* A wild FIPS mode appeared! */
+ if (FIPS_mode()) {
+ /* The return codes on this API are not good */
+ r = RAND_bytes(buf, len);
+ return r == 1;
+ }
+
+#if defined(__linux__) && defined(SYS_getrandom)
while (len > 0) {
/*
* Pull from the /dev/urandom pool, but require it to have been seeded.

View file

@ -1,22 +0,0 @@
From 64c9cb22ec6d7ecdeafaf60bfc8d26780d2cb4ad Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:46:21 -0400
Subject: [PATCH] krb5-1.3.1-dns.patch
We want to be able to use --with-netlib and --enable-dns at the same time.
---
src/aclocal.m4 | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index a7afec09e..db18226ed 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -726,6 +726,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
LIBS="$LIBS $withval"
AC_MSG_RESULT("netlib will use \'$withval\'")
fi
+ KRB5_AC_ENABLE_DNS
],dnl
[AC_LIBRARY_NET]
)])dnl

View file

@ -1 +1 @@
d /var/run/krb5kdc 0755 root root
d /run/krb5kdc 0755 root root

18
krb5-tests Normal file
View file

@ -0,0 +1,18 @@
#!/bin/sh
set -e
export RPM_PACKAGE_NAME={{ name }}
export RPM_PACKAGE_VERSION={{ version }}
export RPM_PACKAGE_RELEASE={{ release }}
export RPM_ARCH={{ arch }}
export RPM_BUILD_NCPUS="$(getconf _NPROCESSORS_ONLN)"
testdir="$(mktemp -d)"
trap "rm -rf ${testdir}" EXIT
build_flags="$(eval "echo $(rpm --eval '%{_smp_mflags}')")"
mkdir "${testdir}/{{ name }}-tests"
cp -rp /usr/share/{{ name }}-tests/{{ arch }} "${testdir}/{{ name }}-tests/"
make -C "${testdir}/{{ name }}-tests/{{ arch }}/" $build_flags
keyctl session - make -C "${testdir}/{{ name }}-tests/{{ arch }}/" check

View file

@ -15,6 +15,8 @@ includedir /etc/krb5.conf.d/
rdns = false
pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
spake_preauth_groups = edwards25519
dns_canonicalize_hostname = fallback
qualify_shortname = ""
# default_realm = EXAMPLE.COM
[realms]

14
krb5.rpmlintrc Normal file
View file

@ -0,0 +1,14 @@
addFilter(r'spelling-error .* en_US (unencrypted)')
addFilter(r'hidden-file-or-dir /usr/share/man/man5/.k5identity.5.gz')
addFilter(r'non-standard-dir-in-var kerberos')
addFilter(r'explicit-lib-dependency libverto-module-base')
addFilter(r'shared-lib-calls-exit')
addFilter(r'dir-or-file-in-var-run /var/run/krb5kdc')
addFilter(r'devel-file-in-non-devel-package /usr/lib64/libkadm5(clnt|srv)_mit.so')
addFilter(r'non-readable /var/kerberos/krb5kdc')
addFilter(r'devel-file-in-non-devel-package /usr/lib64/libkdb_ldap.so')
addFilter(r'/usr/bin/ksu')
addFilter(r'no-documentation')
addFilter(r'invalid-directory-reference .*pkgconfig')
addFilter(r'incoherent-logrotate-file /etc/logrotate.d/k')
addFilter(r'library-not-linked-against-libc')

1851
krb5.spec

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,6 @@
monthly
rotate 12
postrotate
/bin/kill -HUP `cat /var/run/krb5kdc.pid 2>/dev/null` 2> /dev/null || true
systemctl reload krb5kdc.service || true
endscript
}

View file

@ -5,9 +5,9 @@ After=syslog.target network.target network-online.target
[Service]
Type=forking
PIDFile=/var/run/krb5kdc.pid
PIDFile=/run/krb5kdc.pid
EnvironmentFile=-/etc/sysconfig/krb5kdc
ExecStart=/usr/sbin/krb5kdc -P /var/run/krb5kdc.pid $KRB5KDC_ARGS
ExecStart=/usr/sbin/krb5kdc -P /run/krb5kdc.pid $KRB5KDC_ARGS
ExecReload=/bin/kill -HUP $MAINPID
[Install]

111
noport.c
View file

@ -1,111 +0,0 @@
#define _GNU_SOURCE
#include <sys/socket.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
static int
port_is_okay(unsigned short port)
{
char *p, *q;
long l;
p = getenv("NOPORT");
while ((p != NULL) && (*p != '\0')) {
l = strtol(p, &q, 10);
if ((q == NULL) || (q == p)) {
break;
}
if ((*q == '\0') || (*q == ',')) {
if (port == l) {
errno = ECONNREFUSED;
return -1;
}
}
p = q;
p += strspn(p, ",");
}
return 0;
}
int
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
unsigned short port;
static int (*next_connect)(int, const struct sockaddr *, socklen_t);
if (next_connect == NULL) {
next_connect = dlsym(RTLD_NEXT, "connect");
if (next_connect == NULL) {
errno = ENOSYS;
return -1;
}
}
if (getenv("NOPORT") == NULL) {
return next_connect(sockfd, addr, addrlen);
}
switch (addr->sa_family) {
case AF_INET:
port = ntohs(((struct sockaddr_in *)addr)->sin_port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
case AF_INET6:
port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
default:
break;
}
return next_connect(sockfd, addr, addrlen);
}
ssize_t
sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
unsigned short port;
static int (*next_sendto)(int, const void *, size_t, int,
const struct sockaddr *, socklen_t);
if (next_sendto == NULL) {
next_sendto = dlsym(RTLD_NEXT, "sendto");
if (next_sendto == NULL) {
errno = ENOSYS;
return -1;
}
}
if (getenv("NOPORT") == NULL) {
return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}
if (dest_addr != NULL) {
switch (dest_addr->sa_family) {
case AF_INET:
port = ((struct sockaddr_in *)dest_addr)->sin_port;
port = ntohs(port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
case AF_INET6:
port = ((struct sockaddr_in6 *)dest_addr)->sin6_port;
port = ntohs(port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
default:
break;
}
}
return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}

5
plans/tests.fmf Normal file
View file

@ -0,0 +1,5 @@
summary: Tests
discover:
how: fmf
execute:
how: tmt

17
rpminspect.yaml Normal file
View file

@ -0,0 +1,17 @@
---
inspections:
# https://bugzilla.redhat.com/show_bug.cgi?id=1956479
badfuncs: off
# Not a Java package
javabytecode: off
# I need to be able to *add* functions, and also we export internal
# functions that are not considered part of our ABI.
abidiff: off
# These just flag when things change "too much"
changedfiles: off
filesize: off
patches: off
upstream: off

View file

@ -1,3 +1,2 @@
SHA512 (krb5-1.17-pdfs.tar) = 89a5a709720ee9028e9bfbcbc808eec436c4b9c6e105888b37660e97cff48e190bc77affa9809353de9cf2f39e517e8a6ab22792263978b403a4a6317ac24a46
SHA512 (krb5-1.17.tar.gz) = 7462a578b936bd17f155a362dbb5d388e157a80a096549028be6c55400b11361c7f8a28e424fd5674801873651df4e694d536cae66728b7ae5e840e532358c52
SHA512 (krb5-1.17.tar.gz.asc) = 7ee81ccd05559ca1ff945619165297db251010db7c0205855f89ae66a73bc78e98f5e28ea154dcb752f5d4afb9349a293dcf8f64858d2129a869295fa8946e0f
SHA512 (krb5-1.21.3.tar.gz) = 87bc06607f4d95ff604169cea22180703a42d667af05f66f1569b8bd592670c42820b335e5c279e8b4f066d1e7da20f1948a1e4def7c5d295c170cbfc7f49c71
SHA512 (krb5-1.21.3.tar.gz.asc) = 8992a5f5247315b9846aa73be4ee1ea223c0231a52d5c6c28718b1f3e3b45d62e2dad4aa5543a83163d1369bb79886b6c1c22766f22d8aa2f6b2575c54d0075c

View file

@ -0,0 +1,2 @@
gef config gef.disable_color True
got-audit --all

12
tests/got-audit/kdc.conf Normal file
View file

@ -0,0 +1,12 @@
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
${krb5REALM1} = {
#master_key_type = aes256-cts
acl_file = /var/kerberos/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
}

29
tests/got-audit/krb5.conf Normal file
View file

@ -0,0 +1,29 @@
# To opt out of the system crypto-policies configuration of krb5, remove the
# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.
includedir /etc/krb5.conf.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = ${krb5REALM1}
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
default_ccache_name = KEYRING:persistent:%{uid}
[realms]
${krb5REALM1} = {
kdc = localhost.localdomain
admin_server = localhost.localdomain
}
[domain_realm]
${krb5HostName} = ${krb5REALM1}
[capaths]
${krb5REALM1} = .

12
tests/got-audit/main.fmf Normal file
View file

@ -0,0 +1,12 @@
summary: Audit the GOT for signs of tampering
description: |
Pointers in the server process GOT will be checked to ensure that
each function pointer's value is within a shared object file
that exports a symbol of that name, and that no shared object
files export conflicting symbols.
contact: Gordon Messmer <gordon.messmer@gmail.com>
require+:
- gdb-gef # needed to test got-audit
- krb5-server
test: ./runtest.sh
framework: beakerlib

121
tests/got-audit/runtest.sh Executable file
View file

@ -0,0 +1,121 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/openssh/Sanity/got-audit
# Description: Check pointers in the server process GOT for signs of tampering
# Author: Gordon Messmer <gordon.messmer@gmail.com>
#
# Include Beaker environment
. /usr/share/beakerlib/beakerlib.sh || exit 1
krb5REALM1='TEST1.REDHAT.COM'
krb5HostName=`hostname`
krb5DomainName=`hostname -d`
krb5User='alice'
krb5UserPass='alice'
krb5UserKrbPass='aaa'
krb5User2='bob'
krb5User3='carl'
krb5KDCPass='qwe'
krb5RootPass='rrr'
krb5conf="/etc/krb5.conf"
krb5confdir="/etc/krb5.conf.d"
krb5kdcconf="/var/kerberos/krb5kdc/kdc.conf"
krb5kadmacl="/var/kerberos/krb5kdc/kadm5.acl"
rlJournalStart
rlPhaseStartSetup
rlServiceStart sshd
rlRun "TestDir=\$(pwd)"
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
rlRun "pushd $TmpDir"
rlRun "auditfile=\$(mktemp --tmpdir=${TmpDir})"
rlPhaseEnd
rlPhaseStartSetup "KDC and kadmind setup"
# Stop and backup
rlRun "rlServiceStop kadmin krb5kdc"
rlRun "rm -f /var/kerberos/krb5kdc/principal* /var/kerberos/krb5kdc/.k5*"
rlFileBackup $krb5conf /var/kerberos/krb5kdc /etc/sysconfig/{kadmin,krb5kdc} /etc/hosts
rlFileBackup --clean /root/.k5login
[ -e /etc/krb5.keytab ] && rlFileBackup /etc/krb5.keytab
[ -e $krb5confdir ] && rlFileBackup $krb5confdir
# Basic setup of KDC and krb5.conf
rlRun "sed -i \"s/\[libdefaults\]/[libdefaults]\n default_realm = $krb5REALM1/\" $krb5conf"
rlRun "sed -i \"s/\[realms\]/[realms]\n $krb5REALM1 = {\n kdc = $krb5HostName\n admin_server = $krb5HostName\n }/\" $krb5conf"
if [ "$krb5DomainName" ]; then
rlRun "sed -i \"s/\[domain_realm\]/[domain_realm]\n .$krb5DomainName = $krb5REALM1\n $krb5DomainName = $krb5REALM1/\" $krb5conf"
else
rlRun "sed -i \"s/\[domain_realm\]/[domain_realm]\n $krb5HostName = $krb5REALM1/\" $krb5conf"
fi
rlRun "sed -i s/EXAMPLE.COM/$krb5REALM1/ $krb5kdcconf"
# Configure the kadmin ACL
rlRun "echo \"*/master@$krb5REALM1 *\" > $krb5kadmacl"
if rlIsFedora '>=31';then
rlLog "Modify supported_enctypes for Fedora >=31. Remove *DES ciphers."
rlRun "sed -i \"s/supported_enctypes.*/supported_enctypes = aes256-cts:normal aes128-cts:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal/\" /var/kerberos/krb5kdc/kdc.conf"
elif rlIsRHEL '8' && [ `rpm -q --qf '%{VERSION}' krb5-server | cut -d"." -f2` -lt 18 ];then
rlLog "Modify supported_enctypes for RHEL-8."
rlRun "sed -i \"s/supported_enctypes.*/supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal/\" /var/kerberos/krb5kdc/kdc.conf"
else
#RHEL-8 Bug 1802334 - [Rebase] krb5: rebase to 1.18:
#- Removal of *DES encryption types
#https://bugzilla.redhat.com/show_bug.cgi?id=1802334
rlLog "Modify supported_enctypes for RHEL-8 with krb-1.18. Remove *DES ciphers."
rlRun "sed -i \"s/supported_enctypes.*/supported_enctypes = aes256-cts:normal aes128-cts:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal/\" /var/kerberos/krb5kdc/kdc.conf"
fi
# Create the realm databases
rlRun "rngd -r /dev/urandom"
rlRun "kdb5_util create -s -r $krb5REALM1 -P $krb5KDCPass"
rlRun "rlServiceStart kadmin krb5kdc"
rlRun "kadmin.local -r $krb5REALM1 -q \"addprinc -pw $krb5RootPass root/master\""
rlRun "kadmin.local -r $krb5REALM1 -q \"addprinc -pw $krb5UserKrbPass $krb5User\""
rlRun "kadmin.local -r $krb5REALM1 -q \"addprinc -randkey host/$krb5HostName\""
rlRun "kadmin.local -r $krb5REALM1 -q \"ktadd host/$krb5HostName\""
# Create test system user
[ $krb5User != "root" ] && rlRun "useradd $krb5User"
rlRun "echo $krb5UserPass | passwd --stdin $krb5User"
rlPhaseEnd
rlPhaseStartTest "Run GEF got-audit"
rlRun "systemctl restart krb5kdc.service"
rlRun "systemctl restart kadmin.service"
rlRun "systemctl --no-pager status krb5kdc.service"
rlRun "systemctl --no-pager status kadmin.service"
rlRun "SERVICE_PID=\$( systemctl show --property=MainPID krb5kdc.service | cut -f2 -d= )"
rlRun "echo SERVICE_PID is '$SERVICE_PID'"
[ -n "$SERVICE_PID" ] || rlFail "No service pid was found"
rlRun "gdb-gef --pid '$SERVICE_PID' --command='$TestDir'/got-audit.gdb --batch > '$auditfile'"
# Basic test: ensure that at least one symbol is found in libc.so,
# to verify that the report looks plausible.
rlAssertGrep " : /.*/libc.so" "$auditfile"
# Ensure the got-audit did not report any errors
rlAssertNotGrep " :: ERROR" "$auditfile"
rlRun "cp '$auditfile' '$TMT_TEST_DATA'/krb5kdc-got-audit.txt"
rlRun "SERVICE_PID=\$( systemctl show --property=MainPID kadmin.service | cut -f2 -d= )"
rlRun "echo SERVICE_PID is '$SERVICE_PID'"
[ -n "$SERVICE_PID" ] || rlFail "No service pid was found"
rlRun "gdb-gef --pid '$SERVICE_PID' --command='$TestDir'/got-audit.gdb --batch > '$auditfile'"
# Basic test: ensure that at least one symbol is found in libc.so,
# to verify that the report looks plausible.
rlAssertGrep " : /.*/libc.so" "$auditfile"
# Ensure the got-audit did not report any errors
rlAssertNotGrep " :: ERROR" "$auditfile"
rlRun "cp '$auditfile' '$TMT_TEST_DATA'/kadmin-got-audit.txt"
rlPhaseEnd
rlPhaseStartCleanup
rlRun "rm -rf /var/kerberos/krb5kdc/* /var/kerberos/krb5kdc/.k5* /etc/krb5* /etc/sysconfig/{kadmin,krb5kdc}"
rlFileRestore
rlServiceRestore krb5kdc kadmin
[ $krb5User != "root" ] && rlRun "userdel -r -f $krb5User"
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View file

@ -55,6 +55,7 @@ $(METADATA): Makefile
@echo "TestTime: 20m" >> $(METADATA)
@echo "RunFor: krb5" >> $(METADATA)
@echo "Requires: expect krb5-server krb5-workstation openssh-clients openssh-server rng-tools" >> $(METADATA)
@echo "Requires: setools-console" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)

Some files were not shown because too many files have changed in this diff Show more