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

📄 eapsim.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * EAP-SIM implementation for Xsupplicant
 * 
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file eapsim.c
 *
 * \author chris@open1x.org
 *
 * \todo Put IPC error events in this file!
 * \todo Add UI provided username/password here.
 *
 * $Id: eapsim.c,v 1.27.2.17 2007/07/02 22:36:34 chessing Exp $
 * $Date: 2007/07/02 22:36:34 $
 **/

/*******************************************************************
 *
 * The development of the EAP/SIM support was funded by Internet
 * Foundation Austria (http://www.nic.at/ipa)
 *
 *******************************************************************/


#ifdef EAP_SIM_ENABLE     // Only build this if it has been enabled.

#include <inttypes.h>
#include <openssl/hmac.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include "xsup_common.h"
#include "winscard.h"
#include "profile.h"
#include "xsupconfig.h"
#include "eap_sm.h"
#include "eapsim.h"
#include "sm_handler.h"
#include "sim.h"
#include "xsup_debug.h"
#include "xsup_err.h"
#include "frame_structs.h"
#include "ipc_callout.h"
#include "xsup_ipc.h"
#include "eap_types/eap_type_common.h"

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

char *do_sha1(char *tohash, int size)
{
  EVP_MD_CTX ctx;
  char *hash_ret;
  int evp_ret_len;

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

  if (!xsup_assert((size > 0), "size > 0", FALSE))
    return NULL;

  hash_ret = (char *)Malloc(21);  // We should get 20 bytes returned.
  if (hash_ret == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for 'hash_ret' in "
		   "%s().\n", __FUNCTION__);
      return NULL;
    }
 
  EVP_DigestInit(&ctx, EVP_sha1());
  EVP_DigestUpdate(&ctx, tohash, size);
  EVP_DigestFinal(&ctx, hash_ret, (int *)&evp_ret_len);

  if (evp_ret_len != 20)
    {
      debug_printf(DEBUG_NORMAL, "Invalid result from OpenSSL SHA calls! "
		   "(%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  return hash_ret;
}

int eapsim_get_username()
{
  char *imsi;  
  char realm[25], card_mode=0;
  char *readers, *username;
  struct config_eap_sim *userdata;
  struct config_network *network_data;
  SCARDCONTEXT ctx;
  SCARDHANDLE hdl;

  network_data = config_get_network_config();

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

  if (!xsup_assert((network_data->methods != NULL), 
		   "network_data->methods != NULL", FALSE))
    return XEMALLOC;

  userdata = (struct config_eap_sim *)network_data->methods->method_data;

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

  // Initalize our smartcard context, and get ready to authenticate.
  if (sm_handler_init_ctx(&ctx) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't initialize smart card context!\n");
      return XESIMGENERR;
    }

  readers = sm_handler_get_readers(&ctx);
  if (readers == NULL) 
    {
      debug_printf(DEBUG_NORMAL, "Couldn't find any valid card readers!\n");
      return XESIMGENERR;
    }

  // Connect to the smart card.
  if (sm_handler_card_connect(&ctx, &hdl, readers) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error connecting to smart card reader!\n");
      return XESIMGENERR;
    }

  // Wait for up to 10 seconds for the smartcard to become ready.
  if (sm_handler_wait_card_ready(&hdl, 10) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Smart Card wasn't ready after 10 seconds!\n");
      return XESIMGENERR;
    }

  imsi = sm_handler_2g_imsi(&hdl, card_mode, userdata->password);
  if (imsi == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Error starting smart card, and getting "
		   "IMSI!\n");
      return XESIMGENERR;
    }

  debug_printf(DEBUG_AUTHTYPES, "SIM IMSI : %s\n",imsi);

  FREE(network_data->identity);

  network_data->identity = (char *)Malloc(256);  
  if (network_data->identity == NULL) 
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for identity information!  (%s:%d)\n", __FUNCTION__, __LINE__);
      return XEMALLOC;
    }

  username = network_data->identity;
  userdata->username = username;
  memset(username, 0x00, 50);

  username[0] = '1';  // An IMSI should always start with a 1.
  if (Strncpy(&username[1], 50, imsi, 18) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Attempt to overflow a buffer in %s() at %d!\n",
		  __FUNCTION__, __LINE__);
	  return XEMALLOC;
  }

  if (userdata->auto_realm == TRUE)
    {
      memset(&realm, 0x00, 25);
      sprintf((char *)&realm, "@mnc%c%c%c.mcc%c%c%c.owlan.org",
	      username[4], username[5], username[6], username[1], username[2],
	      username[3]);

      debug_printf(DEBUG_AUTHTYPES, "Realm Portion : %s\n",realm);
      if (Strcat(username, 50, realm) != 0)
	{
	  fprintf(stderr, "Refusing to overflow string!\n");
	  return XEMALLOC;
	}
    }

  // Close the smartcard, so that we know what state we are in.
  sm_handler_close_sc(&hdl, &ctx);

  FREE(imsi);
  FREE(readers);

  debug_printf(DEBUG_AUTHTYPES, "Username is now : %s\n", username);

  return XENONE;
}

/***********************************************************************
 *
 * Check to see that we are properly configured to do an EAP-SIM
 * authentication.
 *
 ***********************************************************************/
void eapsim_check(eap_type_data *eapdata)
{
  struct config_eap_sim *simconf;

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

  simconf = (struct config_eap_sim *)eapdata->eap_conf_data;

  if (simconf->password == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No PIN available for EAP-SIM!\n");
      eap_type_common_fail(eapdata);
      return;
    }
}

/***********************************************************************
 *
 * Init EAP-SIM method.
 *
 ***********************************************************************/
uint8_t eapsim_init(eap_type_data *eapdata)
{
  struct eaptypedata *simdata = NULL;
  struct config_eap_sim *userdata = NULL;
  char *imsi;

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

  if (eapdata->eap_data == NULL)
    {
      eapdata->eap_data = Malloc(sizeof(struct eaptypedata));
      if (eapdata->eap_data == NULL)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store "
		       "data for EAP-SIM!\n");
	  return FALSE;
	}
    }

  simdata = eapdata->eap_data;

  FREE(simdata->keyblock);

  if (sm_handler_init_ctx(&simdata->scntx) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't initialize smart card context!\n");
      return FALSE;
    }

  simdata->readers = sm_handler_get_readers(&simdata->scntx);
  if (simdata->readers == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't find any smart card readers "
		   "attached to the system!\n");
      return FALSE;
    }

  if (sm_handler_card_connect(&simdata->scntx, &simdata->shdl, 
			      simdata->readers) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error connecting to smart card reader!\n");
      return FALSE;
    }

  // Wait 20 seconds for the smartcard to become ready.
  if (sm_handler_wait_card_ready(&simdata->shdl, 20) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Smart Card wasn't ready after 20 "
		   "seconds!\n");
      return FALSE;
    }

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

  userdata = eapdata->eap_conf_data;

  if (userdata == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No valid EAP-SIM configuration!\n");
      return FALSE;
    }

  if (userdata->password == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No PIN available.\n");
      return FALSE;
    }

  imsi = sm_handler_2g_imsi(&simdata->shdl, simdata->card_mode,
			    userdata->password);

  if (userdata->username == NULL)
    {
      userdata->username = imsi;
    }
  else
    {
      FREE(imsi);
    }

  eap_type_common_init_eap_data(eapdata);

  return TRUE;
}

/***********************************************************************
 *
 * Process an EAP-SIM start packet.
 *
 ***********************************************************************/
void eapsim_do_start(eap_type_data *eapdata)
{
  struct eaptypedata *simdata;
  int retval, outptr = 0;
  uint16_t offset = 0, size = 0, value16 = 0;
  struct eap_header *eaphdr;
  struct config_eap_sim *simconf;
  char *username;

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

  simdata = (struct eaptypedata *)eapdata->eap_data;
  simconf = (struct config_eap_sim *)eapdata->eap_conf_data;

  if (simdata->response_data != NULL)
    {
      debug_printf(DEBUG_NORMAL, "SIM response data was not properly "
                   "deallocated!  Please check the code!\n");
      FREE(simdata->response_data);
    }

  // Allocate some memory for the request.
  simdata->response_data = Malloc(1500);
  if (simdata->response_data == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store response "
		   "data!\n");
      eap_type_common_fail(eapdata);
      return;
    }

  if (simconf->username == NULL)
    {
      username = eapdata->ident;
    }
  else
    {
      username = simconf->username;
    }

⌨️ 快捷键说明

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