MS-CHAP-V2 with no retry

James J J Hooper jjj.hooper at bristol.ac.uk
Thu Apr 7 14:33:33 CEST 2011



--On Wednesday, April 06, 2011 15:42:11 -0500 John.Hayward at wheaton.edu 
wrote:

>> List info/subscribe/unsubscribe? See
>> http://www.freeradius.org/list/users.html
> I don't know if this should be sent to the developers list instead.
>
> === Background ===
> When there is a failure of the client to match the challenge of the
> server:
>
> According to rfc2759 a failure packet in section 6 a failure packet
> includes a message like:
> "E=eeeeeeeeee R=r C=cccccccccccccccccccccccccccccccc V=vvvvvvvvvv M=<msg>"
> where E is the error code, R 1/0 allow/disallow retry C an ascii version
> of the challenge V=3 and M= some text message.
>
> After this mschap failure message is sent by the server an acknowledgment
> which seems to be have a failure code should be returned from the client.
>
> At that point the server can close the eap connection with a failure.
>
> What the 2.1.10 code (and earlier) appears to do is after mschap is
> detected immediately close the eap connection with a failure.
>
> The effect for windows XP/7 machines connecting wirelessly using mschapv2
> is that they are presented with a dialog box and can enter new
> credentials.
>
> What happens with mac/iphones/androids/ubuntu is that they appear to be
> confused and time out and re-send (at various rates) authentication
> attempts without presenting a dialog box to the user.
>
> For some environments (such as using Novell NDS to authenticate) if
> configured modules/ldap edir_account_policy_check=yes then these repeated
> failures result in account lock outs.
>
> Scenario: Institution requires periodic change of password - user uses a
> web site to change password - user forgets to update their
> mac/iphone/android - user turns on their mac/iphone/android - shortly
> after user cannot access any resources (such as blackboard/portal etc)
> because their account is locked out.
>
> ====== proposed fix ====
> Modify freeradius to follow rfc2759.
>
> This requires patches to two source files:
> o src/modules/rlm_mschap/rlm_mschap.c to include a message which conforms
>    to rfc2759
> o src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c to use the
>    response created by rlm_mschap.c and send that back, also accept an
>    authentication failure acknowledgment before sending eap failure
> packet.
>
> Below are the diffs:

> ======
>
> ==== Comments ====
> o Results:
>    We have implemented this patch (along with the configuration change
>    edir_account_policy_check=no) and observe:
>    1) no more lockouts
>    2) Mac/Iphones users are now presented with a dialog box where they
>       can update their password.
> o Code:
>    a) I don't like the 100 character msg variable - there is probably a
>       better way to do this.
>    b) There is probably a function in free radius library to do the
> sprintf
>       which should be used.
>    c) samba locked accounts should probably have a similar message
>       generated if they are mschapv2.
>
> I would be happy if someone could look over these patches and incorporate
> the ideas into freeradius for future releases.


Hi John,
  I had trouble applying the patches to 2.1.x git -- maybe because they got 
mushed during the email process.

Adding the bits by hand seemed to work, and I can confirm the result is as 
you describe on an iPhone (that's all I had to hand to test).

Attached are the two 'git diff' that I ended up with.

-James


-- 
James J J Hooper
Network Specialist, University of Bristol
http://www.wireless.bristol.ac.uk 	 	http://www.jamesjj.net
-- 

-------------- next part --------------
index c512018..3f3fc46 100644
--- a/src/modules/rlm_mschap/rlm_mschap.c
+++ b/src/modules/rlm_mschap/rlm_mschap.c
@@ -1239,9 +1239,21 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                              response->vp_octets + 26, nthashhash,
                              do_ntlm_auth) < 0) {
                        RDEBUG2("FAILED: MS-CHAP2-Response is incorrect");
+
+                       /* JCH - changes to include challenge and message */
+                        char msg[100];
+                        strcpy(msg, "E=691 R=0 C=");
+                        int i, offset = strlen(msg);
+                        char *ptr = &msg[offset];
+                        for (i=0; i<16; i++, ptr+=2) {
+                           sprintf(ptr, "%02X", response->vp_octets[i+2]);
+                        }
+                        *ptr = 0;
+                        strcat(msg, " V=3 M=May Need to reset cached password");
+
                        mschap_add_reply(request, &request->reply->vps,
                                         *response->vp_octets,
-                                        "MS-CHAP-Error", "E=691 R=1", 9);
+                                        "MS-CHAP-Error", msg, strlen(msg));
                        return RLM_MODULE_REJECT;
                }

-------------- next part --------------
index bdf4668..051fe71 100644
--- a/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c
+++ b/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c
@@ -195,7 +195,9 @@ static int eapmschapv2_compose(EAP_HANDLER *handler, VALUE_PAIR *reply)
 
        case PW_MSCHAP_ERROR:
                DEBUG2("MSCHAP Failure\n");
-               length = 4 + MSCHAPV2_FAILURE_MESSAGE_LEN;
+               /* JCH need to be change length to work with full v2 message  */
+               // length = 4 + MSCHAPV2_FAILURE_MESSAGE_LEN;
+               length = 4 + reply->length-1;
                eap_ds->request->type.data = malloc(length);
 
                /*
@@ -212,7 +214,11 @@ static int eapmschapv2_compose(EAP_HANDLER *handler, VALUE_PAIR *reply)
                eap_ds->request->type.data[1] = eap_ds->response->id;
                length = htons(length);
                memcpy((eap_ds->request->type.data + 2), &length, sizeof(uint16_t));
-               memcpy((eap_ds->request->type.data + 4), MSCHAPV2_FAILURE_MESSAGE, MSCHAPV2_FAILURE_MESSAGE_LEN);
+               /* JCH need to copy the failure message from mschapv2 - it contains ascii version of the challenge C=... */
+                memcpy((eap_ds->request->type.data + 4),
+               (reply->vp_strvalue+1),
+                (reply->length-1));
+               //MSCHAPV2_FAILURE_MESSAGE, MSCHAPV2_FAILURE_MESSAGE_LEN);
                break;
 
        default:
@@ -485,6 +491,18 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
                return 1;
                break;
 
+       /*JCH added - is this is an ack of a failure message */
+        case PW_EAP_MSCHAPV2_FAILURE:
+               if (data->code != PW_EAP_MSCHAPV2_FAILURE) {
+                       radlog(L_ERR, "rlm_eap_mschapv2: Unexpected FAILURE received");
+                       return 0;
+               }
+               //JCH needed??? handler->request->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;
+                eap_ds->request->code = PW_EAP_FAILURE;
+                return 1;
+                break;
+
+
                /*
                 *      Something else, we don't know what it is.
                 */
@@ -657,12 +675,12 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
                 *      Don't return anything in the error message.
                 */
                eap_ds->request->code = PW_EAP_FAILURE;
-               return 1;
-#if 0
-               pairmove2(&handler->request->reply->vps, &response
+//             return 1;
+//#if 0
+               pairmove2(&response, &handler->request->reply->vps,
                          PW_MSCHAP_ERROR);
                data->code = PW_EAP_MSCHAPV2_FAILURE;
-#endif
+//#endif
        }
 
        /*


More information about the Freeradius-Users mailing list