krb5 commit: Add indicator support to PKINIT

Greg Hudson ghudson at mit.edu
Wed Jul 22 13:29:44 EDT 2015


https://github.com/krb5/krb5/commit/8ca82f0e3059cd8805f4dda388a8aa1d67c80920
commit 8ca82f0e3059cd8805f4dda388a8aa1d67c80920
Author: Greg Hudson <ghudson at mit.edu>
Date:   Mon Mar 23 12:20:15 2015 -0400

    Add indicator support to PKINIT
    
    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     |    2 ++
 src/plugins/preauth/pkinit/pkinit_srv.c |   18 ++++++++++++++++++
 src/tests/t_pkinit.py                   |    9 ++++++++-
 3 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
index 83683b3..876db94 100644
--- a/src/plugins/preauth/pkinit/pkinit.h
+++ b/src/plugins/preauth/pkinit/pkinit.h
@@ -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;
 
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index 5b1d73e..295be25 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -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);
 }
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index e1cc514..b66c458 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -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 at 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.


More information about the cvs-krb5 mailing list