From: Greg Hudson Date: Mon, 23 Mar 2015 16:20:15 +0000 (-0400) Subject: Add indicator support to PKINIT X-Git-Tag: krb5-1.14-alpha1~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ca82f0e3059cd8805f4dda388a8aa1d67c80920;p=thirdparty%2Fkrb5.git 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 --- diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h index 83683b3527..876db94c32 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 5b1d73e4a6..295be25e18 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 e1cc514dfe..b66c458dff 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@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.