update for libradsec API cleanups
[mech_eap.git] / accept_sec_context.c
index 2fe3abf..6aef48e 100644 (file)
@@ -43,7 +43,7 @@ eapGssSmAcceptGssReauth(OM_uint32 *minor,
 #endif
 
 /*
- * Mark a context as ready for cryptographic operations
+ * Mark an acceptor context as ready for cryptographic operations
  */
 static OM_uint32
 acceptReadyEap(OM_uint32 *minor, gss_ctx_id_t ctx, gss_cred_id_t cred)
@@ -104,9 +104,14 @@ acceptReadyEap(OM_uint32 *minor, gss_ctx_id_t ctx, gss_cred_id_t cred)
 
     ctx->initiatorName->attrCtx = gssEapCreateAttrContext(cred, ctx);
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }
 
+/*
+ * Emit a identity EAP request to force the initiator (peer) to identify
+ * itself.
+ */
 static OM_uint32
 eapGssSmAcceptIdentity(OM_uint32 *minor,
                        gss_ctx_id_t ctx,
@@ -122,8 +127,10 @@ eapGssSmAcceptIdentity(OM_uint32 *minor,
     } pkt;
     gss_buffer_desc pktBuffer;
 
-    if (inputToken != GSS_C_NO_BUFFER && inputToken->length != 0)
+    if (inputToken != GSS_C_NO_BUFFER && inputToken->length != 0) {
+        *minor = GSSEAP_WRONG_SIZE;
         return GSS_S_DEFECTIVE_TOKEN;
+    }
 
     assert(ctx->acceptorName == GSS_C_NO_NAME);
 
@@ -147,9 +154,13 @@ eapGssSmAcceptIdentity(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_AUTHENTICATE;
 
+    *minor = 0;
     return GSS_S_CONTINUE_NEEDED;
 }
 
+/*
+ * Pass the asserted acceptor identity to the authentication server.
+ */
 static OM_uint32
 setAcceptorIdentity(OM_uint32 *minor,
                     gss_ctx_id_t ctx,
@@ -159,21 +170,25 @@ setAcceptorIdentity(OM_uint32 *minor,
     gss_buffer_desc nameBuf;
     krb5_context krbContext = NULL;
     krb5_principal krbPrinc;
-    struct rs_handle *rh = ctx->acceptorCtx.radHandle;
+    struct rs_context *rc = ctx->acceptorCtx.radContext;
 
-    assert(rh != NULL);
+    assert(rc != NULL);
 
-    /* Awaits further specification */
-    if (ctx->acceptorName == GSS_C_NO_NAME)
+    if (ctx->acceptorName == GSS_C_NO_NAME) {
+        *minor = 0;
         return GSS_S_COMPLETE;
+    }
+
+    if ((ctx->acceptorName->flags & NAME_FLAG_SERVICE) == 0) {
+        *minor = GSSEAP_BAD_SERVICE_NAME;
+        return GSS_S_BAD_NAME;
+    }
 
     GSSEAP_KRB_INIT(&krbContext);
 
     krbPrinc = ctx->acceptorName->krbPrincipal;
     assert(krbPrinc != NULL);
-
-    if (krb5_princ_size(krbContext, krbPrinc) < 2)
-        return GSS_S_BAD_NAME;
+    assert(krb5_princ_size(krbContext, krbPrinc) >= 2);
 
     /* Acceptor-Service-Name */
     krbDataToGssBuffer(krb5_princ_component(krbContext, krbPrinc, 0), &nameBuf);
@@ -234,9 +249,13 @@ setAcceptorIdentity(OM_uint32 *minor,
             return major;
     }
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }
 
+/*
+ * Allocate a RadSec handle
+ */
 static OM_uint32
 createRadiusHandle(OM_uint32 *minor,
                    gss_cred_id_t cred,
@@ -248,11 +267,11 @@ createRadiusHandle(OM_uint32 *minor,
     struct rs_alloc_scheme ralloc;
     struct rs_error *err;
 
-    assert(actx->radHandle == NULL);
+    assert(actx->radContext == NULL);
     assert(actx->radConn == NULL);
 
-    if (rs_context_create(&actx->radHandle, RS_DICT_FILE) != 0) {
-        *minor = GSSEAP_RADSEC_INIT_FAILURE;
+    if (rs_context_create(&actx->radContext, RS_DICT_FILE) != 0) {
+        *minor = GSSEAP_RADSEC_CONTEXT_FAILURE;
         return GSS_S_FAILURE;
     }
 
@@ -268,14 +287,14 @@ createRadiusHandle(OM_uint32 *minor,
     ralloc.free    = GSSEAP_FREE;
     ralloc.realloc = GSSEAP_REALLOC;
 
-    rs_context_set_alloc_scheme(actx->radHandle, &ralloc);
+    rs_context_set_alloc_scheme(actx->radContext, &ralloc);
 
-    if (rs_context_read_config(actx->radHandle, configFile) != 0) {
-        err = rs_err_ctx_pop(actx->radHandle);
+    if (rs_context_read_config(actx->radContext, configFile) != 0) {
+        err = rs_err_ctx_pop(actx->radContext);
         goto fail;
     }
 
-    if (rs_conn_create(actx->radHandle, &actx->radConn, configStanza) != 0) {
+    if (rs_conn_create(actx->radContext, &actx->radConn, configStanza) != 0) {
         err = rs_err_conn_pop(actx->radConn);
         goto fail;
     }
@@ -297,6 +316,9 @@ fail:
     return gssEapRadiusMapError(minor, err);
 }
 
+/*
+ * Process a EAP response from the initiator.
+ */
 static OM_uint32
 eapGssSmAcceptAuthenticate(OM_uint32 *minor,
                            gss_ctx_id_t ctx,
@@ -306,14 +328,13 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor,
                            gss_buffer_t outputToken)
 {
     OM_uint32 major, tmpMinor;
-    struct rs_handle *rh;
     struct rs_connection *rconn;
     struct rs_request *request = NULL;
     struct rs_packet *req = NULL, *resp = NULL;
     struct radius_packet *frreq, *frresp;
     int sendAcceptorIdentity = 0;
 
-    if (ctx->acceptorCtx.radHandle == NULL) {
+    if (ctx->acceptorCtx.radContext == NULL) {
         /* May be NULL from an imported partial context */
         major = createRadiusHandle(minor, cred, ctx);
         if (GSS_ERROR(major))
@@ -322,7 +343,6 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor,
         sendAcceptorIdentity = 1;
     }
 
-    rh = ctx->acceptorCtx.radHandle;
     rconn = ctx->acceptorCtx.radConn;
 
     if (rs_packet_create_acc_request(rconn, &req, NULL, NULL) != 0) {
@@ -389,7 +409,7 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor,
     if (frresp->code == PW_ACCESS_CHALLENGE) {
         major = gssEapRadiusGetAvp(minor, frresp->vps, PW_STATE, 0,
                                    &ctx->acceptorCtx.state, TRUE);
-        if (major != GSS_S_UNAVAILABLE && GSS_ERROR(major))
+        if (GSS_ERROR(major) && *minor != GSSEAP_NO_SUCH_ATTR)
             goto cleanup;
     } else {
         ctx->acceptorCtx.vps = frresp->vps;
@@ -405,6 +425,7 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor,
         ctx->state = EAP_STATE_EXTENSIONS_REQ;
     }
 
+    *minor = 0;
     major = GSS_S_CONTINUE_NEEDED;
 
 cleanup:
@@ -432,6 +453,7 @@ eapGssSmAcceptExtensionsReq(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_EXTENSIONS_RESP;
 
+    *minor = 0;
     return GSS_S_CONTINUE_NEEDED;
 }
 
@@ -451,6 +473,7 @@ eapGssSmAcceptExtensionsResp(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_ESTABLISHED;
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }
 
@@ -486,8 +509,10 @@ makeErrorToken(OM_uint32 *minor,
     case GSSEAP_WRONG_SIZE:
     case GSSEAP_WRONG_MECH:
     case GSSEAP_BAD_TOK_HEADER:
+    case GSSEAP_TOK_TRUNC:
     case GSSEAP_BAD_DIRECTION:
     case GSSEAP_WRONG_TOK_ID:
+    case GSSEAP_REFLECT:
     case GSSEAP_CRIT_EXT_UNAVAILABLE:
     case GSSEAP_MISSING_REQUIRED_EXT:
     case GSSEAP_KEY_UNAVAILABLE:
@@ -497,10 +522,11 @@ makeErrorToken(OM_uint32 *minor,
     case GSSEAP_MISSING_EAP_REQUEST:
         break;
     default:
-        /* Don't return system error codes */
         if (IS_RADIUS_ERROR(minorStatus))
+            /* Squash RADIUS error codes */
             minorStatus = GSSEAP_GENERIC_RADIUS_ERROR;
         else
+            /* Don't return system error codes */
             return GSS_S_COMPLETE;
     }
 
@@ -564,6 +590,7 @@ gss_accept_sec_context(OM_uint32 *minor,
     output_token->value = NULL;
 
     if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
+        *minor = GSSEAP_TOK_TRUNC;
         return GSS_S_DEFECTIVE_TOKEN;
     }
 
@@ -597,7 +624,7 @@ gss_accept_sec_context(OM_uint32 *minor,
         goto cleanup;
 
     if (!gssEapCredAvailable(cred, ctx->mechanismUsed)) {
-        *minor = GSSEAP_WRONG_MECH;
+        *minor = GSSEAP_CRED_MECH_MISMATCH;
         major = GSS_S_BAD_MECH;
         goto cleanup;
     }
@@ -629,7 +656,7 @@ gss_accept_sec_context(OM_uint32 *minor,
                                    input_chan_bindings,
                                    &innerOutputToken);
         if (GSS_ERROR(major)) {
-            /* Generate an error token */
+            /* Possibly generate an error token */
             tmpMajor = makeErrorToken(&tmpMinor, major, *minor, &innerOutputToken);
             if (GSS_ERROR(tmpMajor)) {
                 major = tmpMajor;
@@ -656,8 +683,11 @@ gss_accept_sec_context(OM_uint32 *minor,
             if (GSS_ERROR(major))
                 goto cleanup;
         }
-        if (time_rec != NULL)
-            gssEapContextTime(&tmpMinor, ctx, time_rec);
+        if (time_rec != NULL) {
+            major = gssEapContextTime(&tmpMinor, ctx, time_rec);
+            if (GSS_ERROR(major))
+                goto cleanup;
+        }
     }
 
     assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED);
@@ -713,6 +743,7 @@ acceptReadyKrb(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_ESTABLISHED;
 
+    *minor = 0;
     return GSS_S_COMPLETE;
 }