X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fchap_ms.c;h=016b42e0c10ee9a845a3e96ad8aa55dcb2b0464c;hp=75724c514b0946ad24e7c06d52bcf3eff9eca996;hb=9e05a25d76b3f83096c661678010320df673df6b;hpb=d876c1a1fee8e78feac2c5b5928b39ac7eae1022 diff --git a/pppd/chap_ms.c b/pppd/chap_ms.c index 75724c5..016b42e 100644 --- a/pppd/chap_ms.c +++ b/pppd/chap_ms.c @@ -74,7 +74,7 @@ * */ -#define RCSID "$Id: chap_ms.c,v 1.36 2006/05/21 11:56:40 paulus Exp $" +#define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $" #ifdef CHAPMS @@ -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; @@ -819,7 +884,8 @@ ChapMS(u_char *rchallenge, char *secret, int secret_len, ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); #ifdef MSLANMAN - ChapMS_LANMan(rchallenge, secret, secret_len, &response); + ChapMS_LANMan(rchallenge, secret, secret_len, + &response[MS_CHAP_LANMANRESP]); /* preferred method is set by option */ response[MS_CHAP_USENT] = !ms_lanman; @@ -852,7 +918,7 @@ ChapMS2(u_char *rchallenge, u_char *PeerChallenge, u_char *p = &response[MS_CHAP2_PEER_CHALLENGE]; int i; - BZERO(response, sizeof(*response)); + BZERO(response, MS_CHAP2_RESPONSE_LEN); /* Generate the Peer-Challenge if requested, or copy it if supplied. */ if (!PeerChallenge)