X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util_cred.c;h=58700c7acf65dec00fc68960abe0cf6af4925352;hb=15c93f06ee6ddefa7e7b095351f6e66698c7cc9e;hp=384c5a10e87b30b16f63deb243b65713269ec983;hpb=8d7ecc1269758649a208083877dd766c14717a67;p=mech_eap.git diff --git a/util_cred.c b/util_cred.c index 384c5a1..58700c7 100644 --- a/util_cred.c +++ b/util_cred.c @@ -35,9 +35,10 @@ OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred) { + OM_uint32 tmpMinor; gss_cred_id_t cred; - assert(*pCred == GSS_C_NO_CREDENTIAL); + *pCred = GSS_C_NO_CREDENTIAL; cred = (gss_cred_id_t)GSSEAP_CALLOC(1, sizeof(*cred)); if (cred == NULL) { @@ -45,8 +46,15 @@ gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred) return GSS_S_FAILURE; } + if (GSSEAP_MUTEX_INIT(&cred->mutex) != 0) { + *minor = errno; + gssEapReleaseCred(&tmpMinor, &cred); + return GSS_S_FAILURE; + } + *pCred = cred; + *minor = 0; return GSS_S_COMPLETE; } @@ -55,12 +63,14 @@ gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred) { OM_uint32 tmpMinor; gss_cred_id_t cred = *pCred; - krb5_context kerbCtx = NULL; + krb5_context krbContext = NULL; if (cred == GSS_C_NO_CREDENTIAL) { return GSS_S_COMPLETE; } + GSSEAP_KRB_INIT(&krbContext); + gssEapReleaseName(&tmpMinor, &cred->name); if (cred->password.value != NULL) { @@ -68,11 +78,157 @@ gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred) GSSEAP_FREE(cred->password.value); } + if (cred->radiusConfigFile != NULL) + GSSEAP_FREE(cred->radiusConfigFile); + if (cred->radiusConfigStanza != NULL) + GSSEAP_FREE(cred->radiusConfigStanza); + +#ifdef GSSEAP_ENABLE_REAUTH + if (cred->krbCredCache != NULL) { + if (cred->flags & CRED_FLAG_DEFAULT_CCACHE) + krb5_cc_close(krbContext, cred->krbCredCache); + else + krb5_cc_destroy(krbContext, cred->krbCredCache); + } + if (cred->krbCred != GSS_C_NO_CREDENTIAL) + gssReleaseCred(&tmpMinor, &cred->krbCred); +#endif + + GSSEAP_MUTEX_DESTROY(&cred->mutex); memset(cred, 0, sizeof(*cred)); GSSEAP_FREE(cred); - *pCred = NULL; + *minor = 0; return GSS_S_COMPLETE; } +OM_uint32 +gssEapAcquireCred(OM_uint32 *minor, + const gss_name_t desiredName, + const gss_buffer_t password, + OM_uint32 timeReq, + const gss_OID_set desiredMechs, + int credUsage, + gss_cred_id_t *pCred, + gss_OID_set *pActualMechs, + OM_uint32 *timeRec) +{ + OM_uint32 major, tmpMinor; + gss_cred_id_t cred; + + /* XXX TODO validate with changed set_cred_option API */ + *pCred = GSS_C_NO_CREDENTIAL; + + major = gssEapAllocCred(minor, &cred); + if (GSS_ERROR(major)) + goto cleanup; + + if (desiredName != GSS_C_NO_NAME) { + GSSEAP_MUTEX_LOCK(&desiredName->mutex); + + major = gssEapDuplicateName(minor, desiredName, &cred->name); + if (GSS_ERROR(major)) { + GSSEAP_MUTEX_UNLOCK(&desiredName->mutex); + goto cleanup; + } + + GSSEAP_MUTEX_UNLOCK(&desiredName->mutex); + } else { + if (cred->flags & CRED_FLAG_INITIATE) { + gss_buffer_desc buf; + + buf.value = getlogin(); /* XXX */ + buf.length = strlen((char *)buf.value); + + major = gssEapImportName(minor, &buf, + GSS_C_NT_USER_NAME, &cred->name); + if (GSS_ERROR(major)) + goto cleanup; + } + + cred->flags |= CRED_FLAG_DEFAULT_IDENTITY; + } + + if (password != GSS_C_NO_BUFFER) { + major = duplicateBuffer(minor, password, &cred->password); + if (GSS_ERROR(major)) + goto cleanup; + + cred->flags |= CRED_FLAG_PASSWORD; + } else if (credUsage == GSS_C_INITIATE) { + /* + * OK, here we need to ask the supplicant if we have creds or it + * will acquire them, so GS2 can know whether to prompt for a + * password or not. + */ +#if 0 + && !gssEapCanReauthP(cred, GSS_C_NO_NAME, timeReq) +#endif + major = GSS_S_CRED_UNAVAIL; + goto cleanup; + } + + switch (credUsage) { + case GSS_C_BOTH: + cred->flags |= CRED_FLAG_INITIATE | CRED_FLAG_ACCEPT; + break; + case GSS_C_INITIATE: + cred->flags |= CRED_FLAG_INITIATE; + break; + case GSS_C_ACCEPT: + cred->flags |= CRED_FLAG_ACCEPT; + break; + default: + *minor = GSSEAP_BAD_USAGE; + major = GSS_S_FAILURE; + goto cleanup; + break; + } + + major = gssEapValidateMechs(minor, desiredMechs); + if (GSS_ERROR(major)) + goto cleanup; + + major = duplicateOidSet(minor, desiredMechs, &cred->mechanisms); + if (GSS_ERROR(major)) + goto cleanup; + + if (pActualMechs != NULL) { + major = duplicateOidSet(minor, cred->mechanisms, pActualMechs); + if (GSS_ERROR(major)) + goto cleanup; + } + + if (timeRec != NULL) + *timeRec = GSS_C_INDEFINITE; + + *pCred = cred; + major = GSS_S_COMPLETE; + +cleanup: + if (GSS_ERROR(major)) + gssEapReleaseCred(&tmpMinor, &cred); + + return major; +} + +/* + * Return TRUE if cred available for mechanism. Caller need no acquire + * lock because mechanisms list is immutable. + */ +int +gssEapCredAvailable(gss_cred_id_t cred, gss_OID mech) +{ + OM_uint32 minor; + int present = 0; + + assert(mech != GSS_C_NO_OID); + + if (cred == GSS_C_NO_CREDENTIAL || cred->mechanisms == GSS_C_NO_OID_SET) + return TRUE; + + gss_test_oid_set_member(&minor, mech, cred->mechanisms, &present); + + return present; +}