X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fchap_ms.c;h=016b42e0c10ee9a845a3e96ad8aa55dcb2b0464c;hp=aec12262ed46375d304b12f9b397acb88be21ba4;hb=d883b2dbafeed3ebd9d7a56ab1469373bd001a3b;hpb=dd39af173ba7e20360fff462cd5848aeb9471a4c diff --git a/pppd/chap_ms.c b/pppd/chap_ms.c index aec1226..016b42e 100644 --- a/pppd/chap_ms.c +++ b/pppd/chap_ms.c @@ -320,25 +320,90 @@ chapms_make_response(unsigned char *response, int id, char *our_name, ChapMS(challenge, secret, secret_len, response); } +struct chapms2_response_cache_entry { + int id; + unsigned char challenge[16]; + unsigned char response[MS_CHAP2_RESPONSE_LEN]; + unsigned char auth_response[MS_AUTH_RESPONSE_LENGTH]; +}; + +#define CHAPMS2_MAX_RESPONSE_CACHE_SIZE 10 +static struct chapms2_response_cache_entry + chapms2_response_cache[CHAPMS2_MAX_RESPONSE_CACHE_SIZE]; +static int chapms2_response_cache_next_index = 0; +static int chapms2_response_cache_size = 0; + +static void +chapms2_add_to_response_cache(int id, unsigned char *challenge, + unsigned char *response, + unsigned char *auth_response) +{ + int i = chapms2_response_cache_next_index; + + chapms2_response_cache[i].id = id; + memcpy(chapms2_response_cache[i].challenge, challenge, 16); + memcpy(chapms2_response_cache[i].response, response, + MS_CHAP2_RESPONSE_LEN); + memcpy(chapms2_response_cache[i].auth_response, + auth_response, MS_AUTH_RESPONSE_LENGTH); + chapms2_response_cache_next_index = + (i + 1) % CHAPMS2_MAX_RESPONSE_CACHE_SIZE; + if (chapms2_response_cache_next_index > chapms2_response_cache_size) + chapms2_response_cache_size = chapms2_response_cache_next_index; + dbglog("added response cache entry %d", i); +} + +static struct chapms2_response_cache_entry* +chapms2_find_in_response_cache(int id, unsigned char *challenge, + unsigned char *auth_response) +{ + int i; + + for (i = 0; i < chapms2_response_cache_size; i++) { + if (id == chapms2_response_cache[i].id + && (!challenge + || memcmp(challenge, + chapms2_response_cache[i].challenge, + 16) == 0) + && (!auth_response + || memcmp(auth_response, + chapms2_response_cache[i].auth_response, + MS_AUTH_RESPONSE_LENGTH) == 0)) { + dbglog("response found in cache (entry %d)", i); + return &chapms2_response_cache[i]; + } + } + return NULL; /* not found */ +} + static void chapms2_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { + const struct chapms2_response_cache_entry *cache_entry; + unsigned char auth_response[MS_AUTH_RESPONSE_LENGTH]; + challenge++; /* skip length, should be 16 */ *response++ = MS_CHAP2_RESPONSE_LEN; + cache_entry = chapms2_find_in_response_cache(id, challenge, NULL); + if (cache_entry) { + memcpy(response, cache_entry->response, MS_CHAP2_RESPONSE_LEN); + return; + } ChapMS2(challenge, #ifdef DEBUGMPPEKEY mschap2_peer_challenge, #else NULL, #endif - our_name, secret, secret_len, response, private, + our_name, secret, secret_len, response, auth_response, MS_CHAP2_AUTHENTICATEE); + chapms2_add_to_response_cache(id, challenge, response, auth_response); } static int -chapms2_check_success(unsigned char *msg, int len, unsigned char *private) +chapms2_check_success(int id, unsigned char *msg, int len) { if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || strncmp((char *)msg, "S=", 2) != 0) { @@ -349,7 +414,7 @@ chapms2_check_success(unsigned char *msg, int len, unsigned char *private) msg += 2; len -= 2; if (len < MS_AUTH_RESPONSE_LENGTH - || memcmp(msg, private, MS_AUTH_RESPONSE_LENGTH)) { + || !chapms2_find_in_response_cache(id, NULL /* challenge */, msg)) { /* Authenticator Response did not match expected. */ error("MS-CHAPv2 mutual authentication failed."); return 0;