Greg Hudson [Sat, 11 Nov 2017 18:42:28 +0000 (13:42 -0500)]
Length check when parsing GSS token encapsulation
gssint_get_mech_type_oid() is used by gss_accept_sec_context() to
determine the mechanism of the token. Without length checking, it
might read a few bytes past the end of the input token buffer. Add
length checking as well as test cases for truncated encapsulations.
Reported by Bar Katz.
If krb5_db_fetch_mkey() prompts for a master key and needs to
determine the kvno, check that the master entry contains any key data
before dereferencing the first element. Reported by Joshua Schaeffer.
Assign status values if S4U2Self padata fails to decode, if an
S4U2Proxy request uses invalid KDC options, or if an S4U2Proxy request
uses an evidence ticket which does not match the canonicalized request
server principal name. Reported by Samuel Cabrero.
If a status value is not assigned during KDC processing, default to
"UNKNOWN_REASON" rather than failing an assertion. This change will
prevent future denial of service bugs due to similar mistakes, and
will allow us to omit assigning status values for unlikely errors such
as small memory allocation failures.
CVE-2017-11368:
In MIT krb5 1.7 and later, an authenticated attacker can cause an
assertion failure in krb5kdc by sending an invalid S4U2Self or
S4U2Proxy request.
After gss_init_sec_context() or gss_accept_sec_context() has created a
context, don't delete the mechglue context on failures from subsequent
calls, even if the mechanism deletes the mech-specific context (which
is allowed by RFC 2744 but not preferred). Check for union contexts
with no mechanism context in each GSS function which accepts a
gss_ctx_id_t.
CVE-2017-11462:
RFC 2744 permits a GSS-API implementation to delete an existing
security context on a second or subsequent call to
gss_init_sec_context() or gss_accept_sec_context() if the call results
in an error. This API behavior has been found to be dangerous,
leading to the possibility of memory errors in some callers. For
safety, GSS-API implementations should instead preserve existing
security contexts on error until the caller deletes them.
All versions of MIT krb5 prior to this change may delete acceptor
contexts on error. Versions 1.13.4 through 1.13.7, 1.14.1 through
1.14.5, and 1.15 through 1.15.1 may also delete initiator contexts on
error.
Greg Hudson [Mon, 26 Jun 2017 21:31:37 +0000 (17:31 -0400)]
Fix kadm5 setkey operation with LDAP KDB
Add mask assignments to kadm5_setv4key_principal() and
kadm5_setkey_principal_4() so that their changes to the principal are
properly written to KDB modules which use the mask flag, such as the
LDAP KDB module. Reported by Frank Lonigro.
Greg Hudson [Mon, 19 Jun 2017 15:30:38 +0000 (11:30 -0400)]
Fix kadm5.acl error reporting
In kadm5int_acl_get_line(), increment *lnp after skipping a blank or
comment line, so that kadm5int_acl_load_acl_file() correctly reports
the line number if it fails to parse a line.
In acl_syn_err_msg, use %.10s to limit the amount of the line included
in the error message, not %10s to left-pad it with spaces if it is
shorter than ten characters.
Tomas Kuthan [Tue, 16 May 2017 09:24:40 +0000 (11:24 +0200)]
Free GSS checksum data deterministically
In the normal course of execution, md5.contents allocated by
kg_checksum_channel_bindings() in make_ap_req_v1() is freed in
make_gss_checksum(). But when there is a failure in
krb5_mk_req_extended() or in make_gss_checksum() before free is
called, the memory leaks.
This patch frees the memory unconditionally in make_ap_req_v1().
Commit b496ce4095133536e0ace36b74130e4b9ecb5e11 (ticket #8268) adds
the clock skew to krb5 acceptor context lifetimes for
gss_accept_sec_context() and gss_inquire_context(), but not for
gss_context_time(). Add the clock skew in gss_context_time() as well.
We apply (as of ticket #7604) a ten-second minimum delay after a TCP
connection is accepted before creating new connections or sending UDP
packets. Apply this timeout to HTTPS connections as well, by removing
the transport check in get_endtime(). As the endtime field is only
set by service_tcp_connect(), it will always have the value 0 for UDP
connection state objects, so there is no need to check the transport
type.
krb5int_utf8cs_to_ucs2les() can read slightly beyond the end of the
input buffer if the buffer ends with an invalid UTF-8 sequence. When
computing the RC4 string-to-key result, make a zero-terminated copy of
the input string and use krb5int_utf8s_to_ucs2les() instead.
If we reach the encrypted challenge clpreauth process method without
an armor key, error out instead of crashing. This can happen if (a)
the KDC offers encrypted challenge even though the request doesn't use
FAST (the Heimdal KDC apparently does this), and (b) we fall back to
that preauth method before generating a preauthenticated request,
typically because of a prompter failure in encrypted timestamp.
Reported by Nico Williams.
The flags field in krb5_lcc_data is not initialized in
krb5_lcc_resolve(), so krb5_lcc_next_cred() can sometimes fail to
include a ticket when retrieving a ccache entry. This results in a
"Request did not supply a ticket" error from k5_make_tgs_req() when
trying to use the credential.
Martin Kittel [Wed, 15 Mar 2017 16:21:28 +0000 (17:21 +0100)]
Fix krb5int_open_plugin_dirs() error handling
In krb5int_open_plugin_dirs(), if constructing filepath fails,
filepath is set to null but accessed a few lines later. Add an error
check before calling krb5int_open_plugin().
Greg Hudson [Tue, 14 Mar 2017 23:39:38 +0000 (19:39 -0400)]
Force autoconf rebuild in maintainer rules
autoconf normally avoids recreating files that it does not consider
obsolete. Since it knows nothing about patchlevel.h (which we read at
autoconf time using m4's esyscmd()), changes to patchlevel.h won't be
reflected in configure unless another input to configure has changed,
and the maintainer rule will re-run autoconf over and over again. Fix
this issue by passing the force flag to autoconf when we invoke it
from the maintainer rule.
Isaac Boukris [Sat, 4 Mar 2017 19:23:32 +0000 (21:23 +0200)]
Allow null outputs to gss_get_name_attribute()
In krb5_gss_get_name_attribute(), always ask for kvalue and
kdisplay_value when calling krb5_authdata_get_attribute(), as it
currently expect non-null arguments. This change allows applications
to pass GSS_C_NO_BUFFER for the value and display_value output
parameters. (Passing NULL for the authenticated and complete output
parameters already works.)
[ghudson@mit.edu: initialized kvalue and kdisplay_value for safety]
Greg Hudson [Tue, 28 Feb 2017 03:35:07 +0000 (22:35 -0500)]
Fix udp_preference_limit with SRV records
In sendto_kdc:resolve_server() when resolving a server entry with a
specified transport, defer the resulting addresses if the strategy
dictates that the specified transport is not preferred. Reported by
Jochen Hein.
Greg Hudson [Fri, 24 Feb 2017 18:41:53 +0000 (13:41 -0500)]
Fix PKINIT two-component matching rule parsing
In pkinit_matching.c:parse_rule_set(), apply the default relation when
parsing the second component of a rule, not the third. Otherwise we
apply no default relation to two-component matching rules, effectively
reducing such rules to their second components. Reported by Sumit
Bose.
Tomas Kuthan [Fri, 2 Dec 2016 14:22:54 +0000 (15:22 +0100)]
Add krbPwdPolicy attributes to kerberos.ldif
When LDAP backend support for policy extensions was added by 5edafa0532 (ticket 7223), the kerberos.ldif change neglected to add
the new attributes to krbPwdPolicy.
Greg Hudson [Sun, 27 Nov 2016 23:37:12 +0000 (18:37 -0500)]
Allow slapd path configuration in t_kdb.py
The upstream OpenLDAP installs slapd in libexec, which is not
typically in the path. Also, copying the binary can sometimes cause
it to fail; for instance, in the OpenCSW package,
/opt/csw/libexec/slapd is a script which chooses a binary based on the
system architecture and the path to the script. Allow the test runner
to set the SLAPD environment variable to specify the slapd location
and avoid the copy.
Greg Hudson [Mon, 31 Oct 2016 15:48:54 +0000 (11:48 -0400)]
Make zap() more reliable
The gcc assembly version of zap() could still be optimized out under
gcc 5.1 or later, and the krb5int_zap() function could be optimized
out with link-time optimization. Based on work by Zhaomo Yang and
Brian Johannesmeyer, use the C11 memset_s() when available, then fall
back to a memory barrier with gcc or clang, and finally fall back to
using krb5int_zap(). Modify krb5int_zap() to use a volatile pointer
in case link-time optimization is used.
Tom Yu [Tue, 4 Oct 2016 22:14:51 +0000 (18:14 -0400)]
Set alg param correctly for PKCS1
When using a smart card and constructing a DigestInfo to pass to the
CKM_RSA_PKCS mechanism, make sure to set the AlgorithmIdentifier
parameters correctly. This is typically an ASN.1 NULL value.
In the previous code, when the remote peer performed an orderly shutdown
on the socket, libkrad would enter a state in which all future requests
timed out. Instead, if the peer shuts down its socket, we need to
attempt to reopen it.
Ben Kaduk [Mon, 26 Jan 2015 16:15:42 +0000 (11:15 -0500)]
Improve keytab documentation
In the k5srvutil man page, do not give the impression that arbitrary
new keys can be added to the keytab (requested by Dan Gillmor), since
only the new keys randomly generated by the KDC via 'k5srvutil change'
can be added to the keytab. Reiterate the importance of running
k5srvutil delold after running k5srvutil change in the description of
k5srvutil change, as well as in the description of k5srvutil delold
itself.
In install_kdc.rst, mention using a separate keytab file when
generating a keytab on a KDC for use on another host.
[ghudson@mit.edu: squashed two commits, condensed commit message]
Ben Kaduk [Wed, 11 Jun 2014 20:38:57 +0000 (16:38 -0400)]
Document krb5_kt_next_entry() requirement
Successful calls to krb5_kt_next_entry() return a krb5_keytab_entry
that the caller is responsible for freeing. Note this, and the
proper function to do so, in the doxygen comments.
In prepare_error_as(), if krb5_us_timeofday() fails and error pa-data
was supplied, the FAST cookie and a shallow copy of the error padata
can be leaked. Reported by Will Fiveash.
Tom Yu [Wed, 7 Sep 2016 21:28:34 +0000 (17:28 -0400)]
Fix unaligned accesses in bt_split.c
In the libdb2 btree back end, splitting a page at an overflow key
could result in an unaligned access, causing a crash (and data
corruption) on platforms with strict alignment. This probably occurs
only rarely in practice.
Ben Kaduk [Thu, 11 Aug 2016 04:25:47 +0000 (23:25 -0500)]
Fix build with -O3 on ppc64el
Ubuntu runs ppc64el builds with -O3, which elicited a few warnings
from gcc that were not generated elsewhere, as documented at
https://bugs.launchpad.net/ubuntu/+source/krb5/+bug/1592841 .
Initialize the output variable at the top of a couple of helper functions
to silence the uninitialized-variable warnings.
Commit e3d9f03a658e247dbb43cb345aa93a28782fd995 (ticket 8481) added
several checks for negative length values when decoding DB2 principal
entries, including two unnecessary checks on unsigned values. Remove
those checks as they can generate warnings.
We depend on the behavior of having a separate subshell for each line in
our Makefiles, so force it where make (observed FreeBSD 10.3) does not
create one.
[ghudson@mit.edu: also changed rules in config/post.in]
Tom Yu [Thu, 25 Aug 2016 22:02:56 +0000 (18:02 -0400)]
Avoid byte-swap cache corruption in libdb2
Apply a patch from NetBSD to restore the cached copy of a page to the
machine byte order after a write operation swapped it to the file byte
order. As a regression test, modify test13 to sync the database file
after each put to exercise this bug.
Tom Yu [Fri, 26 Aug 2016 22:40:49 +0000 (18:40 -0400)]
Add known file test case for btree byte swap
Add a regression test for the preceding bugfix. This test uses btree
database files with known contents and byte orders with short keys and
overflow data items.
Tom Yu [Fri, 26 Aug 2016 19:24:52 +0000 (15:24 -0400)]
Fix btree byte swapping for overflow data
When operating on a btree database file of the opposite endianness,
libdb2 was swapping the wrong bytes if a record had a short key but
overflow data. Fix this bug by not incrementing p when swapping a
P_BIGKEY overflow pointer, and by always skipping the full key size
before swapping a P_BIGDATA overflow pointer (instead of assuming that
a P_BIGKEY pointer always precedes a P_BIGDATA pointer).
Greg Hudson [Tue, 23 Aug 2016 17:41:00 +0000 (13:41 -0400)]
Improve checking of decoded DB2 principal values
In krb5_decode_princ_entry(), verify the length of the principal name
before calling krb5_parse_name() or strlen(), to avoid a possible
buffer read overrun. Check all length fields for negative values.
Avoid performing arithmetic as part of bounds checks. If the value of
key_data_ver is unexpected, return KRB5_KDB_BAD_VERSION instead of
aborting.
To work correctly with older Samba clients, we should guess the mutual
flag based on the ap_options from the AP-REQ and not set it
unconditionally. Found by the Samba torture testsuite.
[ghudson@mit.edu: edited comments and commit message]
Greg Hudson [Tue, 23 Aug 2016 16:35:50 +0000 (12:35 -0400)]
Fix GSSRPC server credential memory leak
In svc_auth_gss.c, stop using the global svcauth_gss_creds, and
instead keep a credential in struct svc_rpc_gss_data. This change
ensures that the same credential is used for each accept_sec_context
call for a particular context, and ensures that the credential is
freed when the authentication data is destroyed. Also, do not acquire
a credential when the default name is used (as it is in kadmind) as it
is not needed.
Leave the svcauth_gss_creds around for the backportable fix as it is
in the library export list. It will be removed in a subsequent
commit.
In spnego_gss_import_cred(), use create_spnego_cred() to create the
SPNEGO credential structure. Prior to this change, an imported SPNEGO
cred did not initialize the no_ask_integ field (added by commit cf39ed349976908626cad3e05e17788f8334bce9, ticket #6938).
Greg Hudson [Fri, 5 Aug 2016 16:28:03 +0000 (12:28 -0400)]
Use responder for non-preauth AS requests
If no AS reply key is computed during pre-authentication (typically
because no pre-authentication was required by the KDC), ask for the
password using the responder before calling gak_fct for the key, and
supply any resulting responder items to gak_fct.
Sarah Day [Mon, 15 Aug 2016 20:11:31 +0000 (16:11 -0400)]
Fix KDC to drop repeated in-progress requests
When a KDC receives a repeated request while the original request is
still in progress, it is supposed to be to drop the request. Commit f07760088b72a11c54dd72efbc5739f231a4d4b0 introduced a bug in this
logic, causing the KDC to instead send an empty reply. In
kdc_check_lookaside(), return a NULL reply_packet for empty entries,
restoring the expected behavior.
[ghudson@mit.edu: edited commit message, added a comment]
Greg Hudson [Sun, 14 Aug 2016 16:08:16 +0000 (12:08 -0400)]
Work around glibc OFD lock bug on 32-bit Linux
A bug in Gnu libc causes OFD locking to fail unpredictably on 32-bit
Linux, typically leading to deadlocks. Work around this bug by using
the fcntl64 system call and struct flock64.
See also: https://sourceware.org/bugzilla/show_bug.cgi?id=20251
Ben Kaduk [Wed, 3 Aug 2016 15:23:56 +0000 (10:23 -0500)]
Properly escape quotes for otp set_string example
The libss parser will consume paired double quotes, but within
a double-quoted region, repeated double quotes will be treated
as an escape and passed through as a single double quote.
(The new kadmin(1) parser in 1.14 that lets commands be specified
on the command line without -q does not go through the libss parser,
so standard shell methods for escaping quotes function as usual.)
Greg Hudson [Tue, 28 Jun 2016 16:28:11 +0000 (12:28 -0400)]
Fix leak in gss_display_name() for non-MN names
RFC 2744 states that the gss_display_name() output_name_type result is
"a pointer into static storage, and should be treated as read-only by
the caller (in particular, the application should not attempt to free
it)". For non-mechanism names, we were making a copy of the name type
from the union name structure, causing a memory leak; stop doing that.
Greg Hudson [Mon, 27 Jun 2016 23:38:36 +0000 (19:38 -0400)]
Fix leak in k5_free_cammac()
free_vmac(), a helper function used by k5_free_cammac(), must free its
val pointer as well as the contents; otherwise the krb5_verifier_mac
container is leaked.
Greg Hudson [Mon, 27 Jun 2016 21:49:57 +0000 (17:49 -0400)]
Fix leaks on error in krb5 gss_acquire_cred()
In acquire_cred_context(), when releasing the partially constructed
cred on error, make sure to free the password and impersonator fields,
and to destroy the ccache if we created it.
Greg Hudson [Fri, 24 Jun 2016 16:33:05 +0000 (12:33 -0400)]
Fix memory leak in db2 policy DB initialization
osa_adb_init_db() maintains a static linked list mapping filenames to
lock structures. Entries are never removed from the list; when their
reference counts hit 0, the lockfile is closed but the filename
remains allocated. However, the filename is allocated each time the
lockfile is re-opened, leaking the old value. Fix this leak by moving
filename initialization to entry creation.
Tom Yu [Wed, 3 Aug 2016 21:00:05 +0000 (17:00 -0400)]
Warn about dump -recurse nonfunctionality
kdb5_util dump -recurse hasn't behaved as documented since krb5-1.5,
when the DAL was integrated. Restoring it is a nontrivial amount of
work, so just document it for now.
In validate_as_request(), when enforcing restrict_anonymous_to_tgt,
use client.princ instead of request->client; the latter is NULL when
validating S4U2Self requests.
CVE-2016-3120:
In MIT krb5 1.9 and later, an authenticated attacker can cause krb5kdc
to dereference a null pointer if the restrict_anonymous_to_tgt option
is set to true, by making an S4U2Self request.
Commit 632260bd1fccfb420f0827b59c85c329203eafc9 (ticket #7517) allows
better error reporting for some client pre-authentication failures.
However, it breaks an assumption in the S4U2Self code that such errors
can be recognized by the KRB5_PREAUTH_FAILED error code. Instead of
passing through the error code reported by the first real preauth
module, wrap that error and return KRB5_PREAUTH_FAILED.
The KDC now needs write access to the LDAP KDB, unless password
lockout and tracking of the last successful authentication time are
disabled. Update the example LDAP access control configuration in
conf_ldap.rst to reflect this, add a note that only read access is
required if lockout is disabled, and add a section to lockout.rst
calling out the need for write access. Reported by Will Fiveash.
Greg Hudson [Thu, 23 Jun 2016 16:01:56 +0000 (12:01 -0400)]
Fix profile_flush_to_file() state corruption
In write_data_to_file(), do not clear the profile data object's flags.
If the call to this function resulted from profile_flush_to_file(), we
do not want to clear the DIRTY flag, and we especially do not want to
clear the SHARED flag for a data object which is part of
g_shared_trees. Instead, clear the DIRTY flag in
profile_flush_file_data().
Add a test case to prof_test1 to exercise the bug in unfixed code.
Also modify test1 to abandon the altered profile after flushing it to
a file, to preserve the external behavior of the script before this
fix.
When the default realm name is unspecified, and none was set in the
krb5_context object, return KRB5_CONFIG_NODEFREALM from libkdb5
instead of the confusing KRB5_KDB_DBTYPE_NOTFOUND. To accomplish
this, make kdb_get_library_name() return a krb5_error_code.
Before this patch libkrad would always subtract the existing buffer
length from pktlen before passing it to recv(). In the case of stream
sockets, this is incorrect since krad_packet_bytes_needed() already
performs this calculation. Subtracting the buffer length twice could
cause integer underflow on the len parameter to recv().
Greg Hudson [Wed, 8 Jun 2016 04:00:55 +0000 (00:00 -0400)]
Fix kadmin min_life check with nonexistent policy
In kadmind, self-service key changes require a check against the
policy's min_life field. If the policy does not exist, this check
should succeed according to the semantics introduced by ticket #7385.
Fix check_min_life() to return 0 if kadm5_get_policy() returns
KADM5_UNK_POLICY. Reported by John Devitofranceschi.
Greg Hudson [Mon, 9 May 2016 17:45:06 +0000 (13:45 -0400)]
Fix unlikely pointer error in get_in_tkt.c
In add_padata(), reset the caller's pointer and ensure the list is
terminated as soon as realloc() succeeds; otherwise, the old pointer
could be left behind if a later allocation fails.
Tom Yu [Fri, 27 May 2016 19:19:43 +0000 (15:19 -0400)]
Relax t_sn2princ.py reverse resolution test
Relax t_sn2princ.py check of the reverse resolution of the test
hostname. The new requirement is that it be different from the
forward resolved hostname. (There is also an existing implicit
requirement that it be in the mit.edu domain.) This makes
t_sn2princ.py more robust against changes in the reverse resolution of
the test hostname.
In otp_client_process(), call cb->set_as_key() later in the function
after the OTP request has been created. The previous position of this
call caused the AS key to be replaced even when later code in the
function failed, preventing other preauth mechanisms from retrieving
the correct AS key.