📄 eapleap.c
字号:
memcpy(challenge_response_got, &leapresponse->randval, leapresponse->count);
// store AP response.
memcpy(leapdata->leapchallenges->apr, leapresponse->randval, 24);
// Let's contstruct the expected one.
memset(challenge_response_expected, 0x00, 24);
// Calculate the 24 bytes MS-CHAP Challenge Response
leap_mschap(leapdata->password, (char *)&challenge_response_expected,
leapdata->leapchallenges->apc);
if (memcmp(challenge_response_got, challenge_response_expected, 24) == 0)
{
debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) AP Challenge Response got is "
"valid!\n");
leapdata->eapsuccess = TRUE;
}
else
{
debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) AP Challenge Response got is "
"NOT valid!\n");
}
FREE(challenge_response_got);
// We were successful, so generate keying material.
ntPwdHash(MD4Hash, leapdata->password);
md4_calc(MD4HashHash, MD4Hash, 16);
debug_printf(DEBUG_AUTHTYPES, "leap_session_key : ");
debug_hex_printf(DEBUG_AUTHTYPES, MD4HashHash, 16);
GetMasterLEAPKey((char *)&MD4HashHash, (char *)leapdata->leapchallenges->apc,
(char *)leapdata->leapchallenges->apr,
(char *)leapdata->leapchallenges->pc,
(char *)leapdata->leapchallenges->pr,
(char *)&MasterKey);
debug_printf(DEBUG_AUTHTYPES, "Master LEAP Key : ");
debug_hex_printf(DEBUG_AUTHTYPES, (uint8_t *)&MasterKey, 16);
// Finally, populate our keying material.
FREE(leapdata->keyingMaterial);
leapdata->keyingMaterial = Malloc(64);
if (leapdata->keyingMaterial == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store keying "
"material!\n");
ipc_events_malloc_failed(NULL);
return;
}
memcpy(&leapdata->keyingMaterial[32], &MasterKey, 16);
memcpy(leapdata->keyingMaterial, &MasterKey, 16);
leapdata->eaptype = EAP_REQUEST_PKT;
eapdata->methodState = DONE;
eapdata->ignore = FALSE;
eapdata->decision = UNCOND_SUCC;
eapdata->altAccept = TRUE;
}
/**
* Process an EAP Success Packet during a LEAP conversation.
**/
void eapleap_success_pkt(eap_type_data *eapdata)
{
struct leap_data *leapdata = NULL;
uint8_t chall_response[17];
struct config_pwd_only *leapconf;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
{
eap_type_common_fail(eapdata);
return;
}
if (!xsup_assert((eapdata->eap_conf_data != NULL),
"eapdata->eap_conf_data != NULL", FALSE))
{
eap_type_common_fail(eapdata);
return;
}
leapconf = (struct config_pwd_only *)eapdata->eap_conf_data;
if (eapdata->ident == NULL)
{
debug_printf(DEBUG_NORMAL, "There is no valid username available!\n");
debug_printf(DEBUG_NORMAL, "Did you remember to specify an Identity in "
"the configuration file?\n");
eap_type_common_fail(eapdata);
return;
}
leapdata = (struct leap_data *)eapdata->eap_data;
debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Got EAP-SUCCESS\n");
memset(&chall_response, 0x00, 8);
NtChallengeResponse((char *)leapdata->leaprequest->randval,
leapdata->password,
(char *)&chall_response, 0);
GenerateNTResponse((char *)leapdata->leapchallenges->pr,
(char *)leapdata->leapchallenges->pc,
eapdata->ident, leapdata->password,
(char *)&chall_response, 0);
// store AP challenge
memcpy(&leapdata->leapchallenges->apc, chall_response, 8);
debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) GenerateNTResponse Calculated "
": ");
debug_hex_printf(DEBUG_AUTHTYPES, chall_response, 8);
leapdata->result_size = 8+3+strlen(eapdata->ident)+1;
leapdata->result = Malloc(leapdata->result_size);
if (leapdata->result == NULL)
{
debug_printf(DEBUG_NORMAL, "(EAP-LEAP) Couldn't allocate memory to store"
" success response!\n");
ipc_events_malloc_failed(NULL);
eap_type_common_fail(eapdata);
return;
}
// Construct the LEAP request sub fields packet
// let's start with the version number (LEAP subfield)
// byte 0: Version
// byte 1: Unused - Reserved
// byte 2: Count
// byte 3..10: MS-CHAP Nt Challenge Response
// byte 11..m: username
leapdata->result[0] = 0x01;
leapdata->result[1] = 0x00; // Reserved - Unused
leapdata->result[2] = 8; // Count
// Include MSCHAP Challenge response in the built packet
memcpy(&leapdata->result[3], chall_response, 8);
// include username in the built packet.
memcpy(&leapdata->result[8+3], eapdata->ident, strlen(eapdata->ident)+1);
// Store the new random value to leapdata for further validation of the
// AP response!
memcpy(&leapdata->leaprequest->randval[0], chall_response, 8);
debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Request packet for mutual "
"authentication built!\n");
leapdata->eaptype = EAP_REQUEST_PKT;
eapdata->ignore = FALSE;
eapdata->methodState = MAY_CONT;
}
/**
* Process a LEAP request.
**/
void eapleap_process(eap_type_data *eapdata)
{
struct eap_header *eaphdr;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
debug_printf(DEBUG_AUTHTYPES, "(LEAP) Processing.\n");
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
{
eap_type_common_fail(eapdata);
return;
}
// Since LEAP is a weird protocol, we will get EAP requests, responses,
// and successes. So, we need to check for each type, and process them
// as needed.
eaphdr = (struct eap_header *)eapdata->eapReqData;
switch (eaphdr->eap_code)
{
case EAP_REQUEST_PKT:
eapleap_request_pkt(eapdata);
break;
case EAP_SUCCESS_PKT:
eapleap_success_pkt(eapdata);
break;
case EAP_RESPONSE_PKT:
eapleap_response_pkt(eapdata);
break;
default:
debug_printf(DEBUG_NORMAL, "Unknown EAP packet type! (%02X)\n",
eaphdr->eap_code);
break;
}
}
/**
* Build a LEAP response.
**/
uint8_t *eapleap_buildResp(eap_type_data *eapdata)
{
uint8_t *response;
struct leap_data *leapdata;
struct eap_header *eaphdr;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
{
eap_type_common_fail(eapdata);
return NULL;
}
leapdata = (struct leap_data *)eapdata->eap_data;
if (leapdata->result == NULL)
{
if (eapdata->decision != UNCOND_SUCC)
{
debug_printf(DEBUG_NORMAL, "LEAP had nothing to send, but didn't "
"seem to signal the state machine correctly?\n");
eap_type_common_fail(eapdata);
}
eapdata->ignore = TRUE;
return NULL;
}
// Otherwise, we need to build an EAP header, and send things on.
response = Malloc(leapdata->result_size + sizeof(struct eap_header));
if (response == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to build response "
"packet!\n");
ipc_events_malloc_failed(NULL);
eap_type_common_fail(eapdata);
return NULL;
}
eaphdr = (struct eap_header *)response;
switch (leapdata->eaptype)
{
case EAP_SUCCESS_PKT:
// Build a success packet to send to the AP.
eaphdr->eap_code = leapdata->eaptype;
eaphdr->eap_identifier = eap_type_common_get_eap_reqid(eapdata->eapReqData);
eaphdr->eap_length = htons(sizeof(struct eap_header));
eaphdr->eap_type = EAP_SUCCESS_PKT;
break;
case EAP_REQUEST_PKT:
case EAP_RESPONSE_PKT:
// Build a normal EAP packet to send to the AP.
eaphdr->eap_code = leapdata->eaptype;
eaphdr->eap_identifier = eap_type_common_get_eap_reqid(eapdata->eapReqData);
eaphdr->eap_length = htons(leapdata->result_size + sizeof(struct eap_header));
eaphdr->eap_type = EAP_TYPE_LEAP;
memcpy(&response[sizeof(struct eap_header)], leapdata->result,
leapdata->result_size);
break;
}
FREE(leapdata->result);
return response;
}
/**
* Determine if key data is available.
**/
uint8_t eapleap_isKeyAvailable(eap_type_data *eapdata)
{
struct leap_data *leapdata;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return FALSE;
if (!xsup_assert((eapdata->eap_data != NULL),
"eapdata->eap_data != NULL", FALSE))
return FALSE;
leapdata = (struct leap_data *)eapdata->eap_data;
if (leapdata->keyingMaterial == NULL) return FALSE;
return TRUE;
}
/**
* Return key data.
**/
uint8_t *eapleap_getKey(eap_type_data *eapdata)
{
struct leap_data *leapdata;
uint8_t *keydata;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return FALSE;
if (!xsup_assert((eapdata->eap_data != NULL),
"eapdata->eap_data != NULL", FALSE))
return FALSE;
leapdata = (struct leap_data *)eapdata->eap_data;
keydata = Malloc(64);
if (keydata == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to return key "
"data!\n");
return NULL;
}
memcpy(keydata, leapdata->keyingMaterial, 64);
return keydata;
}
/**
* Return the length of the keying material.
**/
uint8_t eapleap_getKey_len(eap_type_data *eapdata)
{
return 16;
}
/**
* Clean up following our authentication.
**/
void eapleap_deinit(eap_type_data *eapdata)
{
struct leap_data *leapdata;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
return;
leapdata = (struct leap_data *)eapdata->eap_data;
FREE(leapdata->keyingMaterial);
FREE(leapdata->leaprequest);
FREE(leapdata->leapchallenges);
FREE(leapdata->password);
FREE(leapdata);
debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Cleaning up.\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -