]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
eap: Deal with the case where the first response message is not an Identity-Response...
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 14 Jun 2023 18:05:37 +0000 (14:05 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 14 Jun 2023 18:05:42 +0000 (14:05 -0400)
src/lib/unlang/module.h
src/modules/rlm_eap/rlm_eap.c

index a4c6f14d22f1d70a34c16a7439f45c92f8301ae7..929f3725556da79bb51bf820a62180981c06a9d4 100644 (file)
@@ -93,7 +93,7 @@ int           unlang_module_fd_delete(request_t *request, void const *rctx, int fd);
 
 int            unlang_module_push(rlm_rcode_t *p_result, request_t *request,
                                   module_instance_t *module_instance, module_method_t method, bool top_frame)
-                                  CC_HINT(warn_unused_result);
+                                  CC_HINT(warn_unused_result) CC_HINT(nonnull(2,3,4));
 
 int            unlang_module_set_resume(request_t *request, module_method_t resume);
 
index 1caf7005d921d8de21ad595354cb113b78e7ce71..1f45c131119fc84adb3395d1993ce7acdd36a202 100644 (file)
@@ -699,24 +699,16 @@ static unlang_action_t eap_method_select(rlm_rcode_t *p_result, module_ctx_t con
                                }
                        }
                }
-
+       do_init:
                /*
                 *      Ensure it's valid.
                 */
                if ((next < FR_EAP_METHOD_MD5) || (next >= FR_EAP_METHOD_MAX) || (!inst->methods[next].submodule)) {
-                       REDEBUG2("Tried to start unsupported EAP type %s (%d)",
+                       REDEBUG2("Peer tried to start unsupported EAP type %s (%d)",
                                 eap_type2name(next), next);
                        goto is_invalid;
                }
 
-       do_init:
-               /*
-                *      If any of these fail, we messed badly somewhere
-                */
-               fr_assert(next >= FR_EAP_METHOD_MD5);
-               fr_assert(next < FR_EAP_METHOD_MAX);
-               fr_assert(inst->methods[next].submodule);
-
                eap_session->process = inst->methods[next].submodule->session_init;
                eap_session->type = next;
                break;
@@ -749,9 +741,32 @@ static unlang_action_t eap_method_select(rlm_rcode_t *p_result, module_ctx_t con
         */
        default:
                if (!inst->methods[type->num].submodule) {
-                       REDEBUG2("Client asked for unsupported EAP type %s (%d)", eap_type2name(type->num), type->num);
+                       REDEBUG2("Peer asked for unsupported EAP type %s (%d)", eap_type2name(type->num), type->num);
                        goto is_invalid;
                }
+               /*
+                *      Perr started the EAP method without
+                *      sending an Identity-Response.
+                *
+                *      There's nothing that says it *HAS* to send an
+                *      identity response before starting a method,
+                *      so just jump to the initialisation function
+                *      of the method and continue.
+                */
+               if (eap_session->rounds == 0) {
+                       RDEBUG2("Peer started EAP type %s (%d) without sending an Identity", eap_type2name(type->num), type->num);
+                       vp = fr_pair_find_by_da(&eap_session->request->control_pairs, NULL, attr_eap_type);
+                       if (vp) {
+                               RDEBUG2("Using method from &control.EAP-Type");
+                               next = vp->vp_uint32;
+                       }
+                       goto do_init;
+               }
+
+               /*
+                *      FIXME - We should only update the type
+                *      on completion of the final round.
+                */
                eap_session->type = type->num;
                break;
        }