X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fchap.c;h=a48f69f2158500a8d906d3c79a47e1b39453bde0;hp=114ed4d6bbfd7e05ee64a7b82d58d21309f3017e;hb=1aa145faffde86065d6ae1af4041d185c7733342;hpb=b38527fb14af5ebe3d2559e2f861575c722a1ce9 diff --git a/pppd/chap.c b/pppd/chap.c index 114ed4d..a48f69f 100644 --- a/pppd/chap.c +++ b/pppd/chap.c @@ -33,7 +33,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: chap.c,v 1.30 2002/04/02 13:54:59 dfs Exp $" +#define RCSID "$Id: chap.c,v 1.33 2002/09/01 12:00:15 dfs Exp $" /* * TODO: @@ -500,7 +500,6 @@ ChapReceiveChallenge(cstate, inp, id, len) case CHAP_MICROSOFT: ChapMS(cstate, rchallenge, secret, secret_len, (MS_ChapResponse *) cstate->response); - cstate->resp_length = MS_CHAP_RESPONSE_LEN; break; case CHAP_MICROSOFT_V2: @@ -509,7 +508,6 @@ ChapReceiveChallenge(cstate, inp, id, len) cstate->resp_name, secret, secret_len, (MS_Chap2Response *) cstate->response, cstate->earesponse, MS_CHAP2_AUTHENTICATEE); - cstate->resp_length = MS_CHAP2_RESPONSE_LEN; break; #endif /* CHAPMS */ @@ -585,6 +583,11 @@ ChapReceiveResponse(cstate, inp, id, len) BCOPY(inp, rhostname, len); rhostname[len] = '\000'; +#ifdef CHAPMS + /* copy the flags into cstate for use elsewhere */ + if (cstate->chal_type == CHAP_MICROSOFT_V2) + cstate->resp_flags = ((MS_Chap2Response *) remmd)->Flags[0]; +#endif /* CHAPMS */ /* * Get secret for authenticating them with us, * do the hash ourselves, and compare the result. @@ -648,8 +651,9 @@ ChapReceiveResponse(cstate, inp, id, len) ChapMS(cstate, cstate->challenge, secret, secret_len, &md); /* compare MDs and send the appropriate status */ - if (memcmp(&md + response_offset, - remmd + response_offset, response_size) == 0) + if (memcmp((u_char *) &md + response_offset, + (u_char *) remmd + response_offset, + response_size) == 0) code = CHAP_SUCCESS; /* they are the same! */ break; } @@ -823,35 +827,35 @@ ChapReceiveFailure(cstate, inp, id, len) /* No M=; use the error code. */ switch(error) { case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: - p = "Restricted logon hours"; + p = "E=646 Restricted logon hours"; break; case MS_CHAP_ERROR_ACCT_DISABLED: - p = "Account disabled"; + p = "E=647 Account disabled"; break; case MS_CHAP_ERROR_PASSWD_EXPIRED: - p = "Password expired"; + p = "E=648 Password expired"; break; case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: - p = "No dialin permission"; + p = "E=649 No dialin permission"; break; case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: - p = "Authentication failure"; + p = "E=691 Authentication failure"; break; case MS_CHAP_ERROR_CHANGING_PASSWORD: /* Should never see this, we don't support Change Password. */ - p = "Error changing password"; + p = "E=709 Error changing password"; break; default: free(msg); p = msg = malloc(len + 33); if (!msg) { - notice("Out of memory in ChapReceiveFailure"); + novm("ChapReceiveFailure"); goto print_msg; } slprintf(p, len + 33, "Unknown authentication failure: %.*s", @@ -934,16 +938,30 @@ ChapSendStatus(cstate, code) #ifdef CHAPMS if (cstate->chal_type == CHAP_MICROSOFT_V2) { /* - * Success message must be formatted as + * Per RFC 2759, success message must be formatted as * "S= M=" * where * is the Authenticator Response (mutual auth) * is a text message + * + * However, some versions of Windows (win98 tested) do not know + * about the M= part (required per RFC 2759) and flag + * it as an error (reported incorrectly as an encryption error + * to the user). Since the RFC requires it, and it can be + * useful information, we supply it if the peer is a conforming + * system. Luckily (?), win98 sets the Flags field to 0x04 + * (contrary to RFC requirements) so we can use that to + * distinguish between conforming and non-conforming systems. + * + * Special thanks to Alex Swiridov for + * help debugging this. */ slprintf(p, q - p, "S="); p += 2; slprintf(p, q - p, "%s", cstate->saresponse); p += strlen(cstate->saresponse); + if (cstate->resp_flags != 0) + goto msgdone; slprintf(p, q - p, " M="); p += 3; } @@ -966,7 +984,16 @@ ChapSendStatus(cstate, code) * * The M=m part is only for MS-CHAPv2, but MS-CHAP should ignore * any extra text according to RFC 2433. So we'll go the easy - * (read: lazy) route and include it always. + * (read: lazy) route and include it always. Neither win2k nor + * win98 (others untested) display the message to the user anyway. + * They also both ignore the E=e code. + * + * Note that it's safe to reuse the same challenge as we don't + * actually accept another response based on the error message + * (and no clients try to resend a response anyway). + * + * Basically, this whole bit is useless code, even the small + * implementation here is only because of overspecification. */ slprintf(p, q - p, "E=691 R=1 C="); p += 12; @@ -980,6 +1007,7 @@ ChapSendStatus(cstate, code) slprintf(p, q - p, "I don't like you. Go 'way."); } +msgdone: msglen = strlen(msg); outlen = CHAP_HEADERLEN + msglen;