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

📄 eapttls.c

📁 linux 下通过802.1认证的安装包
💻 C
字号:
/**
 * EAPTTLS Function implementations
 * 
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file eapttls.c
 *
 * \author chris@open1x.org
 *
 * $Id: eapttls.c,v 1.44.2.61 2008/01/21 22:51:50 chessing Exp $
 * $Date: 2008/01/21 22:51:50 $
 **/

#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 "../../frame_structs.h"
#include "../../eap_sm.h"
#include "../../eap_types/tls/eaptls.h"
#include "../../eap_types/ttls/eapttls.h"
#include "../../eap_types/ttls/ttlsphase2.h"
#include "pap.h"
#include "../../eap_types/tls/tls_funcs.h"
#include "../../eap_types/eap_type_common.h"
#include "../../ipc_callout.h"
#include "../../xsup_ipc.h"
#include "../../ipc_events.h"
#include "../../ipc_events_index.h"
#include "../tls/certificates.h"

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

/**
 *  Init the memory needed for us to complete a TTLS authentication.
 **/
int eapttls_init(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;
  struct config_eap_ttls *userdata = NULL;

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

  debug_printf(DEBUG_AUTHTYPES, "(EAP-TTLS) Initing.\n");

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

  if (userdata == NULL)
    {
      debug_printf(DEBUG_NORMAL, "EAP-TTLS setup was passed NULL userdata!  We"
		   " cannot continue with this attempt at authentication!\n");
      return XENOUSERDATA;
    }

  // First, set up the structure to hold all of our instance specific
  // variables.
  if (eapdata->eap_data == NULL)
    {
      eapdata->eap_data = (char *)Malloc(sizeof(struct tls_vars));
      if (eapdata->eap_data == NULL)
	{
	  debug_printf(DEBUG_NORMAL, "Unable to allocate memory for "
		       "eapdata->eap_data in eapttls_setup()!\n");
	  ipc_events_malloc_failed(NULL);
	  return XEMALLOC;
	}
      
      mytls_vars = (struct tls_vars *)eapdata->eap_data;
    }
  else
    {
      mytls_vars = (struct tls_vars *)eapdata->eap_data;
    }

  mytls_vars->resume = userdata->session_resume;

  if (userdata->validate_cert == FALSE)
    {
      mytls_vars->verify_cert = FALSE;
    }
  else
    {
      mytls_vars->verify_cert = TRUE;
    }

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

  mytls_vars->sessionkeyconst = (uint8_t *)_strdup(TTLS_SESSION_KEY_CONST);

  mytls_vars->sessionkeylen = TTLS_SESSION_KEY_CONST_SIZE;

  if (tls_funcs_init(mytls_vars, EAP_TYPE_TTLS) != XENONE) 
    {
      debug_printf(DEBUG_NORMAL, "Couldn't initialize SSL!\n");
      return XETLSINIT;
    }

  mytls_vars->handshake_done = FALSE;

  mytls_vars->certs_loaded &= ~ROOT_CERTS_LOADED;

  eap_type_common_init_eap_data(eapdata);

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

  return XENONE;
}

/***********************************************************************
*
*  Once we are done with this EAP method, we need to clean up the memory
*  we were using.
*
***********************************************************************/
void eapttls_deinit(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;

  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;

  // Call ttls_phase2_deinit first.
  ttls_phase2_deinit(eapdata);

  tls_funcs_deinit(mytls_vars);

  FREE(mytls_vars->sessionkeyconst);
  FREE(mytls_vars->keyblock);
  FREE(eapdata->eap_data);

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

/*****************************************************************
*
*  Check to be sure we have everything we need to complete an authentication.
*
******************************************************************/
void eapttls_check(eap_type_data *eapdata)
{
  struct config_eap_ttls *ttlsconf = NULL;
  struct tls_vars *mytls_vars = NULL;
  struct config_globals *globals = NULL;


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

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

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

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

  ttlsconf = (struct config_eap_ttls *)eapdata->eap_conf_data;

  if ((ttlsconf->user_key_pass == NULL) && (ttlsconf->user_key != NULL))
    {
      debug_printf(DEBUG_NORMAL, "No password available for TLS certificate in "
		   "EAP-TTLS phase 1!\n");
      eap_type_common_fail(eapdata);
      return;
    }

  if ((mytls_vars->certs_loaded & ROOT_CERTS_LOADED) != ROOT_CERTS_LOADED)
    {
		if (ttlsconf->validate_cert == FALSE)
		{
		  // We were told not to verify certificates.  Spew out a warning, and
		  // then do it!
		  mytls_vars->verify_cert = FALSE;

		  FREE(mytls_vars->cncheck);
	  
		  globals = config_get_globals();
	  
		  if (globals != NULL)
		    {
		      if (!TEST_FLAG(globals->flags, CONFIG_GLOBALS_NO_FRIENDLY_WARNINGS))
				{
					debug_printf(DEBUG_NORMAL, "WARNING - Verification of the Trusted Server's certificate is disabled.  The connection's security could be compromised.\n");
				}
		    }
		} else {
			mytls_vars->verify_cert = TRUE;

			if (certificates_load_root(mytls_vars, ttlsconf->trusted_server) != XENONE)
			{
				debug_printf(DEBUG_NORMAL, "Unable to load root certificate(s)!\n");
				eap_type_common_fail(eapdata);
				return;
			}

			// The stuff below should be able to go soon.
		}
      mytls_vars->certs_loaded |= ROOT_CERTS_LOADED;
    }

  if ((mytls_vars->certs_loaded & USER_CERTS_LOADED) == 0x00)
    {
      if ((ttlsconf->user_cert != NULL) && ((ttlsconf->user_key_pass != NULL)))
	{
	  debug_printf(DEBUG_NORMAL, "Using user certificate with TTLS!\n");
	  tls_funcs_load_user_cert(mytls_vars, ttlsconf->user_cert,
				   ttlsconf->user_key, 
				   ttlsconf->user_key_pass);
	}
      mytls_vars->certs_loaded |= USER_CERTS_LOADED;
    }

  // Check our phase 2 data.
  ttls_phase2_check(eapdata);
}

/******************************************************************
 *
 * Process an EAP-TTLS request, and prepare the data that is needed to
 * build a valid response packet.
 *
 ******************************************************************/
void eapttls_process(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;
  uint8_t *resbuf = NULL;
  int16_t bufsiz;
  uint16_t resout;
  struct eap_header *eaphdr = 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-TTLS) Processing.\n");

  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;

  if ((eapdata->eapReqData[sizeof(struct eap_header)] == EAPTLS_START)
      || (mytls_vars->handshake_done != TRUE))
    {
      debug_printf(DEBUG_AUTHTYPES, "(EAP-TTLS) Processing packet.\n");
      // Actually start to process the packet.
      eapdata->methodState = tls_funcs_process(eapdata->eap_data, 
					       eapdata->eapReqData);

      if ((mytls_vars->handshake_done == TRUE) && (eapdata->methodState != DONE))
		{
			// Process phase 2 data.
			debug_printf(DEBUG_AUTHTYPES, "Processing phase 2 data.\n");
			ttls_phase2_process(eapdata, NULL, 0);
		}
    }
  else
    {
      // We are in later packets of phase 2.
      eaphdr = (struct eap_header *)eapdata->eapReqData;
      resout = ntohs(eaphdr->eap_length) - sizeof(struct eap_header);

      if (tls_funcs_buffer(eapdata->eap_data,
			   &eapdata->eapReqData[sizeof(struct eap_header)],
			   resout) != XENONE)
	{
	  debug_printf(DEBUG_NORMAL, "There was an error buffering data "
		       "fragments.  Discarding fragment.\n");
	  eapdata->ignore = FALSE;
	  return;
	}

      bufsiz = tls_funcs_decrypt_ready(eapdata->eap_data);

      switch (bufsiz)
	{
	case 0:
	  // Nothing to do yet.
	  break;
	  
	case -1:
	  // Got an error.  Discard the frame.
	  eap_type_common_fail(eapdata);
	  break;

	default:
	  // Data to be decrypted.
	  resbuf = Malloc(bufsiz); 
	  if (resbuf == NULL)
	    {
	      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory needed to"
			   " store decrypted data!\n");
		  ipc_events_malloc_failed(NULL);
	      eap_type_common_fail(eapdata);
	      break;
	    }

	  resout = bufsiz;

	  if (tls_funcs_decrypt(eapdata->eap_data, resbuf, &resout) != XENONE)
	    {
	      debug_printf(DEBUG_NORMAL, "Decryption failed!\n");
	      eap_type_common_fail(eapdata);
	      break;
	    }

	  ttls_phase2_process(eapdata, resbuf, resout);
	  
	  FREE(resbuf);
	  break;
	}
    }
}

/*********************************************************************
 *
 *  Build an EAP-TTLS response message to be sent back to the authentication
 *  server.
 *
 *********************************************************************/
uint8_t *eapttls_buildResp(eap_type_data *eapdata)
{
  uint8_t *res = NULL, *ttlsres = NULL;
  uint16_t res_size = 0, total_size = 0;
  struct eap_header *eaphdr = NULL;
  uint8_t reqId;
  uint8_t resbuf[1500];
  struct tls_vars *mytls_vars = NULL;
  struct config_eap_ttls *eapconf = NULL;

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

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

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

  eapconf = eapdata->eap_conf_data;

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

  if (mytls_vars->handshake_done == TRUE)
    {
      ttls_phase2_buildResp(eapdata, (uint8_t *)&resbuf, 
			    (uint16_t *)&res_size);
      if (res_size == 0)
	{
	  // Build ACK.
	  return eap_type_common_buildAck(eapdata, EAP_TYPE_TTLS);
	}
      else
	{
	  tls_funcs_encrypt(eapdata->eap_data, resbuf, res_size);
	}
    }

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

  if (tls_funcs_get_packet(eapdata->eap_data, eapconf->chunk_size, &res,
			   &res_size) != XENONE)
    {
      return NULL;
    }

  if (res == NULL) return NULL;

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

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

  eaphdr = (struct eap_header *)ttlsres;

  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_TTLS;

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

  FREE(res);

  return ttlsres;
}

/*******************************************************************
 *
 * Check to see if the EAP method returned any useful key material.
 *
 *******************************************************************/
uint8_t eapttls_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;

  if (mytls_vars->keyblock == NULL)
    {
      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 FALSE;

  return TRUE;
}

/*********************************************************************
 *
 *  Actually get the key data and return it.
 *
 *********************************************************************/
uint8_t *eapttls_getKey(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars = NULL;
  uint8_t *keydata = NULL;

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

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

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

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

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

  return keydata;
}

⌨️ 快捷键说明

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