📄 eapsim.c
字号:
/**
* 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 + -