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

📄 peap_phase2.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * PEAP phase 2 implementation.
 *
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file peap_phase2.c
 *
 * \author chris@open1x.org
 *
 * $Id: peap_phase2.c,v 1.34.2.41 2007/09/27 21:22:49 chessing Exp $
 * $Date: 2007/09/27 21:22:49 $
 **/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef WINDOWS
#include <netinet/in.h>
#else
#include <winsock2.h>
#endif

#include "../../../lib/libxsupconfig/xsupconfig_structs.h"
#include "../../xsup_common.h"
#include "../../../lib/libxsupconfig/xsupconfig.h"
#include "../../context.h"
#include "../../eap_sm.h"
#include "peap_phase2.h"
#include "eappeap.h"
#include "../tls/eaptls.h"
#include "../tls/tls_funcs.h"
#include "../../xsup_err.h"
#include "../../xsup_debug.h"
#include "../mschapv2/eapmschapv2.h"
#include "../otp/eapotp.h"
#include "../../frame_structs.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 VALID_EAP_TYPE  EAP_TYPE_MSCHAP

static uint8_t eap_ident = 0;

/*******************************************************************
 *
 *  Set the PEAP version that we will be using.
 *
 *******************************************************************/
uint8_t set_peap_version(struct phase2_data *p2d, uint8_t new_version)
{
  if (!xsup_assert((p2d != NULL), "p2d != NULL", FALSE))
    return XEMALLOC;

  if (new_version > HIGHEST_PEAP_SUPPORTED) 
    {
      p2d->peap_version = HIGHEST_PEAP_SUPPORTED;
      return HIGHEST_PEAP_SUPPORTED;
    }

  /* Only change versions if we are changing to a higher one.  This will   *
   * keep us from backing off to a lower version mid-communication, should *
   * the RADIUS server get confused.                                       */
  if (p2d->peap_version < new_version)
    {
      debug_printf(DEBUG_AUTHTYPES, "PEAP Version changed to %d\n",
		   new_version);

      p2d->peap_version = new_version;
    }
  return p2d->peap_version;
}

/**************************************************************************
 *
 * Get PEAP version #.
 *
 **************************************************************************/
uint8_t get_peap_version(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;
  struct phase2_data *p2d;

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

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

  mytls_vars = (struct tls_vars *)eapdata->eap_data;

  p2d = mytls_vars->phase2data;

  if (p2d == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't determine the PEAP version we "
		   "are using!\n");
      return 0;
    }

  return p2d->peap_version;
}

/**************************************************************************
 *
 * Remove the PEAP padding that is used to make a v0 packet a v1 packet.
 *
 **************************************************************************/
void peap_unpad_frame(uint8_t *in, uint16_t in_size, uint8_t *out, 
		      uint16_t *out_size)
{
  if (!xsup_assert((in != NULL), "in != NULL", FALSE))
    return;

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

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

  if (in_size > 1520)
    {
      debug_printf(DEBUG_NORMAL, "Packet too large in peap_unpad_frame()!\n");
      return;
    }

  if ((in_size - 4) <= 0)
  {
	  debug_printf(DEBUG_NORMAL, "Your RADIUS server is on crack!  It sent an empty inner packet!\n");
	  return;
  }

  *out_size = in_size - 4;

  memcpy(out, &in[4], (in_size - 4));
}

/*************************************************************************
 *
 * Pad out the packet so that a v0 packet is a v1 packet that can be
 * processed by the EAP state machine.
 *
 * A v0 packet is basically missing the first 4 bytes of an EAP message. So,
 * we need to recreate those.  The identifier can't be gleaned from any
 * data we know, so it is stored in a static variable called eap_ident.
 * eap_ident should be incremented each time, before it is used in order
 * to keep the EAP state machine from discarding the packet.
 *
 *************************************************************************/
void peap_pad_frame(uint8_t *in, uint16_t in_size, uint8_t *out, 
		    uint16_t *out_size)
{
  struct eap_header *eaphdr;

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

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

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

  if (in_size > 1520)
    {
      debug_printf(DEBUG_NORMAL, "In packet size to large!  Ignoring!\n");
      return;
    }

  *out_size = in_size + 4;

  eaphdr = (struct eap_header *)out;

  eaphdr->eap_code = EAP_REQUEST_PKT;

  if (eap_ident == 0xff) eap_ident = 0;

  eap_ident ++;

  eaphdr->eap_identifier = eap_ident;
  eaphdr->eap_length = htons(in_size+4);

  memcpy(&out[4], in, in_size);
}


/***********************************************************************
 *
 * Process a PEAP v1 packet.
 *
 ***********************************************************************/
int do_peap_version1(struct phase2_data *p2d, uint8_t *in, uint16_t in_size, 
		      uint8_t *out, uint16_t *out_size)
{
  uint8_t *padded_frame = NULL;
  uint8_t eapvalue, eapid;
  int retval = XENONE;

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

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

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

  if (in_size > 1520)
    {
      debug_printf(DEBUG_NORMAL, "Invalid frame passed in to do_peap_version1()!\n");
      return XEINVALIDEAP;
    }

  debug_printf(DEBUG_AUTHTYPES, "Unpadded packet (%d) :\n", in_size);
  debug_hex_dump(DEBUG_AUTHTYPES, in, in_size);
  
  *out_size = 0;

  eapvalue = in[4];
  eapid = in[5]; /* Inner EAP id. */

  debug_printf(DEBUG_AUTHTYPES, "Inner packet : \n");
  if (in_size < 1522)
    {
      debug_hex_dump(DEBUG_AUTHTYPES, in, in_size);
      p2d->sm->eapReq = TRUE;
      p2d->sm->eapReqData = in;
    } else {
      debug_printf(DEBUG_AUTHTYPES, "INVALID PACKET SIZE!\n");
    }

  switch (eapvalue)
    {
      case PEAP_EAP_EXTENSION: /* EAP Extension */
      debug_printf(DEBUG_AUTHTYPES, "Got an EAP extension frame!\n");
      out[0] = EAP_RESPONSE_PKT;
      memcpy(&out[1], &in[1], in_size-1);
      p2d->sm->decision = COND_SUCC;
      *out_size = in_size;
      return XEINNERDONE;
      break;

    default:
      debug_printf(DEBUG_AUTHTYPES, "Running inner state machine...\n");
      eap_sm_run(p2d->sm);
      break;
    }
  
  FREE(padded_frame);

  if (p2d->sm->eapRespData != NULL)
  {
	debug_printf(DEBUG_AUTHTYPES, "Inner EAP returned : \n");
	debug_hex_dump(DEBUG_AUTHTYPES, p2d->sm->eapRespData, eap_type_common_get_eap_length(p2d->sm->eapRespData));
  }
  else
  {
	  debug_printf(DEBUG_AUTHTYPES, "No data returned from inner EAP method.\n");
	  if (p2d->sm->eapSuccess == TRUE) 
	    {
	      debug_printf(DEBUG_AUTHTYPES, "Inner auth completed.\n");
	      retval = XEINNERDONE;
	    }
  }

  if (p2d->sm->eapRespData != NULL)
    {
      *out_size = eap_type_common_get_eap_length(p2d->sm->eapRespData);
      memcpy(out, p2d->sm->eapRespData, *out_size);
      FREE(p2d->sm->eapRespData);
    }

  return retval;
}

/**********************************************************************
 *
 * Process a PEAP v0 packet.  To do this, we want to rebuild the EAP
 * header so that it looks like a PEAP v1 packet.  Once we are done
 * processing the packet as a PEAP v1 packet, we need to remove the
 * padding, so that we send back a v0 packet.
 *
 **********************************************************************/
int do_peap_version0(struct phase2_data *p2d, uint8_t *in, uint16_t in_size, 
		     uint8_t *out, uint16_t *out_size)
{
  uint8_t *padded_frame = NULL, *new_frame = NULL, eframe = 0;
  uint16_t padded_size = 0, new_frame_size = 0;
  int retval = XENONE;

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

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

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

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

  *out_size = 0;

  if (in_size > 1520)
    {
      debug_printf(DEBUG_NORMAL, "Input frame is too big! Ignoring!\n");
      *out_size = 0;
      retval = XEMALLOC;
      goto out;
    }

  padded_size = in_size;

  padded_frame = (uint8_t *)Malloc(in_size+19);  // It is 19 bytes to pad out.
  if (padded_frame == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Unable to allocate memory for padded_frame "
		   "in %s()!\n", __FUNCTION__);
	  ipc_events_malloc_failed(NULL);
      retval = XEMALLOC;
      goto out;
    }

  if ((in[4] == 0x21) && (in[5] == 0x80))
    {
      eframe = 1;

⌨️ 快捷键说明

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