eap_sim_db: Implement eap_sim_db_expire_pending()
Expire pending DB request for EAP-SIM/AKA/AKA'. Timeout defaults to 1 second and is user configurable in hostapd.conf (eap_sim_db_timeout). Signed-off-by: Frederic Leroy <frederic.leroy@b-com.com>
This commit is contained in:
parent
a6cc1e5747
commit
7b0f5500b0
7 changed files with 85 additions and 15 deletions
|
@ -2187,6 +2187,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
} else if (os_strcmp(buf, "eap_sim_db") == 0) {
|
} else if (os_strcmp(buf, "eap_sim_db") == 0) {
|
||||||
os_free(bss->eap_sim_db);
|
os_free(bss->eap_sim_db);
|
||||||
bss->eap_sim_db = os_strdup(pos);
|
bss->eap_sim_db = os_strdup(pos);
|
||||||
|
} else if (os_strcmp(buf, "eap_sim_db_timeout") == 0) {
|
||||||
|
bss->eap_sim_db_timeout = atoi(pos);
|
||||||
} else if (os_strcmp(buf, "eap_sim_aka_result_ind") == 0) {
|
} else if (os_strcmp(buf, "eap_sim_aka_result_ind") == 0) {
|
||||||
bss->eap_sim_aka_result_ind = atoi(pos);
|
bss->eap_sim_aka_result_ind = atoi(pos);
|
||||||
#endif /* EAP_SERVER_SIM */
|
#endif /* EAP_SERVER_SIM */
|
||||||
|
|
|
@ -832,6 +832,11 @@ eap_server=0
|
||||||
#eap_sim_db=unix:/tmp/hlr_auc_gw.sock
|
#eap_sim_db=unix:/tmp/hlr_auc_gw.sock
|
||||||
#eap_sim_db=unix:/tmp/hlr_auc_gw.sock db=/tmp/hostapd.db
|
#eap_sim_db=unix:/tmp/hlr_auc_gw.sock db=/tmp/hostapd.db
|
||||||
|
|
||||||
|
# EAP-SIM DB request timeout
|
||||||
|
# This parameter sets the maximum time to wait for a database request response.
|
||||||
|
# The parameter value is in seconds.
|
||||||
|
#eap_sim_db_timeout=1
|
||||||
|
|
||||||
# Encryption key for EAP-FAST PAC-Opaque values. This key must be a secret,
|
# Encryption key for EAP-FAST PAC-Opaque values. This key must be a secret,
|
||||||
# random value. It is configured as a 16-octet value in hex format. It can be
|
# random value. It is configured as a 16-octet value in hex format. It can be
|
||||||
# generated, e.g., with the following command:
|
# generated, e.g., with the following command:
|
||||||
|
|
|
@ -65,6 +65,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
||||||
bss->dtim_period = 2;
|
bss->dtim_period = 2;
|
||||||
|
|
||||||
bss->radius_server_auth_port = 1812;
|
bss->radius_server_auth_port = 1812;
|
||||||
|
bss->eap_sim_db_timeout = 1;
|
||||||
bss->ap_max_inactivity = AP_MAX_INACTIVITY;
|
bss->ap_max_inactivity = AP_MAX_INACTIVITY;
|
||||||
bss->eapol_version = EAPOL_VERSION;
|
bss->eapol_version = EAPOL_VERSION;
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,7 @@ struct hostapd_bss_config {
|
||||||
struct hostapd_eap_user *eap_user;
|
struct hostapd_eap_user *eap_user;
|
||||||
char *eap_user_sqlite;
|
char *eap_user_sqlite;
|
||||||
char *eap_sim_db;
|
char *eap_sim_db;
|
||||||
|
unsigned int eap_sim_db_timeout;
|
||||||
int eap_server_erp; /* Whether ERP is enabled on internal EAP server */
|
int eap_server_erp; /* Whether ERP is enabled on internal EAP server */
|
||||||
struct hostapd_ip_addr own_ip_addr;
|
struct hostapd_ip_addr own_ip_addr;
|
||||||
char *nas_identifier;
|
char *nas_identifier;
|
||||||
|
|
|
@ -193,6 +193,7 @@ int authsrv_init(struct hostapd_data *hapd)
|
||||||
if (hapd->conf->eap_sim_db) {
|
if (hapd->conf->eap_sim_db) {
|
||||||
hapd->eap_sim_db_priv =
|
hapd->eap_sim_db_priv =
|
||||||
eap_sim_db_init(hapd->conf->eap_sim_db,
|
eap_sim_db_init(hapd->conf->eap_sim_db,
|
||||||
|
hapd->conf->eap_sim_db_timeout,
|
||||||
hostapd_sim_db_cb, hapd);
|
hostapd_sim_db_cb, hapd);
|
||||||
if (hapd->eap_sim_db_priv == NULL) {
|
if (hapd->eap_sim_db_priv == NULL) {
|
||||||
wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
|
wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct eap_sim_db_data {
|
||||||
struct eap_sim_pseudonym *pseudonyms;
|
struct eap_sim_pseudonym *pseudonyms;
|
||||||
struct eap_sim_reauth *reauths;
|
struct eap_sim_reauth *reauths;
|
||||||
struct eap_sim_db_pending *pending;
|
struct eap_sim_db_pending *pending;
|
||||||
|
unsigned int eap_sim_db_timeout;
|
||||||
#ifdef CONFIG_SQLITE
|
#ifdef CONFIG_SQLITE
|
||||||
sqlite3 *sqlite_db;
|
sqlite3 *sqlite_db;
|
||||||
char db_tmp_identity[100];
|
char db_tmp_identity[100];
|
||||||
|
@ -76,6 +77,10 @@ struct eap_sim_db_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void eap_sim_db_del_timeout(void *eloop_ctx, void *user_ctx);
|
||||||
|
static void eap_sim_db_query_timeout(void *eloop_ctx, void *user_ctx);
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_SQLITE
|
#ifdef CONFIG_SQLITE
|
||||||
|
|
||||||
static int db_table_exists(sqlite3 *db, const char *name)
|
static int db_table_exists(sqlite3 *db, const char *name)
|
||||||
|
@ -397,6 +402,57 @@ static void eap_sim_db_add_pending(struct eap_sim_db_data *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void eap_sim_db_free_pending(struct eap_sim_db_data *data,
|
||||||
|
struct eap_sim_db_pending *entry)
|
||||||
|
{
|
||||||
|
eloop_cancel_timeout(eap_sim_db_query_timeout, data, entry);
|
||||||
|
eloop_cancel_timeout(eap_sim_db_del_timeout, data, entry);
|
||||||
|
os_free(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void eap_sim_db_del_pending(struct eap_sim_db_data *data,
|
||||||
|
struct eap_sim_db_pending *entry)
|
||||||
|
{
|
||||||
|
struct eap_sim_db_pending **pp = &data->pending;
|
||||||
|
|
||||||
|
while (*pp != NULL) {
|
||||||
|
if (*pp == entry) {
|
||||||
|
*pp = entry->next;
|
||||||
|
eap_sim_db_free_pending(data, entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pp = &(*pp)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void eap_sim_db_del_timeout(void *eloop_ctx, void *user_ctx)
|
||||||
|
{
|
||||||
|
struct eap_sim_db_data *data = eloop_ctx;
|
||||||
|
struct eap_sim_db_pending *entry = user_ctx;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Delete query timeout for %p", entry);
|
||||||
|
eap_sim_db_del_pending(data, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void eap_sim_db_query_timeout(void *eloop_ctx, void *user_ctx)
|
||||||
|
{
|
||||||
|
struct eap_sim_db_data *data = eloop_ctx;
|
||||||
|
struct eap_sim_db_pending *entry = user_ctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Report failure and allow some time for EAP server to process it
|
||||||
|
* before deleting the query.
|
||||||
|
*/
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Query timeout for %p", entry);
|
||||||
|
entry->state = FAILURE;
|
||||||
|
data->get_complete_cb(data->ctx, entry->cb_session_ctx);
|
||||||
|
eloop_register_timeout(1, 0, eap_sim_db_del_timeout, data, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data,
|
static void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data,
|
||||||
const char *imsi, char *buf)
|
const char *imsi, char *buf)
|
||||||
{
|
{
|
||||||
|
@ -472,7 +528,7 @@ static void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data,
|
||||||
|
|
||||||
parse_fail:
|
parse_fail:
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
|
||||||
os_free(entry);
|
eap_sim_db_free_pending(data, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -563,7 +619,7 @@ static void eap_sim_db_aka_resp_auth(struct eap_sim_db_data *data,
|
||||||
|
|
||||||
parse_fail:
|
parse_fail:
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
|
||||||
os_free(entry);
|
eap_sim_db_free_pending(data, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,12 +746,13 @@ static void eap_sim_db_close_socket(struct eap_sim_db_data *data)
|
||||||
/**
|
/**
|
||||||
* eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface
|
* eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface
|
||||||
* @config: Configuration data (e.g., file name)
|
* @config: Configuration data (e.g., file name)
|
||||||
|
* @db_timeout: Database lookup timeout
|
||||||
* @get_complete_cb: Callback function for reporting availability of triplets
|
* @get_complete_cb: Callback function for reporting availability of triplets
|
||||||
* @ctx: Context pointer for get_complete_cb
|
* @ctx: Context pointer for get_complete_cb
|
||||||
* Returns: Pointer to a private data structure or %NULL on failure
|
* Returns: Pointer to a private data structure or %NULL on failure
|
||||||
*/
|
*/
|
||||||
struct eap_sim_db_data *
|
struct eap_sim_db_data *
|
||||||
eap_sim_db_init(const char *config,
|
eap_sim_db_init(const char *config, unsigned int db_timeout,
|
||||||
void (*get_complete_cb)(void *ctx, void *session_ctx),
|
void (*get_complete_cb)(void *ctx, void *session_ctx),
|
||||||
void *ctx)
|
void *ctx)
|
||||||
{
|
{
|
||||||
|
@ -709,6 +766,7 @@ eap_sim_db_init(const char *config,
|
||||||
data->sock = -1;
|
data->sock = -1;
|
||||||
data->get_complete_cb = get_complete_cb;
|
data->get_complete_cb = get_complete_cb;
|
||||||
data->ctx = ctx;
|
data->ctx = ctx;
|
||||||
|
data->eap_sim_db_timeout = db_timeout;
|
||||||
data->fname = os_strdup(config);
|
data->fname = os_strdup(config);
|
||||||
if (data->fname == NULL)
|
if (data->fname == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -796,7 +854,7 @@ void eap_sim_db_deinit(void *priv)
|
||||||
while (pending) {
|
while (pending) {
|
||||||
prev_pending = pending;
|
prev_pending = pending;
|
||||||
pending = pending->next;
|
pending = pending->next;
|
||||||
os_free(prev_pending);
|
eap_sim_db_free_pending(data, prev_pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
os_free(data);
|
os_free(data);
|
||||||
|
@ -833,11 +891,11 @@ static int eap_sim_db_send(struct eap_sim_db_data *data, const char *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void eap_sim_db_expire_pending(struct eap_sim_db_data *data)
|
static void eap_sim_db_expire_pending(struct eap_sim_db_data *data,
|
||||||
|
struct eap_sim_db_pending *entry)
|
||||||
{
|
{
|
||||||
/* TODO: add limit for maximum length for pending list; remove latest
|
eloop_register_timeout(data->eap_sim_db_timeout, 0,
|
||||||
* (i.e., last) entry from the list if the limit is reached; could also
|
eap_sim_db_query_timeout, data, entry);
|
||||||
* use timeout to expire pending entries */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -891,7 +949,7 @@ int eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data,
|
||||||
if (entry->state == FAILURE) {
|
if (entry->state == FAILURE) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
|
||||||
"failure");
|
"failure");
|
||||||
os_free(entry);
|
eap_sim_db_free_pending(data, entry);
|
||||||
return EAP_SIM_DB_FAILURE;
|
return EAP_SIM_DB_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,7 +969,7 @@ int eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data,
|
||||||
os_memcpy(sres, entry->u.sim.sres,
|
os_memcpy(sres, entry->u.sim.sres,
|
||||||
num_chal * EAP_SIM_SRES_LEN);
|
num_chal * EAP_SIM_SRES_LEN);
|
||||||
os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
|
os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
|
||||||
os_free(entry);
|
eap_sim_db_free_pending(data, entry);
|
||||||
return num_chal;
|
return num_chal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,7 +1003,8 @@ int eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data,
|
||||||
entry->cb_session_ctx = cb_session_ctx;
|
entry->cb_session_ctx = cb_session_ctx;
|
||||||
entry->state = PENDING;
|
entry->state = PENDING;
|
||||||
eap_sim_db_add_pending(data, entry);
|
eap_sim_db_add_pending(data, entry);
|
||||||
eap_sim_db_expire_pending(data);
|
eap_sim_db_expire_pending(data, entry);
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry);
|
||||||
|
|
||||||
return EAP_SIM_DB_PENDING;
|
return EAP_SIM_DB_PENDING;
|
||||||
}
|
}
|
||||||
|
@ -1356,7 +1415,7 @@ int eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username,
|
||||||
entry = eap_sim_db_get_pending(data, imsi, 1);
|
entry = eap_sim_db_get_pending(data, imsi, 1);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
if (entry->state == FAILURE) {
|
if (entry->state == FAILURE) {
|
||||||
os_free(entry);
|
eap_sim_db_free_pending(data, entry);
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure");
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure");
|
||||||
return EAP_SIM_DB_FAILURE;
|
return EAP_SIM_DB_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -1375,7 +1434,7 @@ int eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username,
|
||||||
os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
|
os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
|
||||||
os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
|
os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
|
||||||
*res_len = entry->u.aka.res_len;
|
*res_len = entry->u.aka.res_len;
|
||||||
os_free(entry);
|
eap_sim_db_free_pending(data, entry);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1406,7 +1465,8 @@ int eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username,
|
||||||
entry->cb_session_ctx = cb_session_ctx;
|
entry->cb_session_ctx = cb_session_ctx;
|
||||||
entry->state = PENDING;
|
entry->state = PENDING;
|
||||||
eap_sim_db_add_pending(data, entry);
|
eap_sim_db_add_pending(data, entry);
|
||||||
eap_sim_db_expire_pending(data);
|
eap_sim_db_expire_pending(data, entry);
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry);
|
||||||
|
|
||||||
return EAP_SIM_DB_PENDING;
|
return EAP_SIM_DB_PENDING;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ enum eap_sim_db_method {
|
||||||
struct eap_sim_db_data;
|
struct eap_sim_db_data;
|
||||||
|
|
||||||
struct eap_sim_db_data *
|
struct eap_sim_db_data *
|
||||||
eap_sim_db_init(const char *config,
|
eap_sim_db_init(const char *config, unsigned int db_timeout,
|
||||||
void (*get_complete_cb)(void *ctx, void *session_ctx),
|
void (*get_complete_cb)(void *ctx, void *session_ctx),
|
||||||
void *ctx);
|
void *ctx);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue