Fix enctype selection issues for PAC and other authz-data signatures

We were using the enctype from the PA-TGS-REQ's AP-REQ's Ticket to
    decide what key from the service's realm's krbtgt principal to use.
    This breaks when: a) we're doing cross-realm, b) the service's
    realm's krbtgt principal doesn't have keys for the enctype used in
    the cross-realm TGT.

    The fix is to pick the correct key (strongest or first, per-config)
    from the service's realm's krbtgt principal.
This commit is contained in:
Nicolas Williams
2011-11-08 19:54:45 -06:00
parent 40a7d4b62f
commit 8586d9f88e

View File

@@ -1483,8 +1483,8 @@ tgs_build_reply(krb5_context context,
{
krb5_error_code ret;
krb5_principal cp = NULL, sp = NULL, rsp = NULL, tp = NULL, dp = NULL;
krb5_principal krbtgt_principal = NULL;
char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL;
krb5_principal krbtgt_out_principal = NULL;
char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL, *krbtgt_out_n = NULL;
hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL;
HDB *clientdb, *s4u2self_impersonated_clientdb;
krb5_realm ref_realm = NULL;
@@ -1753,32 +1753,36 @@ server_lookup:
krb5_principal_get_comp_string(context, krbtgt->entry.principal, 1);
ret = krb5_make_principal(context,
&krbtgt_principal,
&krbtgt_out_principal,
remote_realm,
KRB5_TGS_NAME,
remote_realm,
NULL);
if(ret) {
kdc_log(context, config, 0,
"Failed to generate krbtgt principal");
"Failed to make krbtgt principal name object for "
"authz-data signatures");
goto out;
}
ret = krb5_unparse_name(context, krbtgt_out_principal, &krbtgt_out_n);
if (ret) {
kdc_log(context, config, 0,
"Failed to make krbtgt principal name object for "
"authz-data signatures");
goto out;
}
}
ret = _kdc_db_fetch(context, config, krbtgt_principal, HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out);
krb5_free_principal(context, krbtgt_principal);
ret = _kdc_db_fetch(context, config, krbtgt_out_principal,
HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out);
if (ret) {
krb5_error_code ret2;
char *ktpn, *ktpn2;
char *ktpn = NULL;
ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn);
ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2);
kdc_log(context, config, 0,
"Request with wrong krbtgt: %s, %s not found in our database",
(ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>");
if(ret == 0)
free(ktpn);
if(ret2 == 0)
free(ktpn2);
"No such principal %s (needed for authz-data signature keys) "
"while processing TGS-REQ for service %s with krbtg %s",
krbtgt_out_n, spn, (ret == 0) ? ktpn : "<unknown>");
free(ktpn);
ret = KRB5KRB_AP_ERR_NOT_US;
goto out;
}
@@ -1803,8 +1807,15 @@ server_lookup:
goto out;
}
ret = _kdc_get_preferred_key(context, config, krbtgt_out, krbtgt_out_n,
NULL, &tkey_sign);
if (ret) {
kdc_log(context, config, 0,
"Failed to find key for krbtgt PAC signature");
goto out;
}
ret = hdb_enctype2key(context, &krbtgt_out->entry,
krbtgt_etype, &tkey_sign);
tkey_sign->key.keytype, &tkey_sign);
if(ret) {
kdc_log(context, config, 0,
"Failed to find key for krbtgt PAC signature");
@@ -2254,7 +2265,7 @@ server_lookup:
client,
cp,
krbtgt_out,
krbtgt_etype,
tkey_sign->key.keytype,
spp,
&rspac,
&enc_pa_data,
@@ -2266,8 +2277,8 @@ out:
free(tpn);
free(spn);
free(cpn);
if (dpn)
free(dpn);
free(dpn);
free(krbtgt_out_n);
krb5_data_free(&rspac);
krb5_free_keyblock_contents(context, &sessionkey);
@@ -2282,12 +2293,10 @@ out:
if (tp && tp != cp)
krb5_free_principal(context, tp);
if (cp)
krb5_free_principal(context, cp);
if (dp)
krb5_free_principal(context, dp);
if (sp)
krb5_free_principal(context, sp);
krb5_free_principal(context, cp);
krb5_free_principal(context, dp);
krb5_free_principal(context, sp);
krb5_free_principal(context, krbtgt_out_principal);
if (ref_realm)
free(ref_realm);
free_METHOD_DATA(&enc_pa_data);