aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/admin/conf_files/krb5_conf.rst7
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto_openssl.c10
-rw-r--r--src/plugins/preauth/pkinit/pkinit_identity.c30
-rwxr-xr-xsrc/tests/t_pkinit.py7
4 files changed, 29 insertions, 25 deletions
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index cb17a84..6751759 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -1126,10 +1126,9 @@ PKINIT krb5.conf options
**pkinit_identities**
Specifies the location(s) to be used to find the user's X.509
identity information. If this option is specified multiple times,
- the first valid value is used; this can be used to specify an
- environment variable (with **ENV:**\ *envvar*) followed by a
- default value. Note that these values are not used if the user
- specifies **X509_user_identity** on the command line.
+ each value is attempted in order until certificates are found.
+ Note that these values are not used if the user specifies
+ **X509_user_identity** on the command line.
**pkinit_kdc_hostname**
The presence of this option indicates that the client is willing
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index d7d1593..e5940a5 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -3748,7 +3748,7 @@ pkinit_open_session(krb5_context context,
pkinit_set_deferred_id(&cctx->deferred_ids,
p11name, tinfo.flags, NULL);
free(p11name);
- return KRB5KRB_ERR_GENERIC;
+ return 0;
}
/* Look up a responder-supplied password for the token. */
password = pkinit_find_deferred_id(cctx->deferred_ids, p11name);
@@ -4552,11 +4552,9 @@ pkinit_get_certs_pkcs11(krb5_context context,
id_cryptoctx->slotid = idopts->slotid;
id_cryptoctx->pkcs11_method = 1;
- if (pkinit_open_session(context, id_cryptoctx)) {
- pkiDebug("can't open pkcs11 session\n");
- if (!id_cryptoctx->defer_id_prompt)
- return KRB5KDC_ERR_PREAUTH_FAILED;
- }
+ r = pkinit_open_session(context, id_cryptoctx);
+ if (r != 0)
+ return r;
if (id_cryptoctx->defer_id_prompt) {
/*
* We need to reset all of the PKCS#11 state, so that the next time we
diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c
index b89c5d0..4046b15 100644
--- a/src/plugins/preauth/pkinit/pkinit_identity.c
+++ b/src/plugins/preauth/pkinit/pkinit_identity.c
@@ -378,7 +378,7 @@ process_option_identity(krb5_context context,
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_opts *idopts,
pkinit_identity_crypto_context id_cryptoctx,
- const char *value)
+ krb5_principal princ, const char *value)
{
const char *residual;
int idtype;
@@ -424,7 +424,7 @@ process_option_identity(krb5_context context,
switch (idtype) {
case IDTYPE_ENVVAR:
return process_option_identity(context, plg_cryptoctx, req_cryptoctx,
- idopts, id_cryptoctx,
+ idopts, id_cryptoctx, princ,
secure_getenv(residual));
break;
case IDTYPE_FILE:
@@ -450,7 +450,16 @@ process_option_identity(krb5_context context,
retval = EINVAL;
break;
}
- return retval;
+ if (retval)
+ return retval;
+
+ retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx, idopts,
+ id_cryptoctx, princ, TRUE);
+ if (retval)
+ return retval;
+
+ crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, id_cryptoctx);
+ return 0;
}
static krb5_error_code
@@ -525,12 +534,13 @@ pkinit_identity_initialize(krb5_context context,
if (idopts->identity != NULL) {
retval = process_option_identity(context, plg_cryptoctx,
req_cryptoctx, idopts,
- id_cryptoctx, idopts->identity);
+ id_cryptoctx, princ,
+ idopts->identity);
} else if (idopts->identity_alt != NULL) {
for (i = 0; retval != 0 && idopts->identity_alt[i] != NULL; i++) {
retval = process_option_identity(context, plg_cryptoctx,
req_cryptoctx, idopts,
- id_cryptoctx,
+ id_cryptoctx, princ,
idopts->identity_alt[i]);
}
} else {
@@ -540,16 +550,6 @@ pkinit_identity_initialize(krb5_context context,
pkiDebug("%s: no user identity options specified\n", __FUNCTION__);
goto errout;
}
- if (retval)
- goto errout;
-
- retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx,
- idopts, id_cryptoctx, princ, TRUE);
- if (retval)
- goto errout;
-
- crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
- id_cryptoctx);
} else {
/* We're the anonymous principal. */
retval = 0;
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index f224383..aee4da2 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -183,6 +183,13 @@ realm.kinit(realm.user_princ,
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
+# Try using multiple configured pkinit_identities, to make sure we
+# fall back to the second one when the first one cannot be read.
+id_conf = {'realms': {'$realm': {'pkinit_identities': [file_identity + 'X',
+ file_identity]}}}
+id_env = realm.special_env('idconf', False, krb5_conf=id_conf)
+realm.kinit(realm.user_princ, expected_trace=msgs, env=id_env)
+
# Try again using RSA instead of DH.
mark('FILE identity, no password, RSA')
realm.kinit(realm.user_princ,