--- ppp-2.4.4.orig/pppd/chap_ms.c 2006-05-21 07:56:40.000000000 -0400 +++ ppp-2.4.4/pppd/chap_ms.c 2006-11-21 17:19:28.000000000 -0500 @@ -100,25 +100,18 @@ static void ascii2unicode __P((char[], int, u_char[])); static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); static void ChallengeResponse __P((u_char *, u_char *, u_char[24])); -static void ChapMS_NT __P((u_char *, char *, int, u_char[24])); -static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int, +static void ChapMS_NT __P((u_char *, u_char[16], u_char[24])); +static void ChapMS2_NT __P((u_char *, u_char[16], char *, u_char[16], u_char[24])); static void GenerateAuthenticatorResponsePlain - __P((char*, int, u_char[24], u_char[16], u_char *, + __P((u_char[16], u_char[24], u_char[16], u_char *, char *, u_char[41])); -#ifdef MSLANMAN -static void ChapMS_LANMan __P((u_char *, char *, int, u_char *)); -#endif - #ifdef MPPE -static void Set_Start_Key __P((u_char *, char *, int)); -static void SetMasterKeys __P((char *, int, u_char[24], int)); +static void Set_Start_Key __P((u_char *, u_char[16])); +static void SetMasterKeys __P((u_char[16], u_char[24], int)); #endif -#ifdef MSLANMAN -bool ms_lanman = 0; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif +bool chapms_secret_cleartext = 1; #ifdef MPPE u_char mppe_send_key[MPPE_MAX_KEY_LEN]; @@ -152,6 +145,8 @@ { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, "specify CHAP peer challenge" }, #endif + { "chapms_secret_cleartext", o_bool, &chapms_secret_cleartext, + "chap secrets is cleartext (otherwise hex encoded NT-hash)" }, { NULL } }; @@ -185,6 +180,40 @@ random_bytes(challenge, 16); } +static bool +secret_to_passwordhash(unsigned char *secret, int secret_len, + u_char PasswordHash[MD4_SIGNATURE_SIZE]) +{ + if (chapms_secret_cleartext) + { + /* secret is cleartext - convert to NT hash */ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + + /* Hash the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + } + else + { + /* convert hex encoded NT hash into binary */ + int i; + unsigned char lonybble, hinybble; + + if (secret_len != 32) + return 0; + for (i = 0; i < 32; i++) { + lonybble = toupper(secret[i]); + if (lonybble < '0') + return 0; + if (lonybble > 'F') + return 0; + PasswordHash[i / 2] = (hinybble << 4) | lonybble; + hinybble = lonybble; + } + } + return 1; +} + static int chapms_verify_response(int id, char *name, unsigned char *secret, int secret_len, @@ -194,6 +223,7 @@ unsigned char md[MS_CHAP_RESPONSE_LEN]; int diff; int challenge_len, response_len; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; challenge_len = *challenge++; /* skip length, is 8 */ response_len = *response++; @@ -208,8 +238,10 @@ } #endif + if (!secret_to_passwordhash(secret, secret_len, PasswordHash)) + goto bad; /* Generate the expected response. */ - ChapMS(challenge, (char *)secret, secret_len, md); + ChapMS(challenge, PasswordHash, md); #ifdef MSLANMAN /* Determine which part of response to verify against */ @@ -241,6 +273,7 @@ { unsigned char md[MS_CHAP2_RESPONSE_LEN]; char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; int challenge_len, response_len; challenge_len = *challenge++; /* skip length, is 16 */ @@ -248,9 +281,12 @@ if (response_len != MS_CHAP2_RESPONSE_LEN) goto bad; /* not even the right length */ + if (!secret_to_passwordhash(secret, secret_len, PasswordHash)) + goto bad; + /* Generate the expected response and our mutual auth. */ ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name, - (char *)secret, secret_len, md, + PasswordHash, md, (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); /* compare MDs and send the appropriate status */ @@ -315,9 +351,12 @@ unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + challenge++; /* skip length, should be 8 */ *response++ = MS_CHAP_RESPONSE_LEN; - ChapMS(challenge, secret, secret_len, response); + secret_to_passwordhash(secret, secret_len, PasswordHash); + ChapMS(challenge, PasswordHash, response); } static void @@ -325,6 +364,9 @@ unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + + secret_to_passwordhash(secret, secret_len, PasswordHash); challenge++; /* skip length, should be 16 */ *response++ = MS_CHAP2_RESPONSE_LEN; ChapMS2(challenge, @@ -333,7 +375,7 @@ #else NULL, #endif - our_name, secret, secret_len, response, private, + our_name, PasswordHash, response, private, MS_CHAP2_AUTHENTICATEE); } @@ -530,60 +572,22 @@ } static void -ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, +ChapMS_NT(u_char *rchallenge, u_char PasswordHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - ChallengeResponse(rchallenge, PasswordHash, NTResponse); } static void ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, - char *secret, int secret_len, u_char NTResponse[24]) + u_char PasswordHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char Challenge[8]; ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - ChallengeResponse(Challenge, PasswordHash, NTResponse); } -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void -ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, - unsigned char *response) -{ - int i; - u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* LANMan password is case insensitive */ - BZERO(UcasePassword, sizeof(UcasePassword)); - for (i = 0; i < secret_len; i++) - UcasePassword[i] = (u_char)toupper(secret[i]); - (void) DesSetkey(UcasePassword + 0); - DesEncrypt( StdText, PasswordHash + 0 ); - (void) DesSetkey(UcasePassword + 7); - DesEncrypt( StdText, PasswordHash + 8 ); - ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); -} -#endif - - void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], u_char PeerChallenge[16], @@ -632,18 +636,13 @@ static void GenerateAuthenticatorResponsePlain - (char *secret, int secret_len, + (u_char PasswordHash[16], u_char NTResponse[24], u_char PeerChallenge[16], u_char *rchallenge, char *username, u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); @@ -680,15 +679,10 @@ * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) */ static void -Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) +Set_Start_Key(u_char *rchallenge, u_char PasswordHash[MD4_SIGNATURE_SIZE]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); mppe_set_keys(rchallenge, PasswordHashHash); @@ -795,14 +789,9 @@ * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) */ static void -SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) +SetMasterKeys(u_char PasswordHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], int IsServer) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); mppe_set_keys2(PasswordHashHash, NTResponse, IsServer); } @@ -811,24 +800,17 @@ void -ChapMS(u_char *rchallenge, char *secret, int secret_len, +ChapMS(u_char *rchallenge, u_char PasswordHash[MD4_SIGNATURE_SIZE], unsigned char *response) { BZERO(response, MS_CHAP_RESPONSE_LEN); - ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); + ChapMS_NT(rchallenge, PasswordHash, &response[MS_CHAP_NTRESP]); -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, secret, secret_len, &response); - - /* preferred method is set by option */ - response[MS_CHAP_USENT] = !ms_lanman; -#else response[MS_CHAP_USENT] = 1; -#endif #ifdef MPPE - Set_Start_Key(rchallenge, secret, secret_len); + Set_Start_Key(rchallenge, PasswordHash); #endif } @@ -845,7 +827,7 @@ */ void ChapMS2(u_char *rchallenge, u_char *PeerChallenge, - char *user, char *secret, int secret_len, unsigned char *response, + char *user, u_char PasswordHash[16], unsigned char *response, u_char authResponse[], int authenticator) { /* ARGSUSED */ @@ -864,16 +846,16 @@ /* Generate the NT-Response */ ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, - secret, secret_len, &response[MS_CHAP2_NTRESP]); + PasswordHash, &response[MS_CHAP2_NTRESP]); /* Generate the Authenticator Response. */ - GenerateAuthenticatorResponsePlain(secret, secret_len, + GenerateAuthenticatorResponsePlain(PasswordHash, &response[MS_CHAP2_NTRESP], &response[MS_CHAP2_PEER_CHALLENGE], rchallenge, user, authResponse); #ifdef MPPE - SetMasterKeys(secret, secret_len, + SetMasterKeys(PasswordHash, &response[MS_CHAP2_NTRESP], authenticator); #endif } --- ppp-2.4.4.orig/pppd/chap_ms.h 2004-11-15 17:13:26.000000000 -0500 +++ ppp-2.4.4/pppd/chap_ms.h 2006-11-21 17:08:39.000000000 -0500 @@ -87,8 +87,8 @@ #define MS_CHAP2_AUTHENTICATEE 0 #define MS_CHAP2_AUTHENTICATOR 1 -void ChapMS __P((u_char *, char *, int, u_char *)); -void ChapMS2 __P((u_char *, u_char *, char *, char *, int, +void ChapMS __P((u_char *, u_char[MD4_SIGNATURE_SIZE], u_char *)); +void ChapMS2 __P((u_char *, u_char *, char *, u_char[MD4_SIGNATURE_SIZE], u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int)); #ifdef MPPE void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE]));