Optional backwards-compatible anon-pkinit behaviour

* Anonymous pkinit responses from the KDC where the name
  type is not well-known (as issued by 7.5 KDCs and earlier)
  are accepted by the client.  There is no need for the client
  to strictly enforce the name type.

* With historical_anon_pkinit = true, the kinit(1) client's
  "--anonymous" option only performs anon pkinit, and does
  not require an '@' prefix for the realm argument.

* With historical_anon_realm = true, the KDC issues anon
  pkinit tickets with the legacy pre-7.0 "real" realm.
This commit is contained in:
Viktor Dukhovni
2019-07-14 23:02:57 -04:00
committed by Viktor Dukhovni
parent f40d393c83
commit fae8df3839
11 changed files with 141 additions and 27 deletions

View File

@@ -541,10 +541,22 @@ check_client_anonymous(krb5_context context,
if (!rep->enc_part.flags.anonymous)
return KRB5KDC_ERR_BADOPTION;
/*
* Here we must validate that the AS returned a ticket of the expected type
* for either a fully anonymous request, or authenticated request for an
* anonymous ticket. If this is a TGS request, we're done. Then if the
* 'requested' principal was anonymous, we'll check the 'mapped' principal
* accordingly (without enforcing the name type and perhaps the realm).
* Finally, if the 'requested' principal was not anonymous, well check
* that the 'mapped' principal has an anonymous name and type, in a
* non-anonymous realm. (Should we also be checking for a realm match
* between the request and the mapped name in this case?)
*/
if (is_tgs_rep)
flags = KRB5_ANON_MATCH_ANY;
else if (krb5_principal_is_anonymous(context, requested, KRB5_ANON_MATCH_ANY))
flags = KRB5_ANON_MATCH_UNAUTHENTICATED;
flags = KRB5_ANON_MATCH_ANY_NONT;
else if (krb5_principal_is_anonymous(context, requested,
KRB5_ANON_MATCH_ANY_NONT))
flags = KRB5_ANON_MATCH_UNAUTHENTICATED | KRB5_ANON_IGNORE_NAME_TYPE;
else
flags = KRB5_ANON_MATCH_AUTHENTICATED;
@@ -566,7 +578,8 @@ check_client_mismatch(krb5_context context,
krb5_keyblock const * key)
{
if (rep->enc_part.flags.anonymous) {
if (!krb5_principal_is_anonymous(context, mapped, KRB5_ANON_MATCH_ANY)) {
if (!krb5_principal_is_anonymous(context, mapped,
KRB5_ANON_MATCH_ANY_NONT)) {
krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
N_("Anonymous ticket does not contain anonymous "
"principal", ""));