Cannot lookup EAP user on reauthentication (PEAP/TTLS)

James Prestwood prestwoj at
Thu May 26 15:21:32 PDT 2022


For tunneled methods like PEAP/TTLS, on a reauthentication request,
hostapd uses the phase2 identity stored in the sm but hard codes the
phase to 0. This happens in eap_sm_Policy_getDecision().

The reason for this is PEAP/TTLS overwrite sm->identity with the phase2
identity and the phase1 identity is lost forever. The code in
eap_sm_Policy_getDecision() assumes sm->identity is phase one and hard
codes '0' to the phase parameter, causing the lookup to fail.

I'm not sure how you want this fixed, either save the phase1 identity,
or add some flag which tunneled methods can set to signify phase2 has
completed and set the 'phase2' argument to eap_user_get() dependent on
this flag? Maybe the eap_sm already has some value which can hint at
the correct phase value?

I have a patch below which hopefully lines out the issue better. I
don't expect this to get merged, its just (hopefully) showing the
problem better than I can explain it.

diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c
index 0b7a5b98c..7c2d33b51 100644
--- a/src/eap_server/eap_server.c
+++ b/src/eap_server/eap_server.c
@@ -1744,6 +1744,13 @@ static int eap_sm_Policy_getDecision(struct
eap_sm *sm)
        if ((sm->user == NULL || sm->update_user) && sm->identity &&
            !sm->start_reauth) {
+               /*
+                * sm->identity may contain a phase2 identity since
+                * overwrite the phase1 identity. In this case the
lookup should
+                * actually be for phase2 (1) rather than phase1 (0).
+                */
+               int phase = ((sm->currentMethod == EAP_TYPE_PEAP ||
+                               sm->currentMethod == EAP_TYPE_TTLS)) ?
1 : 0;
                 * Allow Identity method to be started once to allow
                 * selection hint to be sent from the authentication
@@ -1755,7 +1762,8 @@ static int eap_sm_Policy_getDecision(struct
eap_sm *sm)
                    sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
                    sm->user->methods[0].method == EAP_TYPE_IDENTITY)
                        id_req = 1;
-               if (eap_user_get(sm, sm->identity, sm->identity_len, 0)
!= 0) {
+               if (eap_user_get(sm, sm->identity, sm->identity_len,
phase) != 0) {
                        wpa_printf(MSG_DEBUG, "EAP: getDecision: user
not "
                                   "found from database -> FAILURE");
                        return DECISION_FAILURE;

More information about the Hostap mailing list