kdc: add krb5plugin_windc_pac_pk_generate() hook
authorStefan Metzmacher <metze@samba.org>
Wed, 18 May 2016 15:07:42 +0000 (17:07 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 29 Apr 2020 09:07:57 +0000 (11:07 +0200)
This allows PAC_CRENDENTIAL_INFO to be added to the PAC
when using PKINIT. In that case PAC_CRENDENTIAL_INFO contains
an encrypted PAC_CRENDENTIAL_DATA.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11441

Signed-off-by: Stefan Metzmacher <metze@samba.org>
(similar to Samba commit 0022ea9efb0e7809fa2d060b294320eb0479cdd2)

kdc/kdc_locl.h
kdc/kerberos5.c
kdc/krb5tgs.c
kdc/windc.c
kdc/windc_plugin.h
tests/plugin/windc.c

index faa89f9b96b58acae2db45bfc7ed7b933e693883..d38d041a8f57f177fa693744b5f3154d88d0fab6 100644 (file)
@@ -78,6 +78,7 @@ struct astgs_request_desc {
     EncKDCRepPart ek;
 
     /* PA methods can affect both the reply key and the session key (pkinit) */
+    int validated_pa_type;
     krb5_enctype sessionetype;
     krb5_keyblock reply_key;
     krb5_keyblock session_key;
index 75a90c41527f1978d0e8821eb3283db984fa1675..0eebe63930f7d87a1a8ec6ccb713b15075e9880c 100644 (file)
@@ -1682,10 +1682,19 @@ static krb5_error_code
 generate_pac(astgs_request_t r, Key *skey)
 {
     krb5_error_code ret;
+    const krb5_keyblock *pk_reply_key = NULL;
     krb5_pac p = NULL;
     krb5_data data;
 
-    ret = _kdc_pac_generate(r->context, r->client, &p);
+    switch (r->validated_pa_type) {
+    case KRB5_PADATA_PK_AS_REQ:
+    case KRB5_PADATA_PK_AS_REQ_WIN:
+       pk_reply_key = &r->reply_key;
+       break;
+    }
+
+    ret = _kdc_pac_generate(r->context, r->client,
+                           pk_reply_key, &p);
     if (ret) {
        _kdc_r_log(r, 4, "PAC generation failed for -- %s",
                   r->cname);
@@ -1992,6 +2001,7 @@ _kdc_as_rep(astgs_request_t r)
                        pat[n].name, r->cname);
                found_pa = 1;
                r->et.flags.pre_authent = 1;
+               r->validated_pa_type = pat[n].type;
            }
        }
     }
index b1398062d1e563f6883de6268b079aebea392a06..1e0e136e8a373057c77207602f3946652463184b 100644 (file)
@@ -2167,7 +2167,8 @@ server_lookup:
            if(rspac.data) {
                krb5_pac p = NULL;
                krb5_data_free(&rspac);
-               ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p);
+               ret = _kdc_pac_generate(context, s4u2self_impersonated_client,
+                                       NULL, &p);
                if (ret) {
                    kdc_log(context, config, 4, "PAC generation failed for -- %s",
                            tpn);
index 05c59caf2464f8e2fbcdbcf5fd37a12a0153f997..e85b614d6bf54bf6382de20db849cceec8d9e8fe 100644 (file)
@@ -71,6 +71,7 @@ krb5_kdc_windc_init(krb5_context context)
 
 struct generate_uc {
     hdb_entry_ex *client;
+    const krb5_keyblock *pk_reply_key;
     krb5_pac *pac;
 };
 
@@ -82,6 +83,12 @@ generate(krb5_context context, const void *plug, void *plugctx, void *userctx)
 
     if (ft->pac_generate == NULL)
        return KRB5_PLUGIN_NO_HANDLE;
+
+    if (ft->pac_pk_generate != NULL && uc->pk_reply_key != NULL) {
+       return ft->pac_pk_generate((void *)plug, context,
+                                  uc->client, uc->pk_reply_key, uc->pac);
+    }
+
     return ft->pac_generate((void *)plug, context, uc->client, uc->pac);
 }
 
