Add an internal variant of krb5_sendto_kdc() which records the
answering KDC in a list. Callers can check the list for replica KDC
use after the success or failure of the KDC exchange is determined,
avoiding DNS queries for the primary KDCs in many common cases and
using fewer DNS queries in other cases.
Perform the fallback in k5_get_init_creds() rather than
krb5_get_init_creds_password(). For now we must additionally perform
the fallback in krb5_get_init_creds_keytab() as it does not use
k5_get_init_creds().
Preserve the current signature of krb5_sendto_kdc() (it is used within
the tree outside of libkrb5, and might be used by other software
despite being non-public), but remove the behavior of setting
*use_primary.
Greg Hudson [Wed, 21 Jun 2023 14:57:39 +0000 (10:57 -0400)]
Ensure array count consistency in kadm5 RPC
In _xdr_kadm5_principal_ent_rec(), ensure that n_key_data matches the
key_data array count when decoding. Otherwise when the structure is
later freed, xdr_array() could iterate over the wrong number of
elements, either leaking some memory or freeing uninitialized
pointers. Reported by Robert Morris.
CVE-2023-36054:
An authenticated attacker can cause a kadmind process to crash by
freeing uninitialized pointers. Remote code execution is unlikely.
An attacker with control of a kadmin server can cause a kadmin client
to crash by freeing uninitialized pointers.
Greg Hudson [Tue, 30 May 2023 05:21:48 +0000 (01:21 -0400)]
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]
Gerald Combs [Sun, 14 May 2023 16:46:13 +0000 (09:46 -0700)]
Get arm64-windows builds working
Update various checks to include "ARM64" and "_M_ARM64".
Remove a /BASE flag which fixes an "ARM64 image cannot have base
address below 4GB" error and which arguably shouldn't be used in
modern times since it prevents using dynamic base addresses.
The Oracle database wire protocol contains a cipher reinitialization
operation using the ticket session key. Add a query operation
(similar to GSS_C_INQ_SSPI_SESSION_KEY) to retrieve the ticket session
key rather than the subkey.
The ubuntu-18.04 image no longer works on Github Actions. Run most
jobs on ubuntu-latest instead.
libresolv-wrapper does not work on ubuntu-22.04 at this time
(Launchpad bug #2015570), so don't install it for now. The URI
discovery tests will be skipped until this is rectified.
For the doc build, move doc-newest-sphix to ubuntu-latest; the Ubuntu
version doesn't matter much for this build as it downloads sphinx from
pypi.org. Move the doc-older-sphinx to ubuntu-22.04 (currently the
same as ubuntu-latest), skipping ubuntu-20.04 as its version of
doxygen (1.18.17) doesn't correctly the type declaration for
krb5_const_principal.
In __delpair(), the assignment to next_key is not used unless DEBUG is
defined, and the debugging assert can never fail--next_realkey() will
always return n + 1 as we just checked KEY_OFF(pagep, n + 1). Remove
the variable, the assert, and the otherwise unused next_realkey()
function. This change eliminates a warning issued by clang 14.
binutils 2.37 makes --with-symbol-versions the default for nm. In
export-check.pl, remove the default symbol versions in the nm output
if they are present.
Greg Hudson [Tue, 21 Mar 2023 04:51:17 +0000 (00:51 -0400)]
Add pac_privsvr_enctype string attribute
The KDC uses the first local TGT key for the privsvr and full PAC
checksums. If this key is of an aes-sha2 enctype in a cross-realm
TGT, a Microsoft KDC in the target realm may reject the ticket because
it has an unexpectedly large privsvr checksum buffer. This behavior
is unnecessarily picky as the target realm KDC cannot and does not
need to very the privsvr checksum, but [MS-PAC] 2.8.2 does limit the
checksum key to three specific enctypes.
As a workaround, add a string attribute which can force the privsvr
key to use a specified enctype using key derivation when issuing
tickets to that principal. This attribute can be set on cross-realm
TGT entries when the target realm uses Active Directory and the local
TGT uses an aes-sha2 primary key.
Greg Hudson [Wed, 15 Mar 2023 20:23:09 +0000 (16:23 -0400)]
Eliminate TWRITE macros in GSS library
Use dynamic k5buf structures to replace the two uses of the TWRITE_
macros, and replace the uses of TREAD_ macros with the equivalent
pointer assignments.
Greg Hudson [Mon, 13 Mar 2023 21:42:50 +0000 (17:42 -0400)]
Make k5buf more flexible for binary data
Remove the invariant that buf.data is always zero-terminated, to allow
marshalling of binary data into precisely allocated fixed regions.
Add k5_buf_cstring() to zero-terminate the buffer and retrieve the
data pointer. Adjust all callers that build C strings appropriately.
Add a k5_buf_add_byte() convenience wrapper alongside the integer
marshalling wrappers. Change k5_buf_init_fixed() to accept a void
pointer so it can more conveniently be used with uint8_t arrays.
Greg Hudson [Fri, 25 Nov 2022 15:11:29 +0000 (10:11 -0500)]
Modernize PAC code
Put the version and buffers directly in krb5_pac_data to avoid using a
variable-length array. Use k5input for krb5_pac_parse(). Adjust some
names and comments.
Greg Hudson [Fri, 24 Feb 2023 19:15:14 +0000 (14:15 -0500)]
Avoid using internal APIs in sim_client
In sim_client.c, remove the calls to krb5_gen_portaddr() and
krb5_gen_replay_name() as they don't do anything after commit dcb853ac32779b173f39e19c0f24b0087de85771. Remove them, and include
krb5.h plus appropriate system headers rather than k5-int.h.
Also use a subkey when negotiating the auth context. Kerberos
application protocols should generally use subkeys to prevent
cross-connection replay attacks.
Julien Rische [Tue, 21 Feb 2023 09:03:35 +0000 (10:03 +0100)]
Fix meridian type in getdate.y
Commit d3356bc42191c1896ab06835a2fb245e00471420 (ticket 8927)
incorrectly tagged tMERIDIAN as <Number>. So while the lexer assigns
meridian values to the Meridian union field, the parser erroneously
reads them from the Number field. On 64-bit IBM zSystems (s390x),
this can result in using the most recently read number as a meridian
value, leading to an abort in ToSeconds().
Greg Hudson [Wed, 8 Feb 2023 17:23:28 +0000 (12:23 -0500)]
Fix read overruns in SPNEGO parsing
Fix three read overruns discovered by the GitHub Security Lab team
(GHSL-2023-016, GHSL-2023-017, and GHSL-2023-018) using OSS-Fuzz.
In get_mech_set(), error out if gss_add_oid_set_member() fails rather
than continue the loop and increment i past the current bound of
returned_mechSet. In g_verify_neg_token_init(), check for zero-byte
sequences before reading tag bytes, and reduce cur_size by one to
account for the tag byte when calling gssint_get_der_length().
Greg Hudson [Sat, 28 Jan 2023 01:13:12 +0000 (20:13 -0500)]
Add margin to expired tickets in test suite
Very occasionally a test using expired tickets will fail because the
ticket isn't seen as expired. Obtain tickets with a longer expiration
margin to avoid these failures.
Greg Hudson [Thu, 22 Dec 2022 08:05:23 +0000 (03:05 -0500)]
Add PAC full checksums
A paper by Tom Tervoort noted that computing the PAC privsvr checksum
over only the server checksum is vulnerable to collision attacks
(CVE-2022-37967). In response, Microsoft has added a second KDC
checksum over the full contents of the PAC. Generate and verify full
KDC checksums in PACs for service tickets. Update the t_pac.c ticket
test case to use a ticket issued by a recent version of Active
Directory (provided by Stefan Metzmacher).
Greg Hudson [Fri, 16 Dec 2022 23:31:07 +0000 (18:31 -0500)]
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.
Greg Hudson [Wed, 14 Dec 2022 18:20:46 +0000 (13:20 -0500)]
In KDC, assume all services support aes256-sha1
To facilitate negotiating session keys with acceptable security,
assume that services support aes256-cts-hmac-sha1 unless a
session_enctypes string attribute says otherwise.
Greg Hudson [Tue, 13 Dec 2022 18:15:28 +0000 (13:15 -0500)]
Fix PKINIT CMS error checking for older OpenSSL
Commit 70f61d417261ca17efe3d60d180033bea2da60b0 updated the
CMS_verify() error code checks, using two error codes new to OpenSSL
3.0 (RSA_R_DIGEST_NOT_ALLOWED and CMS_R_UNKNOWN_DIGEST_ALGORITHM).
This change broke the build for OpenSSL 1.0 and 1.1.
Instead of looking for codes indicating an algorithm issue and
assuming that everything else is an invalid signature, check for the
code indicating an invalid signature and assume that everything else
is an algorithm issue.
Greg Hudson [Mon, 12 Dec 2022 19:36:47 +0000 (14:36 -0500)]
Fix policy DB fallback error handling
In osa_adb_open_and_lock(), if the btree dbopen() call returns EINVAL
or EFTYPE and the fallback hash dbopen() call also returns an error,
release the lock and return an error instead of returning success with
a null database.
ChenChen Zhou [Sun, 27 Nov 2022 14:57:14 +0000 (22:57 +0800)]
Fix gic_keytab crash on memory exhaustion
get_as_key_keytab() does not check the result of krb5_copy_keyblock(),
and dereferences a null pointer if it fails. Remove the call and
steal the memory from kt_ent instead.
ChenChen Zhou [Thu, 24 Nov 2022 13:59:21 +0000 (21:59 +0800)]
Fix profile crash on memory exhaustion
In profile_get_values(), if init_list() fails to allocate values.list,
end_list() will dereference a null pointer. Fix end_list() to handle
list->list being null.
Julien Rische [Thu, 17 Nov 2022 14:01:24 +0000 (15:01 +0100)]
Fix aclocal.m4 syntax error for autoconf 2.72
An incorrect closure inside KRB5_AC_INET6 is innocuous with autoconf
versions up to 2.71, but will cause an error at configure time with
the forthcoming autoconf 2.72.
[ghudson@mit.edu: added more context to commit message]
Greg Hudson [Tue, 18 Oct 2022 20:17:55 +0000 (16:17 -0400)]
Use memmove() in Unicode functions
Where the upstream OpenLDAP code uses AC_MEMCPY(), use memmove()
instead of memcpy() as the copies frequently involve overlapping
memory regions. Credit to OSS-Fuzz for discovering one instance of
the issue.
Greg Hudson [Tue, 18 Oct 2022 00:25:11 +0000 (20:25 -0400)]
Fix integer overflows in PAC parsing
In krb5_parse_pac(), check for buffer counts large enough to threaten
integer overflow in the header length and memory length calculations.
Avoid potential integer overflows when checking the length of each
buffer. Credit to OSS-Fuzz for discovering one of the issues.
CVE-2022-42898:
In MIT krb5 releases 1.8 and later, an authenticated attacker may be
able to cause a KDC or kadmind process to crash by reading beyond the
bounds of allocated memory, creating a denial of service. A
privileged attacker may similarly be able to cause a Kerberos or GSS
application service to crash. On 32-bit platforms, an attacker can
also cause insufficient memory to be allocated for the result,
potentially leading to remote code execution in a KDC, kadmind, or GSS
or Kerberos application server process. An attacker with the
privileges of a cross-realm KDC may be able to extract secrets from a
KDC process's memory by having them copied into the PAC of a new
ticket.
Greg Hudson [Wed, 12 Oct 2022 04:46:52 +0000 (00:46 -0400)]
Fix null deref in KDC when decoding invalid NDR
In ndr_dec_delegation_info(), keep di->transited_services_length valid
by incrementing it as we add entries. Otherwise
ndr_free_delegation_info() could dereference a null
di->transited_services field. Also bound nservices using data->length
to prevent inordinately large memory allocations. Credit to OSS-Fuzz
for discovering the issues.
Greg Hudson [Wed, 12 Oct 2022 04:27:17 +0000 (00:27 -0400)]
Avoid small read overrun in UTF8 normalization
In krb5int_utf8_normalize(), check the length of the current character
against the buffer length before reading more than one byte. Credit
to OSS-Fuzz for discovering the overrun.
Greg Hudson [Tue, 9 Aug 2022 16:22:43 +0000 (12:22 -0400)]
Refactor KDC TGS processing code
Split the TGS processing code into information gathering, constraint
and policy checking, and ticket-issuing steps, using a structure to
hold the gathered information. Split validate_tgs_request() into
validate_tgs_constraints() and check_tgs_policy() for better auditing.
Fold kdc_process_s4u2proxy_req() into check_tgs_policy(), except for
the get_pac_princ_with_realm() step which is now performed in
gather_tgs_req_info(). Modify some other utility functions to fit the
new design.
ts_delta() returns a signed result, which cannot hold an interval
larger than 2^31-1 seconds. Intervals like this have been seen when
admins set password expiration dates more than 68 years in the future.
Add a second helper ts_interval() which returns an unsigned result,
and has the arguments reversed so that the start time is first. Use
it in warn_pw_expiry() to handle the password expiration case, in the
GSS krb5 mech where we return an unsigned context or credential
lifetime to the caller, and in the KEYRING ccache type where we
compute an unsigned keyring timeout.
The code for CMS data verification was initially written for OpenSSL's
PKCS7_verify() function. It now uses CMS_verify(), but error handling
is still done using PKCS7_verify() error identifiers. Update the
recognized error codes so that the KDC generates
KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED errors when appropriate.
Use ERR_peek_last_error() to observe the error generated closest to
the API surface.
Commit 0b4580b09afe9791d81961c41f61e4f06edad58f mistakenly calls the
nonexistent _stop_daemon() in the onexit handler. Replace the call
with code to terminate the daemon and check its exit status.
Eliminate the last two kdc_active_realm macros from realm_data.h (left
behind after commits 0a2f14f752c32a24200363cc6b6ae64a92f81379 and e987546b4ff1689bb711cc46118ad9fc0a5613f6). Where code is affected,
use the names "context" and "realm". Pass contexts instead of realm
data structures to several functions which only need a context.
Every caller of cms_signeddata_create() and cms_envelopeddata_create()
passes 1 for include_certchain. Remove the parameter and
unconditionally add the certificate chain.
Julien Rische [Wed, 1 Jun 2022 16:02:04 +0000 (18:02 +0200)]
Set reasonable supportedCMSTypes in PKINIT
The PKINIT client uses AuthPack.supportedCMSTypes to let the KDC know
the algorithms it supports for verification of the CMS data signature.
(The MIT krb5 KDC currently ignores this list, but other
implementations use it.)
Replace 3DES with sha512WithRSAEncryption and sha256WithRSAEncryption.
[ghudson@mit.edu: simplified code and used appropriate helpers; edited
commit message]
Greg Hudson [Thu, 23 Jun 2022 20:41:40 +0000 (16:41 -0400)]
Simplify plugin loading code
Remove the USE_CFBUNDLE code, which was only used by KfM. Handle
platform conditionals according to current practice. Use
k5_dir_filenames() instead of opendir() and remove the Windows
implementation of opendir().
sashan [Fri, 17 Jun 2022 22:05:32 +0000 (00:05 +0200)]
Fix PKCS11 module path search
Commit c5c11839e02c7993eb78f2c94c75c10cf93f2195 switched the loading
of the PKCS#11 module from dlopen() to krb5int_open_plugin(). Because
krb5int_open_plugin() includes a stat() test, this change has the
unintended consequence of requiring the module name to be an absolute
or relative path to the library, not a filename within the dynamic
linker search path.
Within krb5int_open_plugin(), only stat() the filename on the
platforms which will use the file type.
[ghudson@mit.edu: adjusted conditionals to call stat() on Windows;
rewrote commit message]
Greg Hudson [Fri, 3 Jun 2022 18:28:26 +0000 (14:28 -0400)]
Improve k5test daemon checking
Instead of checking daemon exit statuses prior to termination, check
them after we send SIGTERM. This way we will notice when asan causes
an unsuccessful exit due to memory leaks, or when a daemon crashes in
its exit handling.
Greg Hudson [Fri, 3 Jun 2022 18:38:45 +0000 (14:38 -0400)]
Free verto context later in KDC cleanup
The KDC supplies the verto context to kdcpreauth modules via the loop
method (added in commit 83b4ecd20e50ad330cd761977d5dadefe30a785b).
This context should remain valid until kdcpreauth modules are
unloaded, as modules might refer to it during cleanup. In particular,
the OTP module references the verto context when freeing the RADIUS
client object (commit e89abc2d4ea1fea1ec28d470f297514b828e4842), which
can cause a memory error during KDC shutdown without this change.
sashan [Sun, 29 May 2022 08:32:57 +0000 (10:32 +0200)]
Fix uncommon PKINIT memory leak
PKINIT per-request module data objects are normally created by
pkinit_server_verify_padata() and freed by
pkinit_server_return_padata(). In some unusual circumstances, the KDC
may not call the return_padata method after verification succeeds.
Add a free_modreq method and free the object there instead.
sashan [Thu, 26 May 2022 06:51:10 +0000 (08:51 +0200)]
Fix memory leak in SPAKE kdcpreauth module
Commit ff57dc682a27bd205d715f3c0bed84890f2453c4 introduced a memory
leak into verify_response(). reply_key is no longer passed to the
callback and therefore needs to be freed by this function.
Simo Sorce [Thu, 19 May 2022 16:27:40 +0000 (12:27 -0400)]
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.
Ken Hornstein [Wed, 4 Aug 2021 03:18:27 +0000 (23:18 -0400)]
Support macOS 11 native credential cache
Add an API credential cache implementation using the CCAPI stubs in
the macOS Kerberos framework, tailored to access the native
collections used by macOS 10.6 and later (KCM before macOS 11, XCACHE
afterwards). Make API: the default ccache name for macOS 10.6 and
later.
[ghudson@mit.edu: used shared CCAPI credential conversion functions;
changed ptcursor behavior to match current Unix collection semantics;
adjusted naming and code style]
Greg Hudson [Mon, 9 May 2022 14:55:41 +0000 (10:55 -0400)]
Remove krb5_aprof_init() and krb5_aprof_finish()
These functions are not part of the API, as they are prototyped in the
internal header adm_proto.h. Stop using them in kdc/main.c (instead
using the context profile) and stop defining them.
Greg Hudson [Tue, 3 May 2022 05:56:05 +0000 (01:56 -0400)]
Omit LDFLAGS from krb5-config --libs output
Linker options supplied at configure time (such as -Wl,--as-needed)
can be harmful when applied to downstream users of the libraries, and
in most cases should not be necessary.
Greg Hudson [Mon, 28 Mar 2022 23:06:29 +0000 (19:06 -0400)]
Fix iprop with fallback
kpropd produces a client principal name with
krb5_sname_to_principal(), then converts it to a string to pass as the
client principal to kadm5_init_with_skey(). This conversion loses the
name type, so no canonicalization is performed by libkadm5.
Commit dcb79089276624d7ddf44e08d35bd6d7d7e557d2 addresses this problem
for kadmin -k by looking for the referral realm, but kpropd sets the
realm in the krb5_sname_to_principal() result. Add an additional
check for a two-component principal with kiprop as the first
component.
Greg Hudson [Fri, 4 Mar 2022 05:45:00 +0000 (00:45 -0500)]
Try harder to avoid password change replay errors
Commit d7b3018d338fc9c989c3fa17505870f23c3759a8 (ticket 7905) changed
change_set_password() 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.
Julien Rische [Wed, 19 Jan 2022 18:46:08 +0000 (19:46 +0100)]
Make kprop work for dump files larger than 4GB
If the dump file size does not fit in 32 bits, encode four zero bytes
(forcing an error for unmodified kpropd) followed by the size in the
next 64 bits.
Add a functional test case, but only run it when an environment
variable is set, as processing a 4GB dump file is too
resource-intensive for make check.
[ghudson@mit.edu: edited comments and commit message; eliminated use
of defined constant in some cases; added test case]
Tianjiao Yin [Mon, 7 Feb 2022 08:48:05 +0000 (00:48 -0800)]
Replace macros with typedefs in gssrpc types.h
Defining bool_t and enum_t with the preprocessor conflicts with
namespaced declarations in fbthrift's headers. Use typedefs to avoid
this conflict and for consistency with other Sun RPC implementations.
Greg Hudson [Tue, 25 Jan 2022 23:09:21 +0000 (18:09 -0500)]
Clarify certauth interface documentation
Try to make it clearer that princ is the requested client principal,
not a principal extracted from the certificate, and that the module
must decode the certificate and inspect its attributes. Document
KRB5_CERTAUTH_HWAUTH_PASS in certauth_plugin.h.
Greg Hudson [Wed, 23 Feb 2022 05:31:13 +0000 (00:31 -0500)]
Run Windows CI on windows-2019 image for now
The Github Actions windows-latest runner label now uses Windows Server
2022, which requires different setup steps for the Visual Studio
environment and does not contain CRT merge modules for VS 2022 (though
it does for VS 2017). For now, run the Windows build on windows-2019.
Greg Hudson [Fri, 28 Jan 2022 15:44:21 +0000 (10:44 -0500)]
Remove unneeded SPAKE free_modreq method
Commit ff57dc682a27bd205d715f3c0bed84890f2453c4 removed the use of
per-request module data in SPAKE, but neglected to remove the
corresponding free_modreq method.
Greg Hudson [Fri, 21 Jan 2022 15:58:46 +0000 (10:58 -0500)]
Avoid passing null for asprintf strings
It is undefined behavior to pass null to a printf function for a %.*s
substitution, even if the accompanying length is zero. OpenBSD
generates syslog warnings from libc when it sees a null pointer in a
string substitution (reported by Nathanael Rensen).
krb5_sname_to_principal() passes a null pointer in the usual case
where there is no port trailer. Address this case and others where we
use asprintf() with %.*s substitutions and might pass null, either by
avoiding the use of asprintf() or by ensuring that the pointer isn't
null.
Greg Hudson [Tue, 18 Jan 2022 22:06:46 +0000 (17:06 -0500)]
Pass client flag to KDB for client preauth match
In the kdcpreauth match_client() callback, if it is necessary to look
up the given principal in the KDB, pass KRB5_KDB_FLAG_CLIENT to
krb5_db_get_principal(). Samba requires this flag to properly handle
enterprise client principals.