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

📄 eaptls.c

📁 linux 下通过802.1认证的安装包
💻 C
字号:
/**
 * EAPTLS (RFC 2716) Function implementations
 * 
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file eaptls.c
 *
 * \author chris@open1x.org
 *
 * $Id: eaptls.c,v 1.39.2.28 2007/09/01 00:38:27 chessing Exp $
 * $Date: 2007/09/01 00:38:27 $
 **/

#include <string.h>
#include <stdlib.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 "../../xsup_ipc.h"
#include "../../ipc_callout.h"
#include "../../frame_structs.h"
#include "../../eap_sm.h"
#include "../../eap_types/tls/eaptls.h"
#include "../../eap_types/tls/tls_funcs.h"
#include "../../eap_types/eap_type_common.h"
#include "../../ipc_events.h"
#include "../../ipc_events_index.h"

#ifdef USE_EFENCE
#include <efence.h>
#endif

/********************************************************************
 *
 * Allocate memory, needed to complete a TLS authentication.
 *
 ********************************************************************/
int eaptls_init(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;
  int retVal = 0;
  struct config_eap_tls *userdata = NULL;
  char *password = NULL;
  context *ctx = NULL;

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

  if (!xsup_assert((eapdata->eap_conf_data != NULL), 
		   "eapdata->eap_conf_data != NULL", FALSE))
    {
      eap_type_common_fail(eapdata);
      return XEMALLOC;
    }

  userdata = (struct config_eap_tls *)eapdata->eap_conf_data;

  retVal = XENONE;

  if (eapdata->eap_data != NULL)
    {
      eaptls_deinit(eapdata);
    }

  // First, set up the structure to hold all of our instance specific
  // variables.
  eapdata->eap_data = (char *)Malloc(sizeof(struct tls_vars));
  if (!eapdata->eap_data) 
    {
		ipc_events_malloc_failed(NULL);
      eap_type_common_fail(eapdata);
      return XEMALLOC;
    }

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

  mytls_vars->resume = userdata->session_resume;
  mytls_vars->verify_cert = TRUE;

  mytls_vars->sessionkeyconst = (uint8_t *)Malloc(TLS_SESSION_KEY_CONST_SIZE);
  if (mytls_vars->sessionkeyconst == NULL) return XEMALLOC;

  if (Strncpy((char *)mytls_vars->sessionkeyconst, TLS_SESSION_KEY_CONST_SIZE, 
	  TLS_SESSION_KEY_CONST, TLS_SESSION_KEY_CONST_SIZE) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Attempt to overflow destination string in %s() at %d!\n",
		  __FUNCTION__, __LINE__);
	  return XEMALLOC;
  }

  mytls_vars->sessionkeylen = TLS_SESSION_KEY_CONST_SIZE;

  mytls_vars->keyblock = NULL;
  mytls_vars->handshake_done = FALSE;

  debug_printf(DEBUG_AUTHTYPES, "(EAP-TLS) Initialized.\n");

  if ((retVal = tls_funcs_init(mytls_vars, EAP_TYPE_TLS))!=XENONE)
    {
      debug_printf(DEBUG_NORMAL, "Error initializing TLS functions!\n");
      return retVal;
    }
 
  if (certificates_load_root(mytls_vars, userdata->trusted_server) != XENONE)
    {
      debug_printf(DEBUG_NORMAL, "Error loading root certificate!\n");
      eap_type_common_fail(eapdata);
      return retVal;
    }

	ctx = event_core_get_active_ctx();
	if (ctx == NULL)
	{
      debug_printf(DEBUG_NORMAL, "No valid user password found!\n");
      eap_type_common_fail(eapdata);
	  return XEGENERROR;
	}

	if (ctx->prof->temp_password == NULL)
    {
		if (userdata->user_key_pass == NULL)
		{
			debug_printf(DEBUG_NORMAL, "No valid user password found!\n");
			eap_type_common_fail(eapdata);
			return XEGENERROR;
		}

		password = _strdup(userdata->user_key_pass);
    }
  else
  {
	  password = _strdup(ctx->prof->temp_password);
  }

  if ((retVal = tls_funcs_load_user_cert(mytls_vars, userdata->user_cert, 
					 userdata->user_key, password))!=XENONE)
    {
      debug_printf(DEBUG_NORMAL, "Error loading user certificate!\n");
      eap_type_common_fail(eapdata);
	  FREE(password);
      return retVal;
    } 
  FREE(password);

  if (tls_funcs_load_random(mytls_vars, userdata->random_file) != XENONE)
    {
      debug_printf(DEBUG_NORMAL, "Failed to load random data\n");
      eap_type_common_fail(eapdata);
      return -1;
    }

#ifndef WINDOWS
  if (userdata->sc.engine_id != NULL)
    {
      if (tls_funcs_load_engine(mytls_vars, &userdata->sc) != XENONE)
		{
			debug_printf(DEBUG_NORMAL, "Failed to initialize the OpenSC "
				       "engine.\n");
			return XETLSINIT;
		}
    }
#endif

  eap_type_common_init_eap_data(eapdata);

  return XENONE;
}

/*************************************************************************
 *
 * Verify the packet is really a TLS packet.
 *
 *************************************************************************/
