📄 eapmschapv2.c
字号:
printf("Retry value : %d\n", retry);#endif temp_store = (char *)malloc(32); // It shouldn't be more than 16 bytes. memcpy(temp_store, &chal_blk[2], 32); process_hex(temp_store, 32, challenge); free(temp_store);#if MSCHAP_DEBUG printf("Challenge Value : "); print_hex(challenge, 16);#endif pchange = (int)strtod(&pchange_blk[2], &junk);#if MSCHAP_DEBUG printf("Password change value (should be 3) : %d\n", pchange);#endif memcpy(msg, &msg_blk[2], (strlen(msg_blk)-2));#if MSCHAP_DEBUG printf("Result message : %s\n", msg);#endif}// Convert a string to unicode(ish)char *to_uni(char *non_uni){ char *retUni; int i; retUni = (char *)malloc((strlen(non_uni)+1)*2); bzero(retUni, ((strlen(non_uni)+1)*2)); for (i=0; i<strlen(non_uni); i++) { retUni[(2*i)] = non_uni[i]; } return retUni;}// Pass in the needed information, along with a non-unicode password.// The spec calls for a unicode password, but we will pad it with 0s// to make it work for now. ;)void GenerateNTResponse(char *auth_chal, char *peer_chal, char *username, char *non_uni_password, char *out){ char challenge[8]; char password_hash[16]; char *unicode_password; challenge_hash(auth_chal, auth_chal, username, (char *)&challenge); unicode_password = to_uni(non_uni_password); ntpasswordhash(unicode_password, (strlen(non_uni_password)*2), (char *)&password_hash);#if MSCHAP_DEBUG printf("NtPasswordHash : "); print_hex((char *)&password_hash, 16);#endif mschap(challenge, password_hash, out); free(unicode_password);}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); ntpasswordhash(uni_passwd, (strlen(passwd)*2), (char*)&PasswordHash); 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, (char *)&Digest, &Digest_len); // Is this normal? Should auth_chal = peer_chal? challenge_hash(auth_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, auth_response, &Digest_len);}// 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************************************************************/int 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; char *error_msg; char *authstr; char peer_challenge[16]; char zeros[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char *retbuf; char *answer; // Get our username and password out of our configuration structure in memory username = get_username(); password = get_password();#ifdef MSCHAP_DEBUG xlogf(DEBUG_AUTHTYPES, "(EAPMS-CHAP) ID : %02x\n",get_receivedId()); xlogf(DEBUG_AUTHTYPES, "Username = %s -- Password = %s\n",username,password);#endif // The first payload byte tells us what we are doing. switch (in[0]) { case 0x00 : printf("(EAPMS-CHAP) ACK\n"); // Don't know what to return right now... break; case 0x01 : mschap_id = in[1];#if MSCHAP_DEBUG printf("(EAPMS-CHAP) Identifier : %02x\n", mschap_id);#endif mschap_length = ((in[2] << 8) + in[3]);#if MSCHAP_DEBUG printf("(EAPMS-CHAP) Length : %d\n", mschap_length);#endif //This value should be 16. if (in[4] != 0x10) { printf("ERROR!!!: Value should be 16!\n"); } 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 - (16+5)); memcpy(radius_host, &in[16+5], (mschap_length - (16+5))); radius_host[((mschap_length - (16+5))+1)] = 0x00; printf("(EAPMS-CHAP) RADIUS host : %s\n", radius_host); free(radius_host); // Generate some random bytes. RAND_bytes((char *)&peer_challenge, 16); memcpy(&savedvars.PeerChallenge, &peer_challenge, 16); retbuf = (char *)malloc(25); GenerateNTResponse(mschap_challenge, peer_challenge, username, password, retbuf); memcpy(&savedvars.NtResponse, retbuf, 24); // Save a copy for later. out[0] = 0x02; // Response. out[1] = mschap_id; out[2] = 0x00; // We shouldn't have an answer larger than 255. out[3] = 49; out[4] = 0x31; // This should also be 49. memcpy(&out[5], &mschap_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); free(retbuf); break; case 0x03: // MSCHAP success packet! mschap_length = ((in[2] << 8)+in[3]); answer = (char *)malloc(mschap_length); memcpy(answer, &in[4], mschap_length); authstr = (char *)malloc(20); // Should be exactly 20 bytes. error_msg = (char *)malloc(128); 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) {#if MSCHAP_DEBUG printf("Server is authentic!\n");#endif out[0]=0x03; // Send a success. *out_size = 1; } else {#if MSCHAP_DEBUG printf("This isn't our server!!!!\n");#endif } free(authstr); free(answer); break; case 0x04: // MSCHAP error! mschap_length = ((in[2] << 8)+in[3]); error_msg = (char *)malloc(mschap_length); memcpy(error_msg, &in[4], mschap_length);#if MSCHAP_DEBUG printf("Error message : %s\n", error_msg);#endif retbuf = (char *)malloc(128); // Stash our clear text error. answer = (char *)malloc(16); // Our response challenge. decode_error(error_msg, &err, &retry, answer, &pwval, retbuf); free(error_msg); switch (err) { case 646: printf("Error : Your login is not allowed at this time!\n"); break; case 647: printf("Error : Your account has been disabled.\n"); break; case 648: printf("Error : Your password has expired!\n"); break; case 649: printf("Error : You lack dial-in permissions. 8-)\n"); break; case 691: printf("Error : Authentication Failure\n"); break; case 709: printf("Error : Failure changing password\n"); break; }#if MSCHAP_DEBUG if (retry == 1) { printf("Retry is allowed!\n"); } else printf("Retry is NOT allowed!\n"); printf("Challenge Value : "); print_hex(answer, 16); printf("\n"); if (pwval != 3) { printf("This is a valid MS-CHAPv2 server.\n"); } else printf("WTF - This isn't a valid MS-CHAPv2 server?\n");#endif printf("Message is : %s\n",retbuf); // Since we don't have a way to prompt the user for another password // we will just send back a failure here. free(retbuf); free(answer); break; } return 0;}/****************************************************************** * Get the password for the <nasid:id> found in the config file. ******************************************************************/int eapmschap_auth_challenge(){ char *temp_username=NULL; char *temp_password=NULL; char *trash; // We may want to ask for the user's password. temp_username = get_username(); // We need to think of a better way to handle this. Right now, if you // put in an incorrect password, you can never fix it. trash = get_password(); if (trash == NULL) { xlogf(DEBUG_NORMAL, "(MS-CHAPv2 Authentication) %s's Password : ",temp_username); temp_password = getpass(""); //This is obsolete, fix it! set_password(temp_password); // Update our config values. } else { xlogf(DEBUG_AUTHTYPES, "get_password returned a value!\n"); } free(trash); free(temp_username); temp_username = NULL; 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.#ifdef MSCHAP_DEBUG xlogf(DEBUG_AUTHTYPES, "(EAPMS-CHAP) Cleaning up.\n");#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -