From 09bcd48f79043e54fdce840f70e370b9a507d0fc Mon Sep 17 00:00:00 2001 From: Jo Sutton Date: Thu, 9 May 2024 16:57:14 +1200 Subject: [PATCH] third_party/heimdal: Import lorikeet-heimdal-202405090452 (commit 49c8e97b7221db53355258059ef385c856e1385f) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NOTE: THIS COMMIT WON’T COMPILE/WORK ON ITS OWN! Signed-off-by: Jo Sutton Reviewed-by: Andrew Bartlett --- selftest/skip | 1 - third_party/heimdal/kdc/kdc-plugin.c | 29 +++++++++++++- third_party/heimdal/kdc/kdc-plugin.h | 13 +++++- third_party/heimdal/kdc/kerberos5.c | 59 ++++++++++++++++------------ 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/selftest/skip b/selftest/skip index 2f304237f93..b5266bb16d8 100644 --- a/selftest/skip +++ b/selftest/skip @@ -147,4 +147,3 @@ bench # don't run benchmarks in our selftest ^samba4.smb2.tcon.*\(ad_dc_ntvfs\)$ # Ignore ad_dc_ntvfs since this is a new test ^samba4.smb2.mkdir.*\(ad_dc_ntvfs\)$ # Ignore ad_dc_ntvfs since this is a new test ^samba3.blackbox.open-eintr.* -^samba\.tests\.krb5\. # Lots of these tests will fail until we’ve updated the Hemidal KDC to generate PAC checksums. diff --git a/third_party/heimdal/kdc/kdc-plugin.c b/third_party/heimdal/kdc/kdc-plugin.c index 3b065c698d1..bf41099d9b0 100644 --- a/third_party/heimdal/kdc/kdc-plugin.c +++ b/third_party/heimdal/kdc/kdc-plugin.c @@ -51,7 +51,7 @@ static const char *kdc_plugin_deps[] = { static struct heim_plugin_data kdc_plugin_data = { "krb5", "kdc", - KRB5_PLUGIN_KDC_VERSION_11, + KRB5_PLUGIN_KDC_VERSION_12, kdc_plugin_deps, kdc_get_instance }; @@ -301,6 +301,33 @@ _kdc_referral_policy(astgs_request_t r) return ret; } +static krb5_error_code KRB5_LIB_CALL +hwauth_policy(krb5_context context, const void *plug, void *plugctx, void *userctx) +{ + const krb5plugin_kdc_ftable *ft = plug; + + if (ft->hwauth_policy == NULL) { + return KRB5_PLUGIN_NO_HANDLE; + } + return ft->hwauth_policy((void *)plug, userctx); +} + +krb5_error_code +_kdc_hwauth_policy(astgs_request_t r) +{ + krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE; + + if (have_plugin) { + ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data, 0, r, hwauth_policy); + } + + if (ret == KRB5_PLUGIN_NO_HANDLE) { + ret = 0; + } + + return ret; +} + static krb5_error_code KRB5_LIB_CALL finalize_reply(krb5_context context, const void *plug, void *plugctx, void *userctx) { diff --git a/third_party/heimdal/kdc/kdc-plugin.h b/third_party/heimdal/kdc/kdc-plugin.h index 53613498050..e264bbf4d0a 100644 --- a/third_party/heimdal/kdc/kdc-plugin.h +++ b/third_party/heimdal/kdc/kdc-plugin.h @@ -113,6 +113,16 @@ typedef krb5_error_code typedef krb5_error_code (KRB5_CALLCONV *krb5plugin_kdc_referral_policy)(void *, astgs_request_t); +/* + * A hardware authentication policy plugin can indicate what is to + * happen when a client authenticates using a method other than + * hardware authentication. It can return zero to allow the + * authentication, or an appropriate error code to deny it. + */ + +typedef krb5_error_code +(KRB5_CALLCONV *krb5plugin_kdc_hwauth_policy)(void *, astgs_request_t); + /* * Update the AS or TGS reply immediately prior to encoding. */ @@ -135,7 +145,7 @@ typedef krb5_error_code * Plugins should carefully check API contract notes for changes * between plugin API versions. */ -#define KRB5_PLUGIN_KDC_VERSION_11 11 +#define KRB5_PLUGIN_KDC_VERSION_12 12 typedef struct krb5plugin_kdc_ftable { HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context); @@ -144,6 +154,7 @@ typedef struct krb5plugin_kdc_ftable { krb5plugin_kdc_pac_update pac_update; krb5plugin_kdc_client_access client_access; krb5plugin_kdc_referral_policy referral_policy; + krb5plugin_kdc_hwauth_policy hwauth_policy; krb5plugin_kdc_finalize_reply finalize_reply; krb5plugin_kdc_audit audit; } krb5plugin_kdc_ftable; diff --git a/third_party/heimdal/kdc/kerberos5.c b/third_party/heimdal/kdc/kerberos5.c index d8127e850f9..22f16e169d2 100644 --- a/third_party/heimdal/kdc/kerberos5.c +++ b/third_party/heimdal/kdc/kerberos5.c @@ -1382,6 +1382,7 @@ struct kdc_patypes { #define PA_REPLACE_REPLY_KEY 8 /* PA mech replaces reply key */ #define PA_USES_LONG_TERM_KEY 16 /* PA mech uses client's long-term key */ #define PA_USES_FAST_COOKIE 32 /* Multi-step PA mech maintains state in PA-FX-COOKIE */ +#define PA_HARDWARE_AUTH 64 /* PA mech uses hardware authentication */ krb5_error_code (*validate)(astgs_request_t, const PA_DATA *pa); krb5_error_code (*finalize_pac)(astgs_request_t r); void (*cleanup)(astgs_request_t r); @@ -1391,11 +1392,11 @@ static const struct kdc_patypes pat[] = { #ifdef PKINIT { KRB5_PADATA_PK_AS_REQ, "PK-INIT(ietf)", - PA_ANNOUNCE | PA_SYNTHETIC_OK | PA_REPLACE_REPLY_KEY, + PA_ANNOUNCE | PA_SYNTHETIC_OK | PA_REPLACE_REPLY_KEY | PA_HARDWARE_AUTH, pa_pkinit_validate, NULL, NULL }, { - KRB5_PADATA_PK_AS_REQ_WIN, "PK-INIT(win2k)", PA_ANNOUNCE | PA_REPLACE_REPLY_KEY, + KRB5_PADATA_PK_AS_REQ_WIN, "PK-INIT(win2k)", PA_ANNOUNCE | PA_REPLACE_REPLY_KEY | PA_HARDWARE_AUTH, pa_pkinit_validate, NULL, NULL }, { @@ -2224,7 +2225,6 @@ generate_pac(astgs_request_t r, const Key *skey, const Key *tkey, krb5_boolean is_tgs) { krb5_error_code ret; - krb5_data data; uint16_t rodc_id; krb5_principal client; krb5_const_principal canon_princ = NULL; @@ -2289,18 +2289,18 @@ generate_pac(astgs_request_t r, const Key *skey, const Key *tkey, return ret; } - ret = _krb5_pac_sign(r->context, - r->pac, - r->et.authtime, - client, - &skey->key, /* Server key */ - &tkey->key, /* TGS key */ - rodc_id, - NULL, /* UPN */ - canon_princ, - FALSE, /* add_full_sig */ - is_tgs ? &r->pac_attributes : NULL, - &data); + ret = _krb5_kdc_pac_sign_ticket(r->context, + r->pac, + client, + &skey->key, /* Server key */ + &tkey->key, /* TGS key */ + rodc_id, + NULL, /* UPN */ + canon_princ, + !is_tgs, /* add_ticket_sig */ + !is_tgs, /* add_full_sig */ + &r->et, + is_tgs ? &r->pac_attributes : NULL); krb5_free_principal(r->context, client); krb5_pac_free(r->context, r->pac); r->pac = NULL; @@ -2309,9 +2309,6 @@ generate_pac(astgs_request_t r, const Key *skey, const Key *tkey, r->cname); return ret; } - - ret = _kdc_tkt_insert_pac(r->context, &r->et, &data); - krb5_data_free(&data); return ret; } @@ -2691,6 +2688,13 @@ _kdc_as_rep(astgs_request_t r) ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; goto out; } + if (!(pat[n].flags & PA_HARDWARE_AUTH)) { + ret = _kdc_hwauth_policy(r); + if (ret) { + kdc_log(r->context, config, 4, "Hardware authentication required for %s", r->cname); + return ret; + } + } kdc_audit_addkv((kdc_request_t)r, KDC_AUDIT_VIS, "pa", "%s", pat[n].name); ret = pat[n].validate(r, pa); @@ -3098,13 +3102,6 @@ _kdc_as_rep(astgs_request_t r) if (ret) goto out; - /* Add the PAC */ - if (!r->et.flags.anonymous) { - ret = generate_pac(r, skey, krbtgt_key, is_tgs); - if (ret) - goto out; - } - if (r->client->flags.synthetic) { ret = add_synthetic_princ_ad(r); if (ret) @@ -3148,6 +3145,18 @@ _kdc_as_rep(astgs_request_t r) } } + /* Add the PAC */ + if (!r->et.flags.anonymous) { + ret = generate_pac(r, skey, krbtgt_key, is_tgs); + if (ret) + goto out; + } + + /* + * No more changes to the ticket (r->et) from this point on, lest + * the checksums in the PAC be invalidated. + */ + /* * Last chance for plugins to update reply */