@@ -89,6 +96,7 @@ generate(krb5_context context, const void *plug, void *plugctx, void *userctx)
 krb5_error_code
 _kdc_pac_generate(krb5_context context,
                  hdb_entry_ex *client,
+                 const krb5_keyblock *pk_reply_key,
                  krb5_pac *pac)
 {
     struct generate_uc uc;
@@ -97,6 +105,7 @@ _kdc_pac_generate(krb5_context context,
        return 0;
 
     uc.client = client;
+    uc.pk_reply_key = pk_reply_key;
     uc.pac = pac;
 
     (void)_krb5_plugin_run_f(context, &windc_plugin_data,
index 4401500e6563157abb46da14337734e59ec1339f..12bfd7f8a164ab9a5ca4b4c2ef347cc41c01f8c6 100644 (file)
@@ -53,7 +53,14 @@ struct hdb_entry_ex;
 
 typedef krb5_error_code
 (*krb5plugin_windc_pac_generate)(void *, krb5_context,
-                                struct hdb_entry_ex *, krb5_pac *);
+                                struct hdb_entry_ex *, /* client */
+                                krb5_pac *);
+
+typedef krb5_error_code
+(*krb5plugin_windc_pac_pk_generate)(void *, krb5_context,
+                                   struct hdb_entry_ex *, /* client */
+                                   const krb5_keyblock *, /* pk_replykey */
+                                   krb5_pac *);
 
 typedef krb5_error_code
 (*krb5plugin_windc_pac_verify)(void *, krb5_context,
@@ -73,7 +80,7 @@ typedef krb5_error_code
        KDC_REQ *, METHOD_DATA *);
 
 
-#define KRB5_WINDC_PLUGIN_MINOR                        6
+#define KRB5_WINDC_PLUGIN_MINOR                        7
 #define KRB5_WINDC_PLUGING_MINOR KRB5_WINDC_PLUGIN_MINOR
 
 typedef struct krb5plugin_windc_ftable {
@@ -83,6 +90,7 @@ typedef struct krb5plugin_windc_ftable {
     krb5plugin_windc_pac_generate      pac_generate;
     krb5plugin_windc_pac_verify                pac_verify;
     krb5plugin_windc_client_access     client_access;
+    krb5plugin_windc_pac_pk_generate    pac_pk_generate;
 } krb5plugin_windc_ftable;
 
 #endif /* HEIMDAL_KRB5_PAC_PLUGIN_H */
index 65d0ddf86d5c581d3ef186716d48ef0c450a8076..9fbe495aa07e97062473f2acfb88a10ae7563f18 100644 (file)
@@ -41,6 +41,31 @@ pac_generate(void *ctx, krb5_context context,
     return 0;
 }
 
+static krb5_error_code
+pac_pk_generate(void *ctx, krb5_context context,
+               struct hdb_entry_ex *client,
+               const krb5_keyblock *pk_replykey,
+               krb5_pac *pac)
+{
+    krb5_error_code ret;
+    krb5_data data;
+
+    krb5_warnx(context, "pac pk generate");
+
+    data.data = "\x00\x01";
+    data.length = 2;
+
+    ret = krb5_pac_init(context, pac);
+    if (ret)
+       return ret;
+
+    ret = krb5_pac_add_buffer(context, *pac, 1, &data);
+    if (ret)
+       return ret;
+
+    return 0;
+}
+
 static krb5_error_code
 pac_verify(void *ctx, krb5_context context,
           const krb5_principal new_ticket_client,
@@ -83,7 +108,8 @@ static krb5plugin_windc_ftable windc = {
     windc_fini,
     pac_generate,
     pac_verify,
-    client_access
+    client_access,
+    pac_pk_generate
 };
 
 static const krb5plugin_windc_ftable *const windc_plugins[] = {