]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Add indicator support to PKINIT
authorGreg Hudson <ghudson@mit.edu>
Mon, 23 Mar 2015 16:20:15 +0000 (12:20 -0400)
committerGreg Hudson <ghudson@mit.edu>
Wed, 22 Jul 2015 16:22:47 +0000 (12:22 -0400)
Read a "pkinit_indicator" profile variable for PKINIT realm
configuration and assert its values as indicators when PKINIT is used
to authenticate.  Add a test case in t_pkinit.py for this feature.

ticket: 8157

src/plugins/preauth/pkinit/pkinit.h
src/plugins/preauth/pkinit/pkinit_srv.c
src/tests/t_pkinit.py

index 83683b35276ff22769a70dd2b4cf31b82d3125dc..876db94c32f86ed498747cceffeb5b4c14dee33b 100644 (file)
@@ -66,6 +66,7 @@
 #define KRB5_CONF_REALMS                        "realms"
 #define KRB5_CONF_PKINIT_ALLOW_UPN              "pkinit_allow_upn"
 #define KRB5_CONF_PKINIT_ANCHORS                "pkinit_anchors"
+#define KRB5_CONF_PKINIT_INDICATOR              "pkinit_indicator"
 #define KRB5_CONF_PKINIT_CERT_MATCH             "pkinit_cert_match"
 #define KRB5_CONF_PKINIT_DH_MIN_BITS            "pkinit_dh_min_bits"
 #define KRB5_CONF_PKINIT_EKU_CHECKING           "pkinit_eku_checking"
@@ -226,6 +227,7 @@ struct _pkinit_kdc_context {
     pkinit_identity_opts *idopts;
     char *realmname;
     unsigned int realmname_len;
+    char **auth_indicators;
 };
 typedef struct _pkinit_kdc_context *pkinit_kdc_context;
 
index 5b1d73e4a6c4820af9e6c9bb24db67928f6d9b20..295be25e18bf7e30d28937812450ac9a589c8700 100644 (file)
@@ -298,6 +298,7 @@ pkinit_server_verify_padata(krb5_context context,
     int is_signed = 1;
     krb5_pa_data **e_data = NULL;
     krb5_kdcpreauth_modreq modreq = NULL;
+    char **sp;
 
     pkiDebug("pkinit_verify_padata: entered!\n");
     if (data == NULL || data->length <= 0 || data->contents == NULL) {
@@ -525,6 +526,15 @@ pkinit_server_verify_padata(krb5_context context,
         break;
     }
 
+    if (is_signed && plgctx->auth_indicators != NULL) {
+        /* Assert configured authentication indicators. */
+        for (sp = plgctx->auth_indicators; *sp != NULL; sp++) {
+            retval = cb->add_auth_indicator(context, rock, *sp);
+            if (retval)
+                goto cleanup;
+        }
+    }
+
     /* remember to set the PREAUTH flag in the reply */
     enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
     modreq = (krb5_kdcpreauth_modreq)reqctx;
@@ -1217,6 +1227,9 @@ pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
         free(eku_string);
     }
 
+    pkinit_kdcdefault_strings(context, plgctx->realmname,
+                              KRB5_CONF_PKINIT_INDICATOR,
+                              &plgctx->auth_indicators);
 
     return 0;
 errout:
@@ -1369,6 +1382,8 @@ errout:
 static void
 pkinit_server_plugin_fini_realm(krb5_context context, pkinit_kdc_context plgctx)
 {
+    char **sp;
+
     if (plgctx == NULL)
         return;
 
@@ -1377,6 +1392,9 @@ pkinit_server_plugin_fini_realm(krb5_context context, pkinit_kdc_context plgctx)
     pkinit_fini_identity_crypto(plgctx->idctx);
     pkinit_fini_plg_crypto(plgctx->cryptoctx);
     pkinit_fini_plg_opts(plgctx->opts);
+    for (sp = plgctx->auth_indicators; sp != NULL && *sp != NULL; sp++)
+        free(*sp);
+    free(plgctx->auth_indicators);
     free(plgctx->realmname);
     free(plgctx);
 }
index e1cc514dfe61e6f887c034872fb73d8f3af6bbc4..b66c458dff4c08446c088f1b3850f5acf8b2201d 100755 (executable)
@@ -31,7 +31,8 @@ pkinit_krb5_conf = {'realms': {'$realm': {
 pkinit_kdc_conf = {'realms': {'$realm': {
             'default_principal_flags': '+preauth',
             'pkinit_eku_checking': 'none',
-            'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem)}}}
+            'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem),
+            'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}}
 restrictive_kdc_conf = {'realms': {'$realm': {
             'restrict_anonymous_to_tgt': 'true' }}}
 
@@ -67,6 +68,9 @@ realm.addprinc('WELLKNOWN/ANONYMOUS')
 realm.kinit('@%s' % realm.realm, flags=['-n'])
 realm.klist('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS')
 realm.run([kvno, realm.host_princ])
+out = realm.run(['./adata', realm.host_princ])
+if '97:' in out:
+    fail('auth indicators seen in anonymous PKINIT ticket')
 
 # Test anonymous kadmin.
 f = open(os.path.join(realm.testdir, 'acl'), 'a')
@@ -113,6 +117,9 @@ realm.kinit(realm.user_princ,
             password='encrypted')
 realm.klist(realm.user_princ)
 realm.run([kvno, realm.host_princ])
+out = realm.run(['./adata', realm.host_princ])
+if '+97: [indpkinit1, indpkinit2]' not in out:
+    fail('auth indicators not seen in PKINIT ticket')
 
 # Run the basic test - PKINIT with FILE: identity, with a password on the key,
 # supplied by the responder.