#include "gssapiP_eap.h"
#ifdef GSSEAP_ENABLE_REAUTH
-static int
-canReauthP(gss_cred_id_t cred);
-
static OM_uint32
eapGssSmInitGssReauth(OM_uint32 *minor,
gss_cred_id_t cred,
OM_uint32 major;
const unsigned char *key;
size_t keyLength;
- krb5_enctype encryptionType;
- int gotKey = 0;
-#if 0
+#if 1
/* XXX actually check for mutual auth */
if (reqFlags & GSS_C_MUTUAL_FLAG)
ctx->gssFlags |= GSS_C_MUTUAL_FLAG;
#endif
/* Cache encryption type derived from selected mechanism OID */
- major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &encryptionType);
+ major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType);
if (GSS_ERROR(major))
return major;
- if (encryptionType != ENCTYPE_NULL &&
- eap_key_available(ctx->initiatorCtx.eap)) {
- key = eap_get_eapKeyData(ctx->initiatorCtx.eap, &keyLength);
-
- if (keyLength >= EAP_EMSK_LEN) {
- major = gssEapDeriveRfc3961Key(minor,
- &key[EAP_EMSK_LEN / 2],
- EAP_EMSK_LEN / 2,
- encryptionType,
- &ctx->rfc3961Key);
- if (GSS_ERROR(major))
- return major;
-
- major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key,
- &ctx->checksumType);
- if (GSS_ERROR(major))
- return major;
- gotKey++;
- }
- }
+ if (!eap_key_available(ctx->initiatorCtx.eap))
+ return GSS_S_UNAVAILABLE;
- if (gotKey) {
- ctx->encryptionType = encryptionType;
- } else {
- /*
- * draft-howlett-eap-gss says that integrity/confidentialty should
- * always be advertised as available, but if we have no keying
- * material it seems confusing to the caller to advertise this.
- */
- ctx->gssFlags &= ~(GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG);
- }
+ key = eap_get_eapKeyData(ctx->initiatorCtx.eap, &keyLength);
+
+ if (keyLength < EAP_EMSK_LEN)
+ return GSS_S_UNAVAILABLE;
+
+ major = gssEapDeriveRfc3961Key(minor,
+ &key[EAP_EMSK_LEN / 2],
+ EAP_EMSK_LEN / 2,
+ ctx->encryptionType,
+ &ctx->rfc3961Key);
+ if (GSS_ERROR(major))
+ return major;
+
+ major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key,
+ &ctx->checksumType);
+ if (GSS_ERROR(major))
+ return major;
major = sequenceInit(minor,
&ctx->seqState,
else
ctx->expiryTime = time(NULL) + timeReq;
+ /*
+ * The credential mutex protects its name, however we need to
+ * explicitly lock the acceptor name (unlikely as it may be
+ * that it has attributes set on it).
+ */
major = gssEapDuplicateName(minor, cred->name, &ctx->initiatorName);
if (GSS_ERROR(major))
return major;
+ GSSEAP_MUTEX_LOCK(&target->mutex);
+
major = gssEapDuplicateName(minor, target, &ctx->acceptorName);
- if (GSS_ERROR(major))
+ if (GSS_ERROR(major)) {
+ GSSEAP_MUTEX_UNLOCK(&target->mutex);
return major;
+ }
+
+ GSSEAP_MUTEX_UNLOCK(&target->mutex);
- if (mech == GSS_C_NULL_OID || oidEqual(mech, GSS_EAP_MECHANISM)) {
+ if (mech == GSS_C_NULL_OID) {
major = gssEapDefaultMech(minor, &ctx->mechanismUsed);
} else if (gssEapIsConcreteMechanismOid(mech)) {
if (!gssEapInternalizeOid(mech, &ctx->mechanismUsed))
gss_buffer_desc innerOutputToken = GSS_C_EMPTY_BUFFER;
enum gss_eap_token_type tokType;
gss_cred_id_t defaultCred = GSS_C_NO_CREDENTIAL;
+ int initialContextToken = 0;
*minor = 0;
major = gssEapAllocContext(minor, &ctx);
if (GSS_ERROR(major))
- goto cleanup;
+ return major;
ctx->flags |= CTX_FLAG_INITIATOR;
-#ifdef GSSEAP_ENABLE_REAUTH
- if (canReauthP(cred))
- ctx->state = EAP_STATE_KRB_REAUTH_GSS;
-#endif
-
+ initialContextToken = 1;
*context_handle = ctx;
}
- if (cred != GSS_C_NO_CREDENTIAL) {
- if ((cred->flags & CRED_FLAG_INITIATE) == 0) {
- major = GSS_S_NO_CRED;
- goto cleanup;
- }
- } else {
+ GSSEAP_MUTEX_LOCK(&ctx->mutex);
+
+ if (cred == GSS_C_NO_CREDENTIAL) {
if (ctx->initiatorCtx.defaultCred == GSS_C_NO_CREDENTIAL) {
major = gssEapAcquireCred(minor,
GSS_C_NO_NAME,
cred = ctx->initiatorCtx.defaultCred;
}
- GSSEAP_MUTEX_LOCK(&ctx->mutex);
+ GSSEAP_MUTEX_LOCK(&cred->mutex);
+
+#ifdef GSSEAP_ENABLE_REAUTH
+ if (initialContextToken && gssEapCanReauthP(cred, target_name, time_req))
+ ctx->state = EAP_STATE_KRB_REAUTH_GSS;
+#endif
+
+ if ((cred->flags & CRED_FLAG_INITIATE) == 0) {
+ major = GSS_S_NO_CRED;
+ goto cleanup;
+ }
sm = &eapGssInitiatorSm[ctx->state];
assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED);
cleanup:
+ if (cred != GSS_C_NO_CREDENTIAL)
+ GSSEAP_MUTEX_UNLOCK(&cred->mutex);
GSSEAP_MUTEX_UNLOCK(&ctx->mutex);
if (GSS_ERROR(major))
}
#ifdef GSSEAP_ENABLE_REAUTH
-static int
-canReauthP(gss_cred_id_t cred)
-{
- return (cred != GSS_C_NO_CREDENTIAL &&
- cred->krbCred != GSS_C_NO_CREDENTIAL &&
- cred->expiryTime > time(NULL));
-}
-
static OM_uint32
eapGssSmInitGssReauth(OM_uint32 *minor,
gss_cred_id_t cred,