📄 eapleap.c
字号:
/**
* LEAP implementation.
*
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file eapleap.c
*
* \author Marios Karagiannopoulos (marios@master.math.upatras.gr)
*
* Modified to support dynamic keying by Chris Hessing, with help from
* Gilbert Goodwill.
**/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef WINDOWS
#include <winsock2.h>
#endif
#include "../../../lib/libxsupconfig/xsupconfig_structs.h"
#include "../../xsup_common.h"
#include "../../../lib/libxsupconfig/xsupconfig.h"
#include "../../context.h"
#include "../../xsup_debug.h"
#include "../../xsup_err.h"
#include "../../frame_structs.h"
#include "../../eap_sm.h"
#include "eapleap.h"
#include "leapmd4.h"
#include "../../eap_types/mschapv2/mschapv2.h"
#include "../../ipc_callout.h"
#include "../../xsup_ipc.h"
#include "../../eap_types/eap_type_common.h"
#include "../../ipc_events.h"
#include "../../ipc_events_index.h"
#ifdef USE_EFENCE
#include <efence.h>
#endif
#define LEAP_LENGTH 0x08
/**
* Convert a regular ASCII password in to a Unicode password, and generate
* an MD4 hash of it.
**/
static void ntPwdHash(unsigned char *MD4Hash, char *password)
{
char unicodePass[513];
char passLen;
int i;
if (!xsup_assert((MD4Hash != NULL), "MD4Hash != NULL", FALSE))
return;
if (!xsup_assert((password != NULL), "password != NULL", FALSE))
return;
/* Microsoft passwords are unicode. Convert plain text password
to unicode by inserting a zero every other byte */
passLen = strlen(password);
for (i = 0; i < passLen; i++) {
unicodePass[2 * i] = password[i];
unicodePass[2 * i + 1] = 0;
}
/* Encrypt plain text password to a 16-byte MD4 hash */
md4_calc(MD4Hash, (uint8_t *) unicodePass, passLen * 2);
}
void leap_mschap(char * password, char * response, uint8_t *apc)
{
unsigned char MD4Hash[16], MD4HashHash[16];
if (!xsup_assert((password != NULL), "password != NULL", FALSE))
return;
if (!xsup_assert((response != NULL), "response != NULL", FALSE))
return;
ntPwdHash(MD4Hash, password);
md4_calc(MD4HashHash, MD4Hash, 16);
ChallengeResponse((char *)apc, (char *) MD4HashHash, response);
}
/**
* Setup to handle LEAP EAP requests
*
* This function is called when we receive the first packet of a LEAP
* authentication request. At a minimum, it should check to make sure it's
* stub in the structure exists, and if not, set up any varliables it may need.
*
**/
int eapleap_init(eap_type_data *eapdata)
{
struct leap_data *mydata;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return XEMALLOC;
mydata = (struct leap_data *)Malloc(sizeof(struct leap_data));
if (mydata == NULL)
{
debug_printf(DEBUG_NORMAL, "Cannot allocate memory in %s()!\n",
__FUNCTION__);
ipc_events_malloc_failed(NULL);
return XEMALLOC;
}
FREE(mydata->keyingMaterial);
mydata->eapsuccess = FALSE;
if (eapdata->eap_data != NULL)
{
eapleap_deinit(eapdata);
}
eap_type_common_init_eap_data(eapdata);
eapdata->eap_data = mydata;
return XENONE;
}
/**
* Check to make sure we have everything we need to do a LEAP authentication.
**/
void eapleap_check(eap_type_data *eapdata)
{
struct config_pwd_only *leapconf = NULL;
struct leap_data *leapdata = NULL;
context *ctx = NULL;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
if (!xsup_assert((eapdata->eap_conf_data != NULL),
"eapdata->eap_conf_data != NULL", FALSE))
{
eap_type_common_fail(eapdata);
return;
}
debug_printf(DEBUG_AUTHTYPES, "(LEAP) Checking..\n");
if (eapdata->methodState == INIT)
{
if (eapleap_init(eapdata) != XENONE)
{
eap_type_common_fail(eapdata);
return;
}
}
leapconf = (struct config_pwd_only *)eapdata->eap_conf_data;
leapdata = (struct leap_data *)eapdata->eap_data;
FREE(leapdata->password);
ctx = event_core_get_active_ctx();
if (ctx == NULL)
{
debug_printf(DEBUG_NORMAL, "No password available for LEAP!\n");
eap_type_common_fail(eapdata);
return;
}
if (ctx->prof->temp_password == NULL)
{
if (leapconf->password == NULL)
{
debug_printf(DEBUG_NORMAL, "No password available for LEAP!\n");
eap_type_common_fail(eapdata);
return;
}
else
{
leapdata->password = _strdup(leapconf->password);
}
}
else
{
leapdata->password = _strdup(ctx->prof->temp_password);
}
}
/**
* Process an EAP Request Packet that contains LEAP.
**/
void eapleap_request_pkt(eap_type_data *eapdata)
{
struct leap_data *leapdata = NULL;
struct config_pwd_only *leapconf;
uint8_t chall_response[24];
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;
leapdata = (struct leap_data *)eapdata->eap_data;
leapdata->eapsuccess = FALSE;
leapdata->leapchallenges = (struct leap_challenges *)Malloc(sizeof(struct leap_challenges));
if (leapdata->leapchallenges == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store LEAP "
"challenge data.\n");
ipc_events_malloc_failed(NULL);
eap_type_common_fail(eapdata);
return;
}
leapdata->leaprequest = (struct leap_requests *)Malloc(sizeof(struct leap_requests));
if (leapdata->leaprequest == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store LEAP "
"request data!\n");
eap_type_common_fail(eapdata);
return;
}
// store Peer challenge
memcpy(leapdata->leaprequest,
&eapdata->eapReqData[sizeof(struct eap_header)],
sizeof(struct leap_requests));
memcpy(leapdata->leapchallenges->pc, leapdata->leaprequest->randval, 8);
if (leapdata->leaprequest->count != LEAP_LENGTH)
{
debug_printf(DEBUG_NORMAL, "(EAP-LEAP) Incorrect length for LEAP "
"random value!\n");
eap_type_common_fail(eapdata);
return;
}
memset(chall_response, 0x00, 24);
debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Incoming Peer Challenge Random "
"Value (Length = %d) : ", leapdata->leaprequest->count);
debug_hex_printf(DEBUG_AUTHTYPES, leapdata->leaprequest->randval,
leapdata->leaprequest->count);
if (!xsup_assert((leapdata->password != NULL), "leapdata->password != NULL",
FALSE))
{
debug_printf(DEBUG_NORMAL, "LEAP doesn't have a valid password!\n");
eap_type_common_fail(eapdata);
return;
}
NtChallengeResponse((char *)leapdata->leapchallenges->pc, leapdata->password,
(char *)&chall_response, 0);
// Store peer response.
memcpy(leapdata->leapchallenges->pr, chall_response, 24);
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 "
"setting in the configuration file?\n");
eap_type_common_fail(eapdata);
return;
}
leapdata->result_size = 24+3+strlen(eapdata->ident)+1;
leapdata->result = Malloc(leapdata->result_size);
if (leapdata->result == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store LEAP "
"response!\n");
ipc_events_malloc_failed(NULL);
eap_type_common_fail(eapdata);
return;
}
// Construct the LEAP response sub fields packet
// let's start with the version number (LEAP subfield)
// byte 0: Version
// byte 1: Unused - Reserved
// byte 2: Count
// byte 3..26: MS-CHAP Challenge Response
// byte 27..m: username
leapdata->result[0] = 0x01;
leapdata->result[1] = 0x00; // Reserved - Unused
leapdata->result[2] = 24; // Count
// Include MSCHAP Challenge response in the built packet.
memcpy(&leapdata->result[3], chall_response, 24);
// Include username in the built packet
memcpy(&leapdata->result[24+3], eapdata->ident, strlen(eapdata->ident)+1);
leapdata->eaptype = EAP_RESPONSE_PKT;
eapdata->ignore = FALSE;
eapdata->methodState = MAY_CONT;
}
/**
* Process an EAP Response Packet that contains LEAP.
**/
void eapleap_response_pkt(eap_type_data *eapdata)
{
struct leap_data *leapdata = NULL;
struct leap_responses *leapresponse = NULL;
uint8_t *challenge_response_got;
uint8_t challenge_response_expected[24];
struct config_pwd_only *leapconf;
uint8_t MD4Hash[16], MD4HashHash[16], MasterKey[16];
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;
leapdata = (struct leap_data *)eapdata->eap_data;
leapresponse = (struct leap_responses *)&eapdata->eapReqData[sizeof(struct eap_header)];
challenge_response_got = Malloc(leapresponse->count+1);
if (challenge_response_got == NULL)
{
debug_printf(DEBUG_NORMAL, "(EAP-LEAP) challenge_response_got is NULL"
" after malloc!\n");
ipc_events_malloc_failed(NULL);
eap_type_common_fail(eapdata);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -