📄 eapmschapv2.c
字号:
if (eapmschapv2_init(eapdata) != XENONE)
{
debug_printf(DEBUG_NORMAL, "Failed to properly initialize "
"EAP-MSCHAPv2!\n");
eapdata->methodState = EAP_FAIL;
return;
}
}
challenge = (struct mschapv2_challenge *)&eapdata->eapReqData[sizeof(struct eap_header)];
switch (challenge->OpCode)
{
case MS_CHAPV2_CHALLENGE:
eapdata->methodState = eapmschapv2_challenge(eapdata);
break;
case MS_CHAPV2_RESPONSE:
debug_printf(DEBUG_NORMAL, "Got an MS-CHAPv2 response packet! Your "
"RADIUS server is probably broken.\n");
break;
case MS_CHAPV2_SUCCESS:
eapdata->methodState = eapmschapv2_success(eapdata);
break;
case MS_CHAPV2_FAILURE:
eapdata->methodState = eapmschapv2_failure(eapdata);
break;
case MS_CHAPV2_CHANGE_PWD:
debug_printf(DEBUG_NORMAL, "Password changing is not supported!\n");
break;
default:
debug_printf(DEBUG_NORMAL, "Unknown OpCode %d!\n", challenge->OpCode);
break;
}
}
/*******************************************************************
*
* Build a challenge response message.
*
*******************************************************************/
uint8_t *eapmschapv2_challenge_resp(eap_type_data *eapdata)
{
struct mschapv2_vars *myvars;
struct config_eap_mschapv2 *eapconf;
struct mschapv2_response *response;
uint8_t *resp = NULL;
uint16_t respsize;
uint8_t eapid = 0;
struct eap_header *eap_header;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
return NULL;
if (!xsup_assert((eapdata->eapReqData != NULL),
"eapdata->eapReqData != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eap_conf_data != NULL),
"eapdata->eap_conf_data != NULL", FALSE))
return NULL;
myvars = (struct mschapv2_vars *)eapdata->eap_data;
eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;
// 54 bytes is the length of the response, including MS-CHAPv2 header.
respsize = 54+strlen(eapdata->ident)+sizeof(struct eap_header);
resp = Malloc(respsize);
if (resp == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for return frame "
"in %s!\n", __FUNCTION__);
return NULL;
}
// Get the EAP ID from the packet sent in.
eap_header = (struct eap_header *)eapdata->eapReqData;
eapid = eap_header->eap_identifier;
// Build the EAP header for the response.
eap_header = (struct eap_header *)resp;
eap_header->eap_code = EAP_RESPONSE_PKT;
eap_header->eap_identifier = eapid;
eap_header->eap_length = htons(respsize);
eap_header->eap_type = EAP_TYPE_MSCHAPV2;
// Now, build the MS-CHAPv2 part of the response.
response = (struct mschapv2_response *)&resp[sizeof(struct eap_header)];
response->OpCode = MS_CHAPV2_RESPONSE;
response->MS_CHAPv2_ID = myvars->MS_CHAPv2_ID;
response->MS_Length = htons(54+strlen(eapdata->ident));
response->Value_Size = 49;
if (eap_fast_mode == TRUE)
{
memset((uint8_t *)&response->Peer_Challenge, 0x00, 16);
}
else
{
memcpy((uint8_t *)&response->Peer_Challenge, myvars->PeerChallenge, 16);
}
memset((uint8_t *)&response->Reserved, 0x00, 8);
memcpy((uint8_t *)&response->NT_Response, myvars->NtResponse, 24);
debug_printf(DEBUG_AUTHTYPES, "response->NT_Response = ");
debug_hex_printf(DEBUG_AUTHTYPES, response->NT_Response, 24);
response->Flags = 0;
memcpy(&resp[sizeof(struct eap_header)+54], eapdata->ident,
strlen(eapdata->ident));
return resp;
}
/******************************************************************
*
* Build a success response message.
*
******************************************************************/
uint8_t *eapmschapv2_success_resp(eap_type_data *eapdata)
{
struct mschapv2_vars *myvars;
struct config_eap_mschapv2 *eapconf;
uint8_t *resp = NULL;
uint16_t respsize = 0;
struct eap_header *eap_header;
uint8_t eapid = 0;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
return NULL;
if (!xsup_assert((eapdata->eapReqData != NULL),
"eapdata->eapReqData != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eap_conf_data != NULL),
"eapdata->eap_conf_data != NULL", FALSE))
return NULL;
myvars = (struct mschapv2_vars *)eapdata->eap_data;
eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;
// 54 bytes is the length of the response, including MS-CHAPv2 header.
respsize = sizeof(struct eap_header) + 1;
resp = Malloc(respsize);
if (resp == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for return frame "
"in %s!\n", __FUNCTION__);
ipc_events_malloc_failed(NULL);
return NULL;
}
// Get the EAP ID from the packet sent in.
eap_header = (struct eap_header *)eapdata->eapReqData;
eapid = eap_header->eap_identifier;
// Build the EAP header for the response.
eap_header = (struct eap_header *)resp;
eap_header->eap_code = EAP_RESPONSE_PKT;
eap_header->eap_identifier = eapid;
eap_header->eap_length = htons(respsize);
eap_header->eap_type = EAP_TYPE_MSCHAPV2;
resp[sizeof(struct eap_header)] = MS_CHAPV2_SUCCESS;
return resp;
}
/**********************************************************************
*
* Return a response to a failure message.
*
**********************************************************************/
uint8_t *eapmschapv2_failure_resp(eap_type_data *eapdata)
{
struct mschapv2_vars *myvars;
struct config_eap_mschapv2 *eapconf;
uint8_t *resp = NULL;
uint16_t respsize = 0;
struct eap_header *eap_header;
uint8_t eapid = 0;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
return NULL;
if (!xsup_assert((eapdata->eapReqData != NULL),
"eapdata->eapReqData != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eap_conf_data != NULL),
"eapdata->eap_conf_data != NULL", FALSE))
return NULL;
myvars = (struct mschapv2_vars *)eapdata->eap_data;
eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;
// 54 bytes is the length of the response, including MS-CHAPv2 header.
respsize = sizeof(struct eap_header) + 1;
resp = Malloc(respsize);
if (resp == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for return frame "
"in %s!\n", __FUNCTION__);
ipc_events_malloc_failed(NULL);
return NULL;
}
// Get the EAP ID from the packet sent in.
eap_header = (struct eap_header *)eapdata->eapReqData;
eapid = eap_header->eap_identifier;
// Build the EAP header for the response.
eap_header = (struct eap_header *)resp;
eap_header->eap_code = EAP_RESPONSE_PKT;
eap_header->eap_identifier = eapid;
eap_header->eap_length = htons(respsize);
eap_header->eap_type = EAP_TYPE_MSCHAPV2;
resp[sizeof(struct eap_header)] = MS_CHAPV2_FAILURE;
return resp;
}
/******************************************************************
*
* Build a response packet for EAP-MSCHAPv2.
*
******************************************************************/
uint8_t *eapmschapv2_buildResp(eap_type_data *eapdata)
{
struct mschapv2_challenge *challenge;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return NULL;
if (!xsup_assert((eapdata->eapReqData != NULL),
"eapdata->eapReqData != NULL", FALSE))
return NULL;
challenge = (struct mschapv2_challenge *)&eapdata->eapReqData[sizeof(struct eap_header)];
switch (challenge->OpCode)
{
case MS_CHAPV2_CHALLENGE:
return eapmschapv2_challenge_resp(eapdata);
break;
case MS_CHAPV2_RESPONSE:
debug_printf(DEBUG_NORMAL, "Not sending a response for a response!\n");
return NULL;
break;
case MS_CHAPV2_SUCCESS:
return eapmschapv2_success_resp(eapdata);
break;
case MS_CHAPV2_FAILURE:
return eapmschapv2_failure_resp(eapdata);
break;
case MS_CHAPV2_CHANGE_PWD:
debug_printf(DEBUG_NORMAL, "Got a request to change the user's password"
" but this is unsupported!\n");
break;
default:
debug_printf(DEBUG_NORMAL, "Unknown Op Code, can't build response!\n");
return NULL;
}
return NULL;
}
/******************************************************************
*
* Determine if a key is available.
*
******************************************************************/
uint8_t eapmschapv2_isKeyAvailable(eap_type_data *eapdata)
{
struct mschapv2_vars *myvars;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return FALSE;
if (!xsup_assert((eapdata->eap_data != NULL),
"eapdata->eap_data != NULL", FALSE))
return FALSE;
myvars = (struct mschapv2_vars *)eapdata->eap_data;
if (myvars->keyingMaterial == NULL)
return FALSE;
return TRUE;
}
/******************************************************************
*
* Return the key material that we have developed during the EAP
* authentication.
*
******************************************************************/
uint8_t *eapmschapv2_getKey(eap_type_data *eapdata)
{
struct mschapv2_vars *myvars;
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;
myvars = (struct mschapv2_vars *)eapdata->eap_data;
// XXX Fix this up. (Low priority, since MS-CHAPv2 keying doesn't
// provide anything useful except for with EAP-FAST.
/*
if (myvars->eap_fast_mode == TRUE) printf("Weird EAP-FAST mode enabled!\n");
if (((peer_challenge != NULL) && (authenticator_challenge != NULL)) ||
(myvars->eap_fast_mode == TRUE))*/
{
// If we get here, then EAP-FAST is using us as an inner method. So,
// mangle the key data in the way that it wants, and return it.
debug_printf(DEBUG_AUTHTYPES, "Returning EAP-FAST style keying material.\n");
memcpy(&myvars->keyingMaterial[16], &myvars->keyingMaterial[0], 16);
memcpy(&myvars->keyingMaterial[0], &myvars->keyingMaterial[32], 16);
}
keydata = Malloc(64);
if (keydata == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for key data!\n");
ipc_events_malloc_failed(NULL);
return NULL;
}
memcpy(keydata, myvars->keyingMaterial, 64);
return keydata;
}
/**********************************************************************
*
* Clean up anything that might be left in memory.
*
**********************************************************************/
void eapmschapv2_deinit(eap_type_data *eapdata)
{
struct mschapv2_vars *myvars;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
myvars = (struct mschapv2_vars *)eapdata->eap_data;
if (eapdata->eap_data != NULL)
{
FREE(myvars->AuthenticatorChallenge);
FREE(myvars->PeerChallenge);
FREE(myvars->NtResponse);
FREE(myvars->keyingMaterial);
FREE(myvars->password);
FREE(eapdata->eap_data);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -