Strange behaviour combining windows, single-sign-on and peap inner-tunnel

Herwin Weststrate herwin at
Thu Nov 3 09:46:51 CET 2016

Recently we've seen an extreme corner case with Freeradius, and I'm a
bit puzzled on what the best way would be to fix this.

The scenario uses Windows clients on Wifi with single-sign-on, PEAP,
Freeradius as the Radius server where the inner-tunnel is used, and an
Active Directory as backend (this could be either NPS/Radius or
Winbind/NTLM authentication, both show this behaviour). The problem does
not occur when acting as a real Radius proxy and let the NPS handle the
authentication completely.

The problem arises when the user is in the AD backend with a certain
casing (e.g. "john_doe") but is logging in with a different casing
("John_Doe"). The first authentication succeeds and John Doe's laptop is
connected to the wifi. Then, the session expires and the client tries to
reauthenticate. Both the inner and outer Radius packets still show
"John_Doe" as User-Name attribute, but the authentication fails. I tried
recalculating the MS-CHAP2-Response value, and it looks like this has
been calculated using the "john_doe" value as username. I'm not exactly
sure if it normalizes the username to lowercase here, or if it uses the
value as given in the AD backend (in this testcase, both were
lowercased, but it sounds more logical to me that the user-name with
casing was found via the AD domain).

First thing I tried was switching to using the ntlmauth executable
instead of a Radius tunnel or Winbind-libs (it was on a system without a
build environment, so making changes to the source was not really an
option here) and build a wrapper around it: Try an authentication, and
if that fails: lowercase the username, recalculate the value that is
given as the --challenge-parameter with the new username and try a new
authentication. If that fails too, the password is probably incorrect. I
switched to ntlm_auth because I didn't exactly see an option to try
another authentication with Radius.

The authentication succeeded, but the MS-CHAP2-Response attribute in the
reply was still based on the username with the incorrect casing, so that
failed too. After adding a script in the post-auth to calculate the
correct value (which didn't have access to the username used for the
authentication, so it just had to blindly try an authentication again,
if that failed: lowercase  the username and use that), recalculate and
everything worked. Well, it worked as far as the proof of concept was
concerned, of course this is not exactly a setup you would use in a real

The only sensible setup I could think of was to include this within the
winbind library user (which would be rlm_mschap here because it's a 3.0
setup): add a boolean config option to retry authentication with a
normalized username and use that for further hash calculations. This
allows the option to save the user-name used for the authentication hash
to be saved in the "session", so we could use it again without have to
attempt more authentications.
Normalizing to lowercase is probably a bad idea, the `wbinfo` tool
allows us to search for the user, we could probably use that too in the
winbind libs (and it gives an extra reason why putting this in the
winbind code would be a good idea)

Herwin Weststrate

More information about the Freeradius-Users mailing list