Does eapol_test lie about the data it exchanges with FreeRADIUS?

Alan DeKok aland at deployingradius.com
Thu Apr 20 15:59:24 UTC 2023


On Apr 20, 2023, at 11:28 AM, Joe Garcia <joe27256 at gmail.com> wrote:
> 
> I've been debugging an embedded RADIUS client, specifically one that does PEAP
> auth, using eapol_test, or at least trying to, however I can't see how it
> could work using the messages it claims to be exchanging with FreeRADIUS.  In
> particular eapol_test claims it replies to the initial identity request with
> an EAP, not PEAP, message:

  PEAP is encapsulated inside of EAP.  There's a 4 byte EAP header, followed by one byte of the PEAP code, followed by PEAP data.

> EAP-PEAP: Encrypting Phase 2 data - hexdump(len=12): 02 a5 00 0c 01 74
> 65 73 74 33 32 31

  That's a full EAP packet with 4 byte EAP header, Identity (code 01), and then identity "test321"

> when it should be just PEAP, 01 74 65 73 74 33 32 31.

  PEAP has this "wonderful" property where it omits the 4 byte EAP header.  I don't know why, but its annoying.

  The data here is *not* PEAP.  It's an EAP identity packet (code 01), with identity "test321".  But the 4 byte EAP header has been dropped.

  I haven't looked at that part of wpa_supplicant in detail, but I'd bet it also strips out that 4 byte header before the data gets put into the PEAP tunnel.

>  Looking at the
> FreeRADIUS code that handles this (3.2.x, the current version shipping with
> various Linux distros), src/modules/rlm_eap/types/
> rlm_eap_peap:eappeap_process() calls eapmessage_verify() which, for an EAP
> Response (type = 2) only allows an EAP-TLV and nothing else, in particular not
> an EAP Identity message as eapol_test claims it's sending.  I've verified this
> by sending the message that eapol_test claims it's sending and getting:

  FreeRADIUS fakes out an EAP header for the inner tunnel PEAP data, and then just processes it as EAP.

> eap_peap: Received unexpected EAP-Response, rejecting the session.
> eap_peap: ERROR: Tunneled data is invalid
> 
> which is exactly what you'd expect from the code in eapmessage_verify().

  Because rlm_eap_peap expects that the inner tunnel data doesn't have an EAP header.  So it adds one.

  And the rest of the EAP code assumes that the EAP packet is well formed.  So if you mangle the inner data to add a header, then it now has two headers, and it's not correct.

> So does eapol_test invisibly convert messages to and from EAP/PEAP format when
> communicating with FreeRADIUS and report the EAP form while using the PEAP
> form?  Further evidence in support of this is what it reports on read of a
> PEAP Identity Request:
> 
> EAP-PEAP: Decrypted Phase 2 EAP - hexdump(len=1): 01
> EAP-PEAP: received Phase 2: code=1 identifier=165 length=5

  Yes.

> The first line reports it's read a PEAP message

  No, the first line reports that the *outer* EAP method is PEAP.  And then the *inner* data is an EAP identity, with the 4 byte EAP header stripped.

> (which is indeed what's being
> sent) and on the second line it's magically converted itself into an EAP
> message, which isn't actually sent.

  Exactly.

> Does this mean that eapol_test is an unreliable source of information when it
> comes to debugging auth issues?

  I suspect that eapol_test prints out the full EAP packet when sending data inside of PEAP.  And then skips the 4 byte EAP header.

  It's a little odd, but it only affects the debug output.  If you look at the FreeRADIUS debug output, I suspect you would see:

eapol_test says  "Encrypting Phase 2 data - hexdump(len=12): 02 a5 00 0c 01 74 65 73 74 33 32 31"

and then the FreeRADIUS inner-tunnel says it receives "01 74 65 73 74 33 32 31"

  It's fine.  It's confusing, but that's PEAP.  :(

  Alan DeKok.




More information about the Freeradius-Users mailing list