📄 eapmschapv2.cpp
字号:
char password_hash[16];
if ((!Challenge) || (!Password) || (!Response))
{
return;
}
NtPasswordHash(Password, (char *)&password_hash);
ChallengeResponse(Challenge, (char *)&password_hash, Response);
}void GenerateAuthenticatorResponse(char *passwd, char *ntresponse, char *peer_chal, char *auth_chal, char *username, char *auth_response){ char PasswordHash[16]; char PasswordHashHash[16]; EVP_MD_CTX context; int Digest_len; char Digest[20]; char out_chal[8]; char *uni_passwd; char Magic1[39] = {0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74}; char Magic2[41] = {0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E}; uni_passwd = to_uni(passwd); HashNtPasswordHash((char *)&PasswordHash, (char *)&PasswordHashHash); EVP_DigestInit(&context, EVP_sha1()); EVP_DigestUpdate(&context, &PasswordHashHash, 16); EVP_DigestUpdate(&context, ntresponse, 24); EVP_DigestUpdate(&context, Magic1, 39); EVP_DigestFinal(&context, (u_char *)&Digest, (uint32_t *)&Digest_len); // Is this normal? Should auth_chal = peer_chal? challenge_hash(peer_chal, auth_chal, username, (char *)&out_chal); EVP_DigestInit(&context, EVP_sha1()); EVP_DigestUpdate(&context, &Digest, 20); EVP_DigestUpdate(&context, &out_chal, 8); EVP_DigestUpdate(&context, Magic2, 41); EVP_DigestFinal(&context, (u_char *)auth_response, (uint32_t *)&Digest_len); if (uni_passwd != NULL) { free(uni_passwd); uni_passwd = NULL; }}//526
char *to_unicode(char *non_uni)
{
char *retUni;
int i;
if (!non_uni)
{
return NULL;
}
retUni = (char *)malloc((strlen(non_uni)+1)*2);
if (retUni == NULL)
{
return NULL;
}
memset(retUni, 0, ((strlen(non_uni)+1)*2));
for (i=0; i<strlen(non_uni); i++)
{
retUni[(2*i)] = non_uni[i];
}
return retUni;
}// This should call GenerateAuthenticatorResponse, as stated in RFC 2759.int CheckAuthenticatorResponse(char *uni_passwd, char *ntresponse, char *peer_chal, char *auth_chal, char *username, char *recv_resp){ char MyResponse[20]; GenerateAuthenticatorResponse(uni_passwd, ntresponse, peer_chal, auth_chal, username, (char *)&MyResponse); if (memcmp(&MyResponse, recv_resp, 20) == 0) { return 1; } return 0;}/************************************************************* eapmschap_decode_packet - decode an MS-CHAPv2 message************************************************************///530 some mschap_challenge instead of peer_challenge
//531 change retbuf typeint eapmschap_decode_packet(u_char *in, int in_size, u_char *out, int *out_size){ char *username; char *password; char *radius_host; char mschap_challenge[16]; uint8_t mschap_id; uint16_t mschap_length; int err, retry, pwval, intsize; char *error_msg; char *authstr; char peer_challenge[16]; char zeros[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; u_char retbuf[24]; char *answer; // Get our username and password out of our configuration structure in memory username = get_username(); password = get_password(); // The first payload byte tells us what we are doing. switch (in[0]) { case 0x00 : // Don't know what to return right now... break; case 0x01 : mschap_id = in[1]; mschap_length = ((in[2] << 8) + in[3]); memcpy(&intsize, &in[2], 2); intsize = ntohs(intsize); mschap_length = intsize; //This value should be 16. if (in[4] != 0x10) { } memcpy(&mschap_challenge, &in[5], 16); // Shouldn't be any longer than this. memcpy(&savedvars.AuthenticatorChallenge, &mschap_challenge, 16); radius_host = (char *)malloc(mschap_length); // This is more than we need..... if (radius_host == NULL) { if (username != NULL) { free(username); username = NULL; } if (password != NULL) { free(password); password = NULL; } return -1; } memcpy(radius_host, &in[16+5], (mschap_length - (16+5))); radius_host[((mschap_length - (16+5))+1)] = 0x00; free(radius_host); // Generate some random bytes. RAND_bytes((u_char *)&peer_challenge, 16); memcpy(&savedvars.PeerChallenge, &peer_challenge, 16); GenerateNTResponse((char *)&mschap_challenge, (char *)&peer_challenge, username, password, (char *)&retbuf); memcpy(&savedvars.NtResponse, &retbuf, 24); // Save a copy for later. out[0] = 0x02; // Response. out[1] = mschap_id; mschap_length = htons(54+strlen(username));
memcpy(&out[2], &mschap_length, 2);
out[4] = 0x31; // This should also be 49. memcpy(&out[5], &peer_challenge,16); memcpy(&out[21], &zeros, 8); // Add our zeros. memcpy(&out[29], &retbuf, 24); out[53] = 0x00; // Flags are 0. memcpy(&out[54], username, strlen(username)); *out_size = 54 + strlen(username); break; case 0x02: // MSCHAP response packet! (Probably an error!) break; case 0x03: // MSCHAP success packet! memcpy(&intsize, &in[2], 2); intsize = ntohs(intsize); mschap_length = intsize; answer = (char *)malloc(mschap_length); if (answer == NULL) { return -1; } memcpy(answer, &in[4], mschap_length); authstr = (char *)malloc(20); // Should be exactly 20 bytes. if (authstr == NULL) { return -1; } error_msg = (char *)malloc(128); if (error_msg == NULL) { return -1; } decode_success(answer, strlen(answer), authstr, error_msg); free(error_msg); // Now, using the value from authstr, we should validate the server.. if (CheckAuthenticatorResponse(password, (char *) &savedvars.NtResponse, (char *)&savedvars.PeerChallenge, (char *)&savedvars.AuthenticatorChallenge, username, authstr) == 1) { out[0]=0x03; // Send a success. *out_size = 1; } else { out[0] = 0x03; *out_size = 1; } free(authstr); free(answer); break; case 0x04: // MSCHAP error! mschap_length = ((in[2] << 8)+in[3]); error_msg = (char *)malloc(mschap_length); if (error_msg == NULL) { return -1; } memcpy(error_msg, &in[4], mschap_length);
answer = (char *)malloc(16); // Our response challenge. if (answer == NULL) { return -1; } decode_error(error_msg, &err, &retry, answer, &pwval, (char *)&retbuf); free(error_msg); switch (err) { case 646: break; case 647: break; case 648: break; case 649: break; case 691: break; case 709: break; } // Since we don't have a way to prompt the user for another password // we will just send back a failure here. if (username != NULL) { free(username); username = NULL; } if (password != NULL) { free(password); password = NULL; } free(answer); break; default: break; } if (username != NULL) { free(username); username = NULL; } if (password != NULL) { free(password); password = NULL; } return 0;}/****************************************************************** * Get the password for the <nasid:id> found in the config file. ******************************************************************/int eapmschap_auth_setup(){ return 0;}// Clean up any memory we have allocated, and destroy anything we need to.int eapmschap_shutdown(){ // Don't free one_x_globals as it is a copy of a pointer to memory, and // the shutdown_eap function will free it.
return 0;}int mschap_gen_keyblock(){ // Currently, we don't generate keys for MS-CHAPv2, so this just returns 0. return -1;}//527
void ChallengeHash(char *PeerChallenge, char *AuthenticatorChallenge,
char *UserName, char *Challenge)
{
EVP_MD_CTX cntx;
char Digest[30];
int retLen;
if ((!PeerChallenge) || (!AuthenticatorChallenge) || (!UserName) ||
(!Challenge))
{
return;
}
memset(Digest, 0, 30);
EVP_DigestInit(&cntx, EVP_sha1());
EVP_DigestUpdate(&cntx, PeerChallenge, 16);
EVP_DigestUpdate(&cntx, AuthenticatorChallenge, 16);
EVP_DigestUpdate(&cntx, UserName, strlen(UserName));
EVP_DigestFinal(&cntx, (u_char *)&Digest, (unsigned int *)&retLen);
memcpy(Challenge, Digest, 8);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -