kdc: allow anonymous AS requests with long-term keys
RFC8062 section 4.1 allows clients with long-term KDC keys to set the anonymous flag; in this case their identity is authenticated but the returned ticket contains the anonymous principal name as the client name. kdc: allow authenticated anonymous PKINIT The KDC PKINIT code conflated the checks for authenticated and unauthenticated anonymous by only looking at the anonymous KDC request option.
This commit is contained in:

committed by
Jeffrey Altman

parent
5c8f48495e
commit
63557427e0
@@ -597,12 +597,6 @@ pa_enc_ts_validate(kdc_request_t r, const PA_DATA *pa)
|
|||||||
Key *pa_key;
|
Key *pa_key;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
if (_kdc_is_anon_request(&r->req.req_body)) {
|
|
||||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
|
||||||
_kdc_set_e_text(r, "ENC-TS doesn't support anon");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = decode_EncryptedData(pa->padata_value.data,
|
ret = decode_EncryptedData(pa->padata_value.data,
|
||||||
pa->padata_value.length,
|
pa->padata_value.length,
|
||||||
&enc_data,
|
&enc_data,
|
||||||
@@ -1774,16 +1768,10 @@ _kdc_as_rep(kdc_request_t r,
|
|||||||
|
|
||||||
if (_kdc_is_anonymous(context, r->client_princ)) {
|
if (_kdc_is_anonymous(context, r->client_princ)) {
|
||||||
if (!_kdc_is_anon_request(b)) {
|
if (!_kdc_is_anon_request(b)) {
|
||||||
kdc_log(context, config, 0, "Anonymous ticket w/o anonymous flag");
|
kdc_log(context, config, 0, "Anonymous client w/o anonymous flag");
|
||||||
ret = KRB5KDC_ERR_BADOPTION;
|
ret = KRB5KDC_ERR_BADOPTION;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else if (_kdc_is_anon_request(b)) {
|
|
||||||
kdc_log(context, config, 0,
|
|
||||||
"Request for a anonymous ticket with non "
|
|
||||||
"anonymous client name: %s", r->client_name);
|
|
||||||
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2021,7 +2009,9 @@ _kdc_as_rep(kdc_request_t r,
|
|||||||
ret = copy_Realm(&r->client_princ->realm, &rep.crealm);
|
ret = copy_Realm(&r->client_princ->realm, &rep.crealm);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
if (f.canonicalize || r->client->entry.flags.force_canonicalize)
|
if (_kdc_is_anon_request(b))
|
||||||
|
ret = _kdc_make_anonymous_principalname(&rep.cname);
|
||||||
|
else if (f.canonicalize || r->client->entry.flags.force_canonicalize)
|
||||||
ret = _krb5_principal2principalname(&rep.cname, r->client->entry.principal);
|
ret = _krb5_principal2principalname(&rep.cname, r->client->entry.principal);
|
||||||
else
|
else
|
||||||
ret = _krb5_principal2principalname(&rep.cname, r->client_princ);
|
ret = _krb5_principal2principalname(&rep.cname, r->client_princ);
|
||||||
|
10
kdc/pkinit.c
10
kdc/pkinit.c
@@ -477,7 +477,7 @@ _kdc_pk_rd_padata(krb5_context context,
|
|||||||
|
|
||||||
type = "PK-INIT-Win2k";
|
type = "PK-INIT-Win2k";
|
||||||
|
|
||||||
if (_kdc_is_anon_request(&req->req_body)) {
|
if (_kdc_is_anonymous(context, client->entry.principal)) {
|
||||||
ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
|
ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
|
||||||
krb5_set_error_message(context, ret,
|
krb5_set_error_message(context, ret,
|
||||||
"Anon not supported in RSA mode");
|
"Anon not supported in RSA mode");
|
||||||
@@ -623,7 +623,7 @@ _kdc_pk_rd_padata(krb5_context context,
|
|||||||
hx509_certs signer_certs;
|
hx509_certs signer_certs;
|
||||||
int flags = HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH; /* BTMM */
|
int flags = HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH; /* BTMM */
|
||||||
|
|
||||||
if (_kdc_is_anon_request(&req->req_body))
|
if (_kdc_is_anonymous(context, client->entry.principal))
|
||||||
flags |= HX509_CMS_VS_ALLOW_ZERO_SIGNER;
|
flags |= HX509_CMS_VS_ALLOW_ZERO_SIGNER;
|
||||||
|
|
||||||
ret = hx509_cms_verify_signed(context->hx509ctx,
|
ret = hx509_cms_verify_signed(context->hx509ctx,
|
||||||
@@ -708,7 +708,7 @@ _kdc_pk_rd_padata(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_kdc_is_anon_request(&req->req_body) &&
|
if (_kdc_is_anonymous(context, client->entry.principal) &&
|
||||||
ap.clientPublicValue == NULL) {
|
ap.clientPublicValue == NULL) {
|
||||||
free_AuthPack(&ap);
|
free_AuthPack(&ap);
|
||||||
ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
|
ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
|
||||||
@@ -1676,8 +1676,10 @@ _kdc_pk_check_client(krb5_context context,
|
|||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (cp->cert == NULL) {
|
if (cp->cert == NULL) {
|
||||||
|
if (!_kdc_is_anonymous(context, client->entry.principal))
|
||||||
|
return KRB5KDC_ERR_BADOPTION;
|
||||||
|
|
||||||
*subject_name = strdup("anonymous client client");
|
*subject_name = strdup("<unauthenticated anonymous client>");
|
||||||
if (*subject_name == NULL)
|
if (*subject_name == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user