Merge branch 'master' of ssh://moonshot.suchdamage.org:822/srv/git/moonshot
[mech_eap.orig] / init_sec_context.c
index 56f41de..d90f9e6 100644 (file)
  * SUCH DAMAGE.
  */
 
+/*
+ * Establish a security context on the initiator (client). These functions
+ * wrap around libeap.
+ */
+
 #include "gssapiP_eap.h"
 
 #ifdef GSSEAP_ENABLE_REAUTH
@@ -221,6 +226,13 @@ peerConfigInit(OM_uint32 *minor,
     eapPeerConfig->fragment_size = 1024;
     wpa_debug_level = 0;
 
+    assert(cred->name != GSS_C_NO_NAME);
+
+    if ((cred->name->flags & (NAME_FLAG_NAI | NAME_FLAG_SERVICE)) == 0) {
+        *minor = GSSEAP_BAD_INITIATOR_NAME;
+        return GSS_S_BAD_NAME;
+    }
+
     code = krb5_unparse_name(krbContext, cred->name->krbPrincipal, &identity);
     if (code != 0) {
         *minor = code;
@@ -232,6 +244,7 @@ peerConfigInit(OM_uint32 *minor,
     eapPeerConfig->password = (unsigned char *)cred->password.value;
     eapPeerConfig->password_len = cred->password.length;
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }
 
@@ -246,9 +259,13 @@ peerConfigFree(OM_uint32 *minor,
 
     krb5_free_unparsed_name(krbContext, (char *)eapPeerConfig->identity);
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }
 
+/*
+ * Mark an initiator context as ready for cryptographic operations
+ */
 static OM_uint32
 initReady(OM_uint32 *minor, gss_ctx_id_t ctx, OM_uint32 reqFlags)
 {
@@ -353,16 +370,19 @@ initBegin(OM_uint32 *minor,
         if (!gssEapInternalizeOid(mech, &ctx->mechanismUsed))
             major = duplicateOid(minor, mech, &ctx->mechanismUsed);
     } else {
-        *minor = GSSEAP_WRONG_MECH;
         major = GSS_S_BAD_MECH;
+        *minor = GSSEAP_WRONG_MECH;
     }
     if (GSS_ERROR(major))
         return major;
 
     /* If credentials were provided, check they're usable with this mech */
-    if (!gssEapCredAvailable(cred, ctx->mechanismUsed))
+    if (!gssEapCredAvailable(cred, ctx->mechanismUsed)) {
+        *minor = GSSEAP_CRED_MECH_MISMATCH;
         return GSS_S_BAD_MECH;
+    }
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }
 
@@ -395,6 +415,7 @@ eapGssSmInitIdentity(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_AUTHENTICATE;
 
+    *minor = 0;
     return GSS_S_CONTINUE_NEEDED;
 }
 
@@ -418,6 +439,8 @@ eapGssSmInitAuthenticate(OM_uint32 *minor,
     struct wpabuf *resp = NULL;
     int initialContextToken;
 
+    *minor = 0;
+
     initialContextToken = (inputToken == GSS_C_NO_BUFFER ||
                            inputToken->length == 0);
 
@@ -435,8 +458,8 @@ eapGssSmInitAuthenticate(OM_uint32 *minor,
                                                  ctx,
                                                  &eapConfig);
         if (ctx->initiatorCtx.eap == NULL) {
-            *minor = GSSEAP_PEER_INIT_FAILURE;
             major = GSS_S_FAILURE;
+            *minor = GSSEAP_PEER_SM_INIT_FAILURE;
             goto cleanup;
         }
 
@@ -464,14 +487,14 @@ eapGssSmInitAuthenticate(OM_uint32 *minor,
         major = GSS_S_CONTINUE_NEEDED;
         ctx->state = EAP_STATE_EXTENSIONS_REQ;
     } else if (ctx->flags & CTX_FLAG_EAP_FAIL) {
-        *minor = GSSEAP_PEER_AUTH_FAILURE;
         major = GSS_S_DEFECTIVE_CREDENTIAL;
+        *minor = GSSEAP_PEER_AUTH_FAILURE;
     } else if (code == 0 && initialContextToken) {
         resp = &emptyWpaBuffer;
         major = GSS_S_CONTINUE_NEEDED;
     } else {
-        *minor = GSSEAP_PEER_BAD_MESSAGE;
         major = GSS_S_DEFECTIVE_TOKEN;
+        *minor = GSSEAP_PEER_BAD_MESSAGE;
     }
 
 cleanup:
@@ -519,6 +542,7 @@ eapGssSmInitExtensionsReq(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_EXTENSIONS_RESP;
 
+    *minor = 0;
     return GSS_S_CONTINUE_NEEDED;
 }
 
@@ -542,6 +566,7 @@ eapGssSmInitExtensionsResp(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_ESTABLISHED;
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }
 
@@ -578,18 +603,18 @@ eapGssSmInitError(OM_uint32 *minor,
     unsigned char *p;
 
     if (inputToken->length < 8) {
-        *minor = GSSEAP_WRONG_SIZE;
+        *minor = GSSEAP_TOK_TRUNC;
         return GSS_S_DEFECTIVE_TOKEN;
     }
 
     p = (unsigned char *)inputToken->value;
 
     major = load_uint32_be(&p[0]);
-    *minor = load_uint32_be(&p[4]);
+    *minor = ERROR_TABLE_BASE_eapg + load_uint32_be(&p[4]);
 
     if (!GSS_ERROR(major)) {
-        *minor = GSSEAP_BAD_ERROR_TOKEN;
         major = GSS_S_FAILURE;
+        *minor = GSSEAP_BAD_ERROR_TOKEN;
     }
 
     return major;
@@ -694,8 +719,8 @@ gss_init_sec_context(OM_uint32 *minor,
 #endif
 
     if ((cred->flags & CRED_FLAG_INITIATE) == 0) {
-        *minor = GSSEAP_CRED_USAGE_MISMATCH;
         major = GSS_S_NO_CRED;
+        *minor = GSSEAP_CRED_USAGE_MISMATCH;
         goto cleanup;
     }
 
@@ -710,8 +735,8 @@ gss_init_sec_context(OM_uint32 *minor,
         if (tokType == TOK_TYPE_CONTEXT_ERR) {
             ctx->state = EAP_STATE_ERROR;
         } else if (tokType != sm->inputTokenType) {
-            *minor = GSSEAP_WRONG_TOK_ID;
             major = GSS_S_DEFECTIVE_TOKEN;
+            *minor = GSSEAP_WRONG_TOK_ID;
             goto cleanup;
         }
     } else {