void eaptls_check(eap_type_data *eapdata)
{
  struct eap_header *myeap;
  struct config_eap_tls *tlsconf;

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

  if (!xsup_assert((eapdata->eapReqData != NULL),
		   "eapdata->eapReqData != 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;
    }

  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 (myeap->eap_identifier == 0)
    {
      debug_printf(DEBUG_NORMAL, "Invalid EAP identifier!\n");
      eap_type_common_fail(eapdata);
      return;
    }

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

  tlsconf = (struct config_eap_tls *)eapdata->eap_conf_data;

  if (tlsconf->user_key_pass == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No password available for TLS certificate!\n");
      eap_type_common_fail(eapdata);
      return;
    }
}

/**************************************************************************
 *
 * Process a TLS request.
 *
 **************************************************************************/
void eaptls_process(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = 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;
    }

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

  debug_printf(DEBUG_AUTHTYPES, "(EAP-TLS) Processing.\n");

  if (eapdata->methodState == INIT)
    {
      debug_printf(DEBUG_AUTHTYPES, "(EAP-TLS) Requesting Init.\n");
      if (eaptls_init(eapdata) != XENONE)
        {
          debug_printf(DEBUG_NORMAL, "Failed to properly initialize "
                       "memory structures for EAP-TLS!\n");
	  eap_type_common_fail(eapdata);
          return;
        }
    }

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

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

  eapdata->methodState = tls_funcs_process(eapdata->eap_data,
					   eapdata->eapReqData);

  if (mytls_vars->handshake_done == TRUE)
    {
      eapdata->decision = MAY_CONT;
    }
  else
    {
      eapdata->decision = UNCOND_SUCC;
    }

  eapdata->ignore = FALSE; 
}

/************************************************************************
 *
 *  Build a TLS response packet.
 *
 ************************************************************************/
uint8_t *eaptls_buildResp(eap_type_data *eapdata)
{
  struct eap_header *eaphdr;
  uint8_t reqId;
  struct tls_vars *mytls_vars = NULL;
  struct config_eap_tls *eapconf;
  uint8_t *tlsres = NULL, *res = NULL;
  uint16_t res_size = 0, total_size = 0;

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

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

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

  eapconf = eapdata->eap_conf_data;

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

  if ((eapconf->chunk_size == 0) || (eapconf->chunk_size > MAX_CHUNK))
    eapconf->chunk_size = MAX_CHUNK;

  if (mytls_vars->handshake_done != TRUE)
    {
      if (tls_funcs_get_packet(eapdata->eap_data, eapconf->chunk_size, &res,
			       &res_size) != XENONE)
	{
	  eap_type_common_fail(eapdata);
	  return NULL;
	}
    }
  else
    {
      res = Malloc(1);
      if (res == NULL)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store "
		       "TLS ACK!\n");
	  ipc_events_malloc_failed(NULL);
	  eap_type_common_fail(eapdata);
	  return NULL;
	}
      res[0] = 0x00;
      res_size = 1;
    }

  if (res == NULL) 
    {
      eap_type_common_fail(eapdata);
      return NULL;
    }

  eaphdr = (struct eap_header *)eapdata->eapReqData;
  reqId = eaphdr->eap_identifier;

  tlsres = Malloc(res_size + sizeof(struct eap_header));
  if (tlsres == NULL) 
    {
		ipc_events_malloc_failed(NULL);
      eap_type_common_fail(eapdata);
      return NULL;
    }

  eaphdr = (struct eap_header *)tlsres;

  eaphdr->eap_code = EAP_RESPONSE_PKT;
  eaphdr->eap_identifier = reqId;
  total_size = res_size + sizeof(struct eap_header);
  eaphdr->eap_length = htons(total_size);
  eaphdr->eap_type = EAP_TYPE_TLS;

  memcpy(&tlsres[sizeof(struct eap_header)], res, res_size);

  FREE(res);

  return tlsres;
}

/*************************************************************************
 *
 * Return keying material to the caller.
 *
 *************************************************************************/
uint8_t *eaptls_getKey(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;
  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;

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

  keydata = Malloc(64);
  if (keydata == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store key "
		   "data!\n");
	  ipc_events_malloc_failed(NULL);
      return NULL;
    }

  memcpy(keydata, mytls_vars->keyblock, 64);

  return keydata;
}

/********************************************************************
 *
 * Determine if we have keying data available.
 *
 ********************************************************************/
uint8_t eaptls_isKeyAvailable(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;

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

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

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

  if (mytls_vars->handshake_done == FALSE) return FALSE;

  FREE(mytls_vars->keyblock);

  mytls_vars->keyblock = tls_funcs_gen_keyblock(mytls_vars, 
						TLS_FUNCS_CLIENT_FIRST,
						mytls_vars->sessionkeyconst,
						mytls_vars->sessionkeylen);

  if (mytls_vars->keyblock != NULL) return TRUE;

  return FALSE;
}

/********************************************************************
 *
 * Clean up TLS data.
 *
 ********************************************************************/
void eaptls_deinit(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars;

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

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

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

  FREE(mytls_vars->sessionkeyconst);
  FREE(mytls_vars);

  debug_printf(DEBUG_AUTHTYPES, "(EAP-TLS) Cleaned up.\n");
}

⌨️ 快捷键说明

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