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