MSCHAP Authentication Issue
I realize that this issue has been brought up many times in the past. However, I believe I have new information that I haven't seen reported before.. I'm having a problem with Windows XP supplicant authenticating to FR with PEAP/MSCHAPv2 where authentication fails "sometimes" depending upon various factors. The same device I'm using to test wireless authentication, never has an issue authenticating to my old dain-bramaged Cisco ACS servers. As a result, I decided to investigate what might be different about FreeRadius (perhaps Samba I thought, but didn't want to make assumptions). I don't profess to be an MS-CHAP expert, so what I'm about to say may be completely off-base.. After performing many tests (see below) and reviewing RFC2579 and the code in rlm_mschap.c, I'm hypothesizing that the problem is with how rlm_mschap calculates the challenge hash that is passed to ntlm_auth. Specifically, rlm_mschap uses the User-Name attribute as part of the calculation of the hash. What I'm finding is that, in some cases, the User-Name attribute doesn't match the case of the Name field in the MS-CHAP response (i.e., the userid is the same, it just differs in case). In the tests I've performed, when these userids don't match in case, I get a Logon Failure from ntlm_auth. I'd really like this to "just work" as is commonly said around these parts without additional gymnastics (such as changing all userids to lowercase). Does this seem like a plausible explanation for what's happening? If not, does anyone have any other ideas? I need to resolve this in order to retire two old and cranky (and fairly useless because they don't really do authorization) ACS servers! I'm going to try a change to rlm_mschap so it passes the Name field from the MS-CHAP response to the challenge_hash function (as opposed to the User-Name attribute) to see if that resolves the issue. I realize that ultimately it's Windows fault that it doesn't pass the userid with consistent case (i.e., Identity vs. MS-CHAP response); but, I don't want the ACS server to be seen as a better, more tolerant solution. So, it would be great to make FR more tolerant of this aberrant behaviour. Thanks in advance for any advice/help/suggestions you can provide.. Here's what I tested and what I observed that caused me to draw the above conclusion: Background: Windows XP SP3 laptop using std. Windows wireless supplicant EAP/PEAP/MS-CHAPv2 -> Cisco 1232AP -> FR 2.1.6 (with rlm_perl patch) running on FreeBSD 7.2. In all the tests below, the same SSID, wireless network configuration on the laptop, AP, userid and password were used (the domain and user listed below are contrived, but are representative of the case I saw in the debug output). Laptop Logon Method Wireless Credentials Passed Man/Auto MS-CHAP Response Packet Name field User-Name Request Attribute ntlm_auth Authentication Result Domain logon (via Ethernet) with all lowercase userid entered on gina Manually entered all lowercase userid when supplicant prompted MYDOMAIN\myuser MYDOMAIN\myuser SUCCESS Domain logon (via Ethernet) with all lowercase userid entered on gina Supplicant configured to auto. pass Windows credentials MYDOMAIN\MyuseR MYDOMAIN\myuser Logon failure (0xc000006d) Locally cached credentials (on laptop) with all lowercase userid entered on gina Manually entered all uppercase userid when supplicant prompted MYUSER MYUSER SUCCESS Locally cached credentials (on laptop) with all lowercase userid entered on gina Manually entered all lowercase userid when supplicant prompted myuser myuser SUCCESS Locally cached credentials (on laptop) with all lowercase userid entered on gina Supplicant configured to auto. pass Windows credentials MYDOMAIN\MyuseR MYDOMAIN\MyuseR SUCCESS
Garber, Neal wrote:
I don’t profess to be an MS-CHAP expert, so what I’m about to say may be completely off-base.. After performing many tests (see below) and reviewing RFC2579 and the code in rlm_mschap.c, I’m hypothesizing that the problem is with how rlm_mschap calculates the challenge hash that is passed to ntlm_auth. Specifically, rlm_mschap uses the User-Name attribute as part of the calculation of the hash. What I’m finding is that, in some cases, the User-Name attribute doesn’t match the case of the Name field in the MS-CHAP response (i.e., the userid is the same, it just differs in case).
That seems to be a good explanation for it.
Does this seem like a plausible explanation for what’s happening?
Yes.
If not, does anyone have any other ideas? I need to resolve this in order to retire two old and cranky (and fairly useless because they don’t really do authorization) ACS servers!
Well... that's a good reason to make sure we do it right. Any day where we can replace another RADIUS server with FreeRADIUS is a good day.
I’m going to try a change to rlm_mschap so it passes the Name field from the MS-CHAP response to the challenge_hash function (as opposed to the User-Name attribute) to see if that resolves the issue.
I suspect that it will. The mschap module should also pass the Name field when calling ntlm_auth, too. And maybe print a warning if the fields are different.
I realize that ultimately it’s Windows fault that it doesn’t pass the userid with consistent case (i.e., Identity vs. MS-CHAP response); but, I don’t want the ACS server to be seen as a better, more tolerant solution. So, it would be great to make FR more tolerant of this aberrant behaviour.
Hmm... Microsoft is aberrant. I agree. :) And it gets a lot worse. What do you do when the password is internationalized? Even the Microsoft people I talk to say "good luck". Alan DeKok.
Well... that's a good reason to make sure we do it right. Any day where we can replace another RADIUS server with FreeRADIUS is a good day.
My feelings exactly :)
I suspect that it will. The mschap module should also pass the Name field when calling ntlm_auth, too. And maybe print a warning if the fields are different.
I constructed a test program by extracting challenge_hash from rlm_mschap.c (and all supporting functions). I then extracted the peer challenge, authenticator challenge and NT-Response from the debug output of a failed request (User-Name was all lowercase, Name field was mixed case). I called challenge_hash with the all lowercase userid (to ensure it generated the same challenge as the failed request) - the challenge was identical. I then generated another challenge with the userid from the Name field in the response. Then, I executed ntlm_auth manually with the original challenge and the new challenge. The original failed (as I expected) and, low and behold, the new challenge (created using the Name field's userid) succeeded! I will now proceed to create a patch. I was planning to do a strncasecmp to ensure the only difference between the userid part of User-Name and the userid part of the Name field is case. If there are non-case differences, do you think a RLM_REJECT is in order or do you think it should just warn and use whatever is present (I can't think of a normal case where this would occur, but if you think this is better, then I would definitely use the Name field for the username parameter too)? I was thinking of rejecting the request, in this case, so this couldn't be used to bypass authorization. Interestingly, I copied the challenge and response from a successful and failed attempt and manually called ntlm_auth varying the case of the --username parameter and it didn't affect the results. In other words, --username=MYUSER or --username=myuser or --username=MyuseR all behave the same if the --challenge and --nt-response are correct).
I will now proceed to create a patch.
The MS-CHAP2-Response attribute created by rlm_eap_mschapv2 does not include the Name field from the MS-CHAP response packet (as I suspected). I thought the cleanest way to pass the Name field was to create another attribute in rlm_eap_mschapv2 before it calls rlm_mschap (I chose NTLM-User-Name as it's in the dictionary and I couldn't find it used anywhere). I have coded/compiled the changes (radius.h changed to include PW_NTLM_USER_NAME; rlm_eap_mschapv2.c changed to create NTLM-User-Name request attribute before calling rlm_mschap.c; rlm_mschap.c changed to use NTLM-User-Name to construct MS-CHAPv1 challenge if it exists and it is same as User-Name (case-insensitive compare considering with_ntdomain_hack too). If no NTLM-User-Name found then use User-Name. If the attributes are different, then log error and reject. I will try to get back to work this weekend to do testing. My plan is to get this working over the weekend and submit the patches by Monday. Does this sound like a reasonable solution? If not, feel free to suggest a different approach and I will make changes before submitting the patch files. BTW, if I should be sending these type of messages to the devel list, please let me know.
participants (3)
-
Alan Buxey -
Alan DeKok -
Garber, Neal