⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eapleap.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * 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 + -