eap: Drop method's .probe, rename .remove

The EAP-method's .probe methods only checked the method name so do that
in eap.c instead and allocate method state in .load_settings.  Rename
method's .remove method to .free to improve the naming.
This commit is contained in:
Andrew Zaborowski 2017-09-06 04:12:17 +02:00 committed by Denis Kenzior
parent af124da544
commit 70518fad5f
9 changed files with 142 additions and 180 deletions

View File

@ -119,37 +119,7 @@ struct eap_aka_handle {
uint8_t k_re[EAP_AKA_K_RE_LEN];
};
static int eap_aka_probe(struct eap_state *eap, const char *name)
{
struct eap_aka_handle *aka;
if (strcasecmp(name, "AKA"))
return -ENOTSUP;
aka = l_new(struct eap_aka_handle, 1);
aka->type = EAP_TYPE_AKA;
eap_set_data(eap, aka);
return 0;
}
static int eap_aka_prime_probe(struct eap_state *eap, const char *name)
{
struct eap_aka_handle *aka;
if (strcasecmp(name, "AKA'"))
return -ENOTSUP;
aka = l_new(struct eap_aka_handle, 1);
aka->type = EAP_TYPE_AKA_PRIME;
eap_set_data(eap, aka);
return 0;
}
static void eap_aka_remove(struct eap_state *eap)
static void eap_aka_free(struct eap_state *eap)
{
struct eap_aka_handle *aka = eap_get_data(eap);
@ -573,11 +543,10 @@ req_error:
eap_sim_client_error(eap, aka->type, EAP_SIM_ERROR_PROCESS);
}
static bool eap_aka_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
static bool eap_aka_common_load_settings(struct eap_aka_handle *aka,
struct l_settings *settings,
const char *prefix)
{
struct eap_aka_handle *aka = eap_get_data(eap);
char setting[64];
const char *imsi;
const char *ki;
@ -630,12 +599,35 @@ static bool eap_aka_load_settings(struct eap_state *eap,
return true;
}
static bool eap_aka_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_aka_handle *aka = l_new(struct eap_aka_handle, 1);
aka->type = EAP_TYPE_AKA;
eap_set_data(eap, aka);
return eap_aka_common_load_settings(aka, settings, prefix);
}
static bool eap_aka_prime_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_aka_handle *aka = l_new(struct eap_aka_handle, 1);
aka->type = EAP_TYPE_AKA_PRIME;
eap_set_data(eap, aka);
return eap_aka_common_load_settings(aka, settings, prefix);
}
static struct eap_method eap_aka = {
.request_type = EAP_TYPE_AKA,
.exports_msk = true,
.name = "AKA",
.probe = eap_aka_probe,
.remove = eap_aka_remove,
.free = eap_aka_free,
.handle_request = eap_aka_handle_request,
.load_settings = eap_aka_load_settings,
};
@ -644,10 +636,9 @@ static struct eap_method eap_aka_prime = {
.request_type = EAP_TYPE_AKA_PRIME,
.exports_msk = true,
.name = "AKA'",
.probe = eap_aka_prime_probe,
.remove = eap_aka_remove,
.free = eap_aka_free,
.handle_request = eap_aka_handle_request,
.load_settings = eap_aka_load_settings,
.load_settings = eap_aka_prime_load_settings,
};
static int eap_aka_init(void)

View File

@ -34,21 +34,7 @@ struct eap_md5_state {
char *secret;
};
static int eap_md5_probe(struct eap_state *eap, const char *name)
{
struct eap_md5_state *md5;
if (strcasecmp(name, "MD5"))
return -ENOTSUP;
md5 = l_new(struct eap_md5_state, 1);
eap_set_data(eap, md5);
return 0;
}
static void eap_md5_remove(struct eap_state *eap)
static void eap_md5_free(struct eap_state *eap)
{
struct eap_md5_state *md5 = eap_get_data(eap);
@ -104,18 +90,22 @@ static bool eap_md5_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_md5_state *md5 = eap_get_data(eap);
struct eap_md5_state *md5;
char setting[64];
char *secret;
snprintf(setting, sizeof(setting), "%sMD5-Secret", prefix);
md5->secret = l_strdup(l_settings_get_value(settings,
"Security", setting));
secret = l_strdup(l_settings_get_value(settings, "Security", setting));
if (!md5->secret) {
if (!secret) {
l_error("EAP-MD5 secret is missing");
return false;
}
md5 = l_new(struct eap_md5_state, 1);
md5->secret = secret;
eap_set_data(eap, md5);
return true;
}
@ -124,8 +114,7 @@ static struct eap_method eap_md5 = {
.exports_msk = false,
.name = "MD5",
.probe = eap_md5_probe,
.remove = eap_md5_remove,
.free = eap_md5_free,
.handle_request = eap_md5_handle_request,
.load_settings = eap_md5_load_settings,
};

View File

@ -404,35 +404,21 @@ bool mschapv2_generate_authenticator_response(
return true;
}
static int eap_mschapv2_probe(struct eap_state *eap, const char *name)
{
struct eap_mschapv2_state *state;
if (strcasecmp(name, "MSCHAPV2"))
return -ENOTSUP;
state = l_new(struct eap_mschapv2_state, 1);
eap_set_data(eap, state);
return 0;
}
static void eap_mschapv2_free(struct eap_mschapv2_state *state)
static void eap_mschapv2_state_free(struct eap_mschapv2_state *state)
{
l_free(state->user);
l_free(state);
}
static void eap_mschapv2_remove(struct eap_state *eap)
static void eap_mschapv2_free(struct eap_state *eap)
{
struct eap_mschapv2_state *state;
state = eap_get_data(eap);
eap_set_data(eap, NULL);
eap_mschapv2_free(state);
eap_mschapv2_state_free(state);
}
static bool eap_mschapv2_send_response(struct eap_state *eap)
@ -659,16 +645,18 @@ static bool eap_mschapv2_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_mschapv2_state *state = eap_get_data(eap);
struct eap_mschapv2_state *state;
const char *password;
char setting[64];
state = l_new(struct eap_mschapv2_state, 1);
snprintf(setting, sizeof(setting), "%sIdentity", prefix);
set_user_name(state,
l_settings_get_value(settings, "Security", setting));
if (!state->user)
return false;
goto err;
state->user_len = strlen(state->user);
@ -683,7 +671,7 @@ static bool eap_mschapv2_load_settings(struct eap_state *eap,
if (len != 16) {
l_error("Read an impossible password hash");
l_free(tmp);
return false;
goto err;
}
memcpy(state->password_hash, tmp, 16);
@ -693,10 +681,18 @@ static bool eap_mschapv2_load_settings(struct eap_state *eap,
password = l_settings_get_value(settings, "Security",
setting);
if (!password || !set_password_from_string(state, password))
return false;
goto err;
}
eap_set_data(eap, state);
return true;
err:
l_free(state->user);
l_free(state);
return false;
}
static struct eap_method eap_mschapv2 = {
@ -704,8 +700,7 @@ static struct eap_method eap_mschapv2 = {
.exports_msk = true,
.name = "MSCHAPV2",
.probe = eap_mschapv2_probe,
.remove = eap_mschapv2_remove,
.free = eap_mschapv2_free,
.handle_request = eap_mschapv2_handle_request,
.load_settings = eap_mschapv2_load_settings,
};

View File

@ -125,21 +125,7 @@ struct eap_sim_handle {
bool protected : 1;
};
static int eap_sim_probe(struct eap_state *eap, const char *name)
{
struct eap_sim_handle *sim;
if (strcasecmp(name, "SIM"))
return -ENOTSUP;
sim = l_new(struct eap_sim_handle, 1);
eap_set_data(eap, sim);
return 0;
}
static void eap_sim_remove(struct eap_state *eap)
static void eap_sim_free(struct eap_state *eap)
{
struct eap_sim_handle *sim = eap_get_data(eap);
@ -577,13 +563,16 @@ static bool eap_sim_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_sim_handle *sim = eap_get_data(eap);
struct eap_sim_handle *sim;
char setting[64];
const char *kcs;
const char *imsi;
const char *sres;
size_t len;
sim = l_new(struct eap_sim_handle, 1);
eap_set_data(eap, sim);
/*
* TODO: These values will be loaded from a SIM card. Kc and SRES
* values should be kept secret and crucial to the security of EAP-SIM.
@ -620,8 +609,7 @@ static struct eap_method eap_sim = {
.request_type = EAP_TYPE_SIM,
.exports_msk = true,
.name = "SIM",
.probe = eap_sim_probe,
.remove = eap_sim_remove,
.free = eap_sim_free,
.handle_request = eap_sim_handle_request,
.load_settings = eap_sim_load_settings,
};

View File

@ -46,21 +46,7 @@ struct eap_tls_state {
bool completed;
};
static int eap_tls_probe(struct eap_state *eap, const char *name)
{
struct eap_tls_state *tls;
if (strcasecmp(name, "TLS"))
return -ENOTSUP;
tls = l_new(struct eap_tls_state, 1);
eap_set_data(eap, tls);
return 0;
}
static void eap_tls_remove(struct eap_state *eap)
static void eap_tls_free(struct eap_state *eap)
{
struct eap_tls_state *tls = eap_get_data(eap);
@ -387,9 +373,11 @@ static bool eap_tls_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_tls_state *tls = eap_get_data(eap);
struct eap_tls_state *tls;
char setting[64];
tls = l_new(struct eap_tls_state, 1);
snprintf(setting, sizeof(setting), "%sTLS-CACert", prefix);
tls->ca_cert = l_strdup(l_settings_get_value(settings,
"Security", setting));
@ -408,15 +396,26 @@ static bool eap_tls_load_settings(struct eap_state *eap,
if (!tls->client_cert && tls->client_key) {
l_error("Client key present but no client certificate");
return false;
goto err;
}
if (!tls->client_key && tls->passphrase) {
l_error("Passphrase present but no client private key");
return false;
goto err;
}
eap_set_data(eap, tls);
return true;
err:
l_free(tls->ca_cert);
l_free(tls->client_cert);
l_free(tls->client_key);
l_free(tls->passphrase);
l_free(tls);
return false;
}
static struct eap_method eap_tls = {
@ -424,8 +423,7 @@ static struct eap_method eap_tls = {
.exports_msk = true,
.name = "TLS",
.probe = eap_tls_probe,
.remove = eap_tls_remove,
.free = eap_tls_free,
.handle_request = eap_tls_handle_request,
.load_settings = eap_tls_load_settings,
};

View File

@ -51,21 +51,7 @@ struct eap_ttls_state {
uint8_t negotiated_version;
};
static int eap_ttls_probe(struct eap_state *eap, const char *name)
{
struct eap_ttls_state *ttls;
if (strcasecmp(name, "TTLS"))
return -ENOTSUP;
ttls = l_new(struct eap_ttls_state, 1);
eap_set_data(eap, ttls);
return 0;
}
static void eap_ttls_remove(struct eap_state *eap)
static void eap_ttls_free(struct eap_state *eap)
{
struct eap_ttls_state *ttls = eap_get_data(eap);
@ -648,9 +634,11 @@ static bool eap_ttls_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_ttls_state *ttls = eap_get_data(eap);
struct eap_ttls_state *ttls;
char setting[64];
ttls = l_new(struct eap_ttls_state, 1);
snprintf(setting, sizeof(setting), "%sTTLS-CACert", prefix);
ttls->ca_cert = l_strdup(l_settings_get_value(settings,
"Security", setting));
@ -670,24 +658,40 @@ static bool eap_ttls_load_settings(struct eap_state *eap,
if (!ttls->client_cert && ttls->client_key) {
l_error("Client key present but no client certificate");
return false;
goto err;
}
if (!ttls->client_key && ttls->passphrase) {
l_error("Passphrase present but no client private key");
return false;
goto err;
}
ttls->eap = eap_new(eap_ttls_eap_tx_packet,
eap_ttls_eap_complete, eap);
if (!ttls->eap) {
l_error("Could not create the TTLS inner EAP instance");
return false;
goto err;
}
snprintf(setting, sizeof(setting), "%sTTLS-Phase2-", prefix);
return eap_load_settings(ttls->eap, settings, setting);
if (!eap_load_settings(ttls->eap, settings, setting)) {
eap_free(ttls->eap);
goto err;
}
eap_set_data(eap, ttls);
return true;
err:
l_free(ttls->ca_cert);
l_free(ttls->client_cert);
l_free(ttls->client_key);
l_free(ttls->passphrase);
l_free(ttls);
return false;
}
static struct eap_method eap_ttls = {
@ -695,8 +699,7 @@ static struct eap_method eap_ttls = {
.exports_msk = true,
.name = "TTLS",
.probe = eap_ttls_probe,
.remove = eap_ttls_remove,
.free = eap_ttls_free,
.handle_request = eap_ttls_handle_request,
.load_settings = eap_ttls_load_settings,
};

View File

@ -269,21 +269,7 @@ static bool encrypted_settings_encrypt(struct eap_wsc_state *wsc,
return true;
}
static int eap_wsc_probe(struct eap_state *eap, const char *name)
{
struct eap_wsc_state *wsc;
if (strcasecmp(name, "WSC"))
return -ENOTSUP;
wsc = l_new(struct eap_wsc_state, 1);
eap_set_data(eap, wsc);
return 0;
}
static void eap_wsc_remove(struct eap_state *eap)
static void eap_wsc_free(struct eap_state *eap)
{
struct eap_wsc_state *wsc = eap_get_data(eap);
@ -1167,25 +1153,27 @@ static bool eap_wsc_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_wsc_state *wsc = eap_get_data(eap);
struct eap_wsc_state *wsc;
const char *v;
uint8_t private_key[192];
size_t len;
unsigned int u32;
const char *device_password;
wsc = l_new(struct eap_wsc_state, 1);
wsc->m1 = l_new(struct wsc_m1, 1);
wsc->m1->version2 = true;
v = l_settings_get_value(settings, "WSC", "EnrolleeMAC");
if (!v)
return false;
goto err;
if (!util_string_to_address(v, wsc->m1->addr))
return false;
goto err;
if (!wsc_uuid_from_addr(wsc->m1->addr, wsc->m1->uuid_e))
return false;
goto err;
if (!load_hexencoded(settings, "EnrolleeNonce",
wsc->m1->enrollee_nonce, 16))
@ -1198,15 +1186,15 @@ static bool eap_wsc_load_settings(struct eap_state *eap,
memset(private_key, 0, 192);
if (!wsc->private)
return false;
goto err;
len = sizeof(wsc->m1->public_key);
if (!l_key_compute_dh_public(dh5_generator, wsc->private, dh5_prime,
wsc->m1->public_key, &len))
return false;
goto err;
if (len != sizeof(wsc->m1->public_key))
return false;
goto err;
wsc->m1->auth_type_flags = WSC_AUTHENTICATION_TYPE_WPA2_PERSONAL |
WSC_AUTHENTICATION_TYPE_WPA_PERSONAL |
@ -1252,7 +1240,7 @@ static bool eap_wsc_load_settings(struct eap_state *eap,
strcpy(wsc->m1->device_name, " ");
if (!l_settings_get_uint(settings, "WSC", "RFBand", &u32))
return false;
goto err;
switch (u32) {
case WSC_RF_BAND_2_4_GHZ:
@ -1261,7 +1249,7 @@ static bool eap_wsc_load_settings(struct eap_state *eap,
wsc->m1->rf_bands = u32;
break;
default:
return false;
goto err;
}
wsc->m1->association_state = WSC_ASSOCIATION_STATE_NOT_ASSOCIATED;
@ -1285,11 +1273,11 @@ static bool eap_wsc_load_settings(struct eap_state *eap,
for (i = 0; device_password[i]; i++) {
if (!l_ascii_isxdigit(device_password[i]))
return false;
goto err;
}
if (i < 8)
return false;
goto err;
wsc->device_password = strdup(device_password);
/*
@ -1320,7 +1308,20 @@ static bool eap_wsc_load_settings(struct eap_state *eap,
if (!load_hexencoded(settings, "IV2", wsc->iv2, 16))
l_getrandom(wsc->iv2, 16);
eap_set_data(eap, wsc);
return true;
err:
l_free(wsc->device_password);
if (wsc->private)
l_key_free(wsc->private);
l_free(wsc->m1);
l_free(wsc);
return false;
}
static struct eap_method eap_wsc = {
@ -1329,8 +1330,7 @@ static struct eap_method eap_wsc = {
.request_type = EAP_TYPE_EXPANDED,
.exports_msk = true,
.name = "WSC",
.probe = eap_wsc_probe,
.remove = eap_wsc_remove,
.free = eap_wsc_free,
.handle_request = eap_wsc_handle_request,
.handle_retransmit = eap_wsc_handle_retransmit,
.load_settings = eap_wsc_load_settings,

View File

@ -87,7 +87,7 @@ void eap_set_event_func(struct eap_state *eap, eap_event_func_t func)
void eap_free(struct eap_state *eap)
{
if (eap->method_state)
eap->method->remove(eap);
eap->method->free(eap);
if (eap->identity)
l_free(eap->identity);
@ -319,7 +319,7 @@ void eap_rx_packet(struct eap_state *eap, const uint8_t *pkt, size_t len)
return;
if (eap->method_state)
eap->method->remove(eap);
eap->method->free(eap);
eap->method = NULL;
@ -351,7 +351,7 @@ bool eap_load_settings(struct eap_state *eap, struct l_settings *settings,
entry = entry->next) {
method = entry->data;
if (method->probe(eap, method_name) == 0) {
if (!strcasecmp(method_name, method->name)) {
eap->method = method;
break;
@ -387,8 +387,8 @@ bool eap_load_settings(struct eap_state *eap, struct l_settings *settings,
return true;
err:
if (eap->method->remove)
eap->method->remove(eap);
if (eap->method_state)
eap->method->free(eap);
eap->method = NULL;

View File

@ -93,12 +93,10 @@ struct eap_method {
bool exports_msk;
const char *name;
int (*probe)(struct eap_state *eap, const char *method_string);
void (*remove)(struct eap_state *eap);
bool (*load_settings)(struct eap_state *eap,
struct l_settings *settings,
const char *prefix);
void (*free)(struct eap_state *eap);
void (*handle_request)(struct eap_state *eap,
const uint8_t *pkt, size_t len);