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

📄 eapmschapv2.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
 * EAP-MSCHAPv2 Function implementations
 * 
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file eapmschapv2.c
 *
 * \author chris@open1x.org
 *
 * $Id: eapmschapv2.c,v 1.35.2.40 2007/09/01 00:38:27 chessing Exp $
 * $Date: 2007/09/01 00:38:27 $
 **/

#include <openssl/rand.h>
#include <string.h>

#ifndef WINDOWS
#include <netinet/in.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 "eapmschapv2.h"
#include "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

static uint8_t *peer_challenge = NULL;
static uint8_t *authenticator_challenge = NULL;
static uint8_t eap_fast_mode = 0;

/******************************************************************
 *
 *  *** NOTE *** This function must be called *BEFORE* the init 
 *  phase of the EAP method.  Calling it later will do nothing.
 *
 *  Set the peer_challenge, and authenticator_challenge variables
 *  above so that we can know that we are in the goofy EAP-FAST mode
 *  of MS-CHAPv2 and act accordingly.
 *
 ******************************************************************/
// XXX Store this someplace that isn't a global variable!!!
uint8_t eapmschapv2_set_challenges(uint8_t *pc, uint8_t *ac)
{
  FREE(peer_challenge);
  FREE(authenticator_challenge);

  if ((ac == NULL) && (pc == NULL)) 
    {
      debug_printf(DEBUG_AUTHTYPES, "Cleared MS-CHAPv2 provisioning mode.\n");
      return TRUE;
    }

  peer_challenge = Malloc(16);
  if (peer_challenge == NULL) 
  {
	  ipc_events_malloc_failed(NULL);
	  return FALSE;
  }

  memcpy(peer_challenge, pc, 16);

  debug_printf(DEBUG_AUTHTYPES, "Peer Challenge : ");
  debug_hex_printf(DEBUG_AUTHTYPES, peer_challenge, 16);

  authenticator_challenge = Malloc(16);
  if (authenticator_challenge == NULL)
    {
      FREE(peer_challenge);
	  ipc_events_malloc_failed(NULL);
      return FALSE;
    }

  memcpy(authenticator_challenge, ac, 16);
  
  debug_printf(DEBUG_AUTHTYPES, "Authenticator Challenge : ");
  debug_hex_printf(DEBUG_AUTHTYPES, authenticator_challenge, 16);

  return TRUE;
}

/******************************************************************
 *
 *  Configured EAP-MS-CHAPv2 to run in the weird EAP-FAST modes.
 *
 ******************************************************************/
void eapmschapv2_set_eap_fast_mode(eap_type_data *ctx, uint8_t enable)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

  debug_printf(DEBUG_AUTHTYPES, "Setting EAP-FAST mode for MS-CHAPv2!\n");
  eap_fast_mode = enable;
}

/******************************************************************
 *
 * Execute the INIT functions for this EAP method.
 *
 ******************************************************************/
int eapmschapv2_init(eap_type_data *eapdata)
{
  struct mschapv2_vars *mscv2data = NULL;
  struct config_eap_mschapv2 *eapconf = NULL;
  context *ctx = NULL;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return XEMALLOC;

  eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;

  if (eapconf == NULL)
    {
      debug_printf(DEBUG_NORMAL, "There is no valid configuration for "
		   "EAP-MSCHAPv2.\n");
      eap_type_common_fail(eapdata);
      return XEGENERROR;
    }

  // It is possible that this is a reauthentication, and something is
  // already on our EAP data hook.  So, clear it out.
  eapmschapv2_deinit(eapdata);

  eapdata->eap_data = (uint8_t *)Malloc(sizeof(struct mschapv2_vars));
  if (eapdata->eap_data == NULL) 
  {
	  ipc_events_malloc_failed(NULL);
	  return XEMALLOC;
  }

  mscv2data = (struct mschapv2_vars *)eapdata->eap_data;

  if ((peer_challenge != NULL) && (authenticator_challenge != NULL))
    {
      eap_fast_mode = TRUE;
      mscv2data->AuthenticatorChallenge = authenticator_challenge;
      mscv2data->PeerChallenge = peer_challenge;
    }

	ctx = event_core_get_active_ctx();
	if (ctx == NULL)
	{
      debug_printf(DEBUG_NORMAL, "No password available for EAP-MSCHAPv2!\n");
      eap_type_common_fail(eapdata);
      return XEGENERROR;
	}

	if (ctx->prof->temp_password == NULL)
    {
		if (eapconf->password == NULL)
		{
			debug_printf(DEBUG_NORMAL, "No password available for EAP-MSCHAPv2!\n");
			eap_type_common_fail(eapdata);
			return XEGENERROR;
		}
		else
		{
			mscv2data->password = _strdup(eapconf->password);
		}
    }
  else
  {
	  mscv2data->password = _strdup(ctx->prof->temp_password);
  }

  eap_type_common_init_eap_data(eapdata);

  return XENONE;
}

/******************************************************************
 *
 * Verify that this packet is really an EAP-MSCHAPv2 packet.
 *
 ******************************************************************/
void eapmschapv2_check(eap_type_data *eapdata)
{
  struct eap_header *myeap = NULL;
  struct mschapv2_challenge *mv2 = NULL;
  struct config_eap_mschapv2 *eapconf = NULL;
  context *ctx = NULL;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return;

  myeap = (struct eap_header *)eapdata->eapReqData;

  if (myeap == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No valid packet was passed in to %s!\n",
		   __FUNCTION__);
      eap_type_common_fail(eapdata);
      return;
    }

  if (myeap->eap_code != EAP_REQUEST_PKT)
    {
      debug_printf(DEBUG_NORMAL, "EAP isn't a request packet!\n");
      eap_type_common_fail(eapdata);
      return;
    }

  if (ntohs(myeap->eap_length) < (2 + sizeof(struct eap_header)))
    {
      debug_printf(DEBUG_NORMAL, "Not enough data for valid EAP method.\n");
      eap_type_common_fail(eapdata);
      return;
    }

  mv2 = (struct mschapv2_challenge *)&eapdata->eapReqData[sizeof(struct eap_header)];
  
  if ((mv2->OpCode < MS_CHAPV2_CHALLENGE) || (mv2->OpCode > MS_CHAPV2_FAILURE))
    {
      debug_printf(DEBUG_NORMAL, "Unsupported EAP-MSCHAPv2 OpCode!  (Code : "
		   "%d)\n", mv2->OpCode);
      eap_type_common_fail(eapdata);
      return;
    }

  eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;

  if (eapconf == NULL)
    {
      debug_printf(DEBUG_NORMAL, "There is no valid configuration for "
		   "EAP-MSCHAPv2.\n");
      eap_type_common_fail(eapdata);
      return;
    }

  if (eapconf->password == NULL)
    {
		ctx = event_core_get_active_ctx();
		if (ctx == NULL)
		{
	      debug_printf(DEBUG_NORMAL, "No password available for EAP-MSCHAPv2!\n");
	      eap_type_common_fail(eapdata);
	      return;
		}

		if (ctx->prof->temp_password == NULL)
		{
			debug_printf(DEBUG_NORMAL, "No password available for EAP-MSCHAPv2!\n");
			eap_type_common_fail(eapdata);
			return;
		}
    }
}

/**
 * \brief Strip the domain off the username (if present).
 *
 * \note  The caller is expected to free the value returned in "shortname".
 *
 * @param[in] longname   The username that MAY contain a DOMAIN\ format.
 * @param[out] shortname   The username without the DOMAIN\ format.
 **/
void eapmschapv2_strip_backslash(char *longname, char **shortname)
{	
	char *substr = NULL;

	if (longname == NULL) 
	{
		(*shortname) = NULL;
		return;
	}

	substr = strstr(longname, "\\");
	if (substr == NULL)
	{
		(*shortname) = _strdup(longname);
		return;
	}

	// Otherwise, return 1 character beyond the one we found.
	(*shortname) = _strdup(substr+1);   // Ick!  Pointer math. ;)
}

/******************************************************************
 *
 *  Process an MSCHAPv2 challenge message.  It should return one of the
 *  eapMethod state values.
 *
 ******************************************************************/
uint8_t eapmschapv2_challenge(eap_type_data *eapdata)
{
  struct mschapv2_challenge *challenge = NULL;
  struct mschapv2_vars *myvars = NULL;
  struct config_eap_mschapv2 *eapconf = NULL;
  char *username = NULL;
  char *ident = NULL;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return EAP_FAIL;

  if (!xsup_assert((eapdata->eapReqData != NULL),
		   "eapdata->eapReqData != NULL", FALSE))
    return EAP_FAIL;

  if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
		   FALSE))
    return EAP_FAIL;

  if (!xsup_assert((eapdata->eap_conf_data != NULL), 
		   "eapdata->eap_conf_data != NULL", FALSE))
    return EAP_FAIL;

  eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;

  myvars = (struct mschapv2_vars *)eapdata->eap_data;

  challenge = (struct mschapv2_challenge *)&eapdata->eapReqData[sizeof(struct eap_header)];

  debug_printf(DEBUG_AUTHTYPES, "(EAP-MS-CHAPv2) ID : %02X\n",
	       challenge->MS_CHAPv2_ID);

  // Store a copy for the response.
  myvars->MS_CHAPv2_ID = challenge->MS_CHAPv2_ID;

  // This value should *ALWAYS* be 0x10.
  if (challenge->Value_Size != 0x10)
    {
      if (eapconf->ias_quirk == 1)
	{
	  debug_printf(DEBUG_NORMAL, "(EAP-MS-CHAPv2) Invalid Value-Size! "
		       "(%d), forced to 0x10 (ias_quirk = yes)\n", 
		       challenge->Value_Size);
	  challenge->Value_Size = 0x10;
	}
      else 
	{
	  debug_printf(DEBUG_NORMAL, "(EAP-MS-CHAPv2) Invalid Value-Size! (%d)"
		       "\n", challenge->Value_Size);
	  debug_printf(DEBUG_NORMAL, "(EAP-MS-CHAPv2) Should you enable "
		       "ias_quirk?\n");
	  return EAP_FAIL;
	}
    }


  if (eap_fast_mode != TRUE)
    {
      FREE(myvars->AuthenticatorChallenge);
      
      myvars->AuthenticatorChallenge = (uint8_t *)Malloc(16);
      if (myvars->AuthenticatorChallenge == NULL)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for the "
		       "Authenticator Challenge!\n");
	  ipc_events_malloc_failed(NULL);

	  return EAP_FAIL;
	}

      memcpy(myvars->AuthenticatorChallenge, &challenge->Challenge, 16);
    }

  debug_printf(DEBUG_AUTHTYPES, "Authenticator Challenge : ");
  debug_hex_printf(DEBUG_AUTHTYPES, (uint8_t *) myvars->AuthenticatorChallenge,
		   16);

  if (eap_fast_mode != TRUE)
    {
      FREE(myvars->PeerChallenge);
      
      // Ignore the RADIUS host, we probably don't care.
      myvars->PeerChallenge = (uint8_t *)Malloc(16);
      if (myvars->PeerChallenge == NULL) 
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for the "
		       "Peer Challenge!\n");

	  ipc_events_malloc_failed(NULL);

	  return EAP_FAIL;
	}
      
      RAND_bytes((uint8_t *) myvars->PeerChallenge, 16);
    }

  debug_printf(DEBUG_AUTHTYPES, "Generated PeerChallenge : ");
  debug_hex_printf(DEBUG_AUTHTYPES, (uint8_t *) myvars->PeerChallenge,16);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -