I have an issue with inner versus outer identities. I can demonstrate this with the stock freeradius 3.0.12 config; just uncomment the "bob" and "steve" entries. I have also set "use_tunneled_reply = yes" in raddb/mods-available/eap (in both places) Now I create a config for eapol_test (from wpa_supplicant package) like this: ---- # # eapol_test -c peap-mschapv2.conf -s testing123 # network={ ssid="Cityfibre Admin" key_mgmt=WPA-EAP eap=PEAP identity="bob" anonymous_identity="steve" password="hello" phase2="autheap=MSCHAPV2" # # Uncomment the following to perform server certificate validation. # ca_cert="/etc/raddb/certs/ca.der" } ---- Note how I've chosen "steve" as the anonymous identity. What happens is that is in the second Access-Challenge response, steve's attributes are returned: (0) Received Access-Request Id 0 from 127.0.0.1:49950 to 127.0.0.1:1812 length 118 (0) User-Name = "steve" (0) NAS-IP-Address = 127.0.0.1 (0) Calling-Station-Id = "02-00-00-00-00-01" (0) Framed-MTU = 1400 (0) NAS-Port-Type = Wireless-802.11 (0) Connect-Info = "CONNECT 11Mbps 802.11b" (0) EAP-Message = 0x0200000a017374657665 (0) Message-Authenticator = 0xc31453b2556c5c5767691b67d9d1b1b8 (0) # Executing section authorize from file /etc/raddb/sites-enabled/default (0) authorize { (0) policy filter_username { (0) if (&User-Name) { (0) if (&User-Name) -> TRUE (0) if (&User-Name) { (0) if (&User-Name =~ / /) { (0) if (&User-Name =~ / /) -> FALSE (0) if (&User-Name =~ /@[^@]*@/ ) { (0) if (&User-Name =~ /@[^@]*@/ ) -> FALSE (0) if (&User-Name =~ /\.\./ ) { (0) if (&User-Name =~ /\.\./ ) -> FALSE (0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) { (0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) -> FALSE (0) if (&User-Name =~ /\.$/) { (0) if (&User-Name =~ /\.$/) -> FALSE (0) if (&User-Name =~ /@\./) { (0) if (&User-Name =~ /@\./) -> FALSE (0) } # if (&User-Name) = notfound (0) } # policy filter_username = notfound (0) [preprocess] = ok (0) [chap] = noop (0) [mschap] = noop (0) [digest] = noop (0) suffix: Checking for suffix after "@" (0) suffix: No '@' in User-Name = "steve", looking up realm NULL (0) suffix: No such realm "NULL" (0) [suffix] = noop (0) eap: Peer sent EAP Response (code 2) ID 0 length 10 (0) eap: EAP-Identity reply, returning 'ok' so we can short-circuit the rest of authorize (0) [eap] = ok (0) } # authorize = ok (0) Found Auth-Type = eap (0) # Executing group from file /etc/raddb/sites-enabled/default (0) authenticate { (0) eap: Peer sent packet with method EAP Identity (1) (0) eap: Calling submodule eap_md5 to process data (0) eap_md5: Issuing MD5 Challenge (0) eap: Sending EAP Request (code 1) ID 1 length 22 (0) eap: EAP session adding &reply:State = 0x74107434741170f2 (0) [eap] = handled (0) } # authenticate = handled (0) Using Post-Auth-Type Challenge (0) Post-Auth-Type sub-section not found. Ignoring. (0) # Executing group from file /etc/raddb/sites-enabled/default (0) Sent Access-Challenge Id 0 from 127.0.0.1:1812 to 127.0.0.1:49950 length 0 (0) EAP-Message = 0x0101001604103936abba88e393e0bfbb63a6f9636887 (0) Message-Authenticator = 0x00000000000000000000000000000000 (0) State = 0x74107434741170f2f863cec79136ac13 (0) Finished request Waking up in 4.9 seconds. (1) Received Access-Request Id 1 from 127.0.0.1:49950 to 127.0.0.1:1812 length 132 (1) User-Name = "steve" (1) NAS-IP-Address = 127.0.0.1 (1) Calling-Station-Id = "02-00-00-00-00-01" (1) Framed-MTU = 1400 (1) NAS-Port-Type = Wireless-802.11 (1) Connect-Info = "CONNECT 11Mbps 802.11b" (1) EAP-Message = 0x020100060319 (1) State = 0x74107434741170f2f863cec79136ac13 (1) Message-Authenticator = 0xbf4a7b7d48c99b11a68c98a2af96b7b6 (1) session-state: No cached attributes (1) # Executing section authorize from file /etc/raddb/sites-enabled/default (1) authorize { (1) policy filter_username { (1) if (&User-Name) { (1) if (&User-Name) -> TRUE (1) if (&User-Name) { (1) if (&User-Name =~ / /) { (1) if (&User-Name =~ / /) -> FALSE (1) if (&User-Name =~ /@[^@]*@/ ) { (1) if (&User-Name =~ /@[^@]*@/ ) -> FALSE (1) if (&User-Name =~ /\.\./ ) { (1) if (&User-Name =~ /\.\./ ) -> FALSE (1) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) { (1) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) -> FALSE (1) if (&User-Name =~ /\.$/) { (1) if (&User-Name =~ /\.$/) -> FALSE (1) if (&User-Name =~ /@\./) { (1) if (&User-Name =~ /@\./) -> FALSE (1) } # if (&User-Name) = notfound (1) } # policy filter_username = notfound (1) [preprocess] = ok (1) [chap] = noop (1) [mschap] = noop (1) [digest] = noop (1) suffix: Checking for suffix after "@" (1) suffix: No '@' in User-Name = "steve", looking up realm NULL (1) suffix: No such realm "NULL" (1) [suffix] = noop (1) eap: Peer sent EAP Response (code 2) ID 1 length 6 (1) eap: No EAP Start, assuming it's an on-going EAP conversation (1) [eap] = updated (1) files: users: Matched entry steve at line 73 (1) [files] = ok (1) [expiration] = noop (1) [logintime] = noop (1) pap: WARNING: Auth-Type already set. Not setting to PAP (1) [pap] = noop (1) } # authorize = updated (1) Found Auth-Type = eap (1) # Executing group from file /etc/raddb/sites-enabled/default (1) authenticate { (1) eap: Expiring EAP session with state 0x74107434741170f2 (1) eap: Finished EAP session with state 0x74107434741170f2 (1) eap: Previous EAP request found for state 0x74107434741170f2, released from the list (1) eap: Peer sent packet with method EAP NAK (3) (1) eap: Found mutually acceptable type PEAP (25) (1) eap: Calling submodule eap_peap to process data (1) eap_peap: Initiating new EAP-TLS session (1) eap_peap: Flushing SSL sessions (of #0) (1) eap_peap: [eaptls start] = request (1) eap: Sending EAP Request (code 1) ID 2 length 6 (1) eap: EAP session adding &reply:State = 0x7410743475126df2 (1) [eap] = handled (1) } # authenticate = handled (1) Using Post-Auth-Type Challenge (1) Post-Auth-Type sub-section not found. Ignoring. (1) # Executing group from file /etc/raddb/sites-enabled/default (1) Sent Access-Challenge Id 1 from 127.0.0.1:1812 to 127.0.0.1:49950 length 0 *(1) Service-Type = Framed-User** **(1) Framed-Protocol = PPP** **(1) Framed-IP-Address = 172.16.3.33** **(1) Framed-IP-Netmask = 255.255.255.0** **(1) Framed-Routing = Broadcast-Listen** **(1) Framed-Filter-Id = "std.ppp"** **(1) Framed-MTU = 1500** **(1) Framed-Compression = Van-Jacobson-TCP-IP** *(1) EAP-Message = 0x010200061920 (1) Message-Authenticator = 0x00000000000000000000000000000000 (1) State = 0x7410743475126df2f863cec79136ac13 (1) Finished request It's clearly wrong to return steve's authorization attributes, since we've not authenticated at all (and certainly not as steve) - although since this only an Access-Challenge, hopefully the NAS will ignore them. The EAP exchange does complete successfully. My other concern is that it does an unnecessary database lookup for "steve" - actually the live config which started this investigation is an LDAP one, which is how I noticed this. Now, the default site has in its authorize section: eap { ok = return } But at this step we're getting "updated". So it looks like it would be reasonable to change this to: eap { ok = return updated = return } ... and this does seem to work. But I wonder why it's done this way in the default config. Is this a mistake, or this there some subtle point I am missing? Under what circumstances does rlm_eap return "updated" instead of "ok"? I want to be sure that there's no security impact by dropping out of the authorize section at this point, for example if someone uses a non-tunneled version of EAP like EAP-TLS or EAP-PWD. Thanks, Brian.