DPP: Move hostapd Configurator/bootstrap data into global context

This moves the Configurator and Bootstrapping Information data from
struct hostapd_data (per-BSS) to struct hapd_interfaces (per-hostapd
process). This allows the information to be maintained over interface
restarts and shared between interfaces.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2017-11-27 13:22:32 +02:00 committed by Jouni Malinen
parent cdef4e91aa
commit 7eb6bfb45d
5 changed files with 55 additions and 25 deletions

View file

@ -3532,6 +3532,9 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
#endif /* CONFIG_DPP */ #endif /* CONFIG_DPP */
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_DPP
hostapd_dpp_deinit_global(interfaces);
#endif /* CONFIG_DPP */
} }

View file

@ -24,6 +24,7 @@
#include "ap/hostapd.h" #include "ap/hostapd.h"
#include "ap/ap_config.h" #include "ap/ap_config.h"
#include "ap/ap_drv_ops.h" #include "ap/ap_drv_ops.h"
#include "ap/dpp_hostapd.h"
#include "fst/fst.h" #include "fst/fst.h"
#include "config_file.h" #include "config_file.h"
#include "eap_register.h" #include "eap_register.h"
@ -669,6 +670,9 @@ int main(int argc, char *argv[])
#ifdef CONFIG_ETH_P_OUI #ifdef CONFIG_ETH_P_OUI
dl_list_init(&interfaces.eth_p_oui); dl_list_init(&interfaces.eth_p_oui);
#endif /* CONFIG_ETH_P_OUI */ #endif /* CONFIG_ETH_P_OUI */
#ifdef CONFIG_DPP
hostapd_dpp_init_global(&interfaces);
#endif /* CONFIG_DPP */
for (;;) { for (;;) {
c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:"); c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:");
@ -915,6 +919,10 @@ int main(int argc, char *argv[])
} }
os_free(interfaces.iface); os_free(interfaces.iface);
#ifdef CONFIG_DPP
hostapd_dpp_deinit_global(&interfaces);
#endif /* CONFIG_DPP */
if (interfaces.eloop_initialized) if (interfaces.eloop_initialized)
eloop_cancel_timeout(hostapd_periodic, &interfaces, NULL); eloop_cancel_timeout(hostapd_periodic, &interfaces, NULL);
hostapd_global_deinit(pid_file, interfaces.eloop_initialized); hostapd_global_deinit(pid_file, interfaces.eloop_initialized);

View file

@ -30,7 +30,7 @@ hostapd_dpp_configurator_get_id(struct hostapd_data *hapd, unsigned int id)
{ {
struct dpp_configurator *conf; struct dpp_configurator *conf;
dl_list_for_each(conf, &hapd->dpp_configurator, dl_list_for_each(conf, &hapd->iface->interfaces->dpp_configurator,
struct dpp_configurator, list) { struct dpp_configurator, list) {
if (conf->id == id) if (conf->id == id)
return conf; return conf;
@ -44,8 +44,8 @@ static unsigned int hapd_dpp_next_id(struct hostapd_data *hapd)
struct dpp_bootstrap_info *bi; struct dpp_bootstrap_info *bi;
unsigned int max_id = 0; unsigned int max_id = 0;
dl_list_for_each(bi, &hapd->dpp_bootstrap, struct dpp_bootstrap_info, dl_list_for_each(bi, &hapd->iface->interfaces->dpp_bootstrap,
list) { struct dpp_bootstrap_info, list) {
if (bi->id > max_id) if (bi->id > max_id)
max_id = bi->id; max_id = bi->id;
} }
@ -69,7 +69,7 @@ int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
return -1; return -1;
bi->id = hapd_dpp_next_id(hapd); bi->id = hapd_dpp_next_id(hapd);
dl_list_add(&hapd->dpp_bootstrap, &bi->list); dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list);
if (auth && auth->response_pending && if (auth && auth->response_pending &&
dpp_notify_new_qr_code(auth, bi) == 1) { dpp_notify_new_qr_code(auth, bi) == 1) {
@ -179,7 +179,7 @@ int hostapd_dpp_bootstrap_gen(struct hostapd_data *hapd, const char *cmd)
info ? "I:" : "", info ? info : "", info ? ";" : "", info ? "I:" : "", info ? info : "", info ? ";" : "",
pk); pk);
bi->id = hapd_dpp_next_id(hapd); bi->id = hapd_dpp_next_id(hapd);
dl_list_add(&hapd->dpp_bootstrap, &bi->list); dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list);
ret = bi->id; ret = bi->id;
bi = NULL; bi = NULL;
fail: fail:
@ -200,8 +200,8 @@ dpp_bootstrap_get_id(struct hostapd_data *hapd, unsigned int id)
{ {
struct dpp_bootstrap_info *bi; struct dpp_bootstrap_info *bi;
dl_list_for_each(bi, &hapd->dpp_bootstrap, struct dpp_bootstrap_info, dl_list_for_each(bi, &hapd->iface->interfaces->dpp_bootstrap,
list) { struct dpp_bootstrap_info, list) {
if (bi->id == id) if (bi->id == id)
return bi; return bi;
} }
@ -209,12 +209,12 @@ dpp_bootstrap_get_id(struct hostapd_data *hapd, unsigned int id)
} }
static int dpp_bootstrap_del(struct hostapd_data *hapd, unsigned int id) static int dpp_bootstrap_del(struct hapd_interfaces *ifaces, unsigned int id)
{ {
struct dpp_bootstrap_info *bi, *tmp; struct dpp_bootstrap_info *bi, *tmp;
int found = 0; int found = 0;
dl_list_for_each_safe(bi, tmp, &hapd->dpp_bootstrap, dl_list_for_each_safe(bi, tmp, &ifaces->dpp_bootstrap,
struct dpp_bootstrap_info, list) { struct dpp_bootstrap_info, list) {
if (id && bi->id != id) if (id && bi->id != id)
continue; continue;
@ -241,7 +241,7 @@ int hostapd_dpp_bootstrap_remove(struct hostapd_data *hapd, const char *id)
return -1; return -1;
} }
return dpp_bootstrap_del(hapd, id_val); return dpp_bootstrap_del(hapd->iface->interfaces, id_val);
} }
@ -625,8 +625,8 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
/* Try to find own and peer bootstrapping key matches based on the /* Try to find own and peer bootstrapping key matches based on the
* received hash values */ * received hash values */
dl_list_for_each(bi, &hapd->dpp_bootstrap, struct dpp_bootstrap_info, dl_list_for_each(bi, &hapd->iface->interfaces->dpp_bootstrap,
list) { struct dpp_bootstrap_info, list) {
if (!own_bi && bi->own && if (!own_bi && bi->own &&
os_memcmp(bi->pubkey_hash, r_bootstrap, os_memcmp(bi->pubkey_hash, r_bootstrap,
SHA256_MAC_LEN) == 0) { SHA256_MAC_LEN) == 0) {
@ -1274,7 +1274,7 @@ hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
dpp_bootstrap_info_free(bi); dpp_bootstrap_info_free(bi);
return; return;
} }
dl_list_add(&hapd->dpp_bootstrap, &bi->list); dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list);
} }
@ -1321,7 +1321,7 @@ hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
dpp_bootstrap_info_free(bi); dpp_bootstrap_info_free(bi);
return; return;
} }
dl_list_add(&hapd->dpp_bootstrap, &bi->list); dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list);
os_snprintf(cmd, sizeof(cmd), " peer=%u %s", os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
bi->id, bi->id,
@ -1452,7 +1452,7 @@ static unsigned int hostapd_dpp_next_configurator_id(struct hostapd_data *hapd)
struct dpp_configurator *conf; struct dpp_configurator *conf;
unsigned int max_id = 0; unsigned int max_id = 0;
dl_list_for_each(conf, &hapd->dpp_configurator, dl_list_for_each(conf, &hapd->iface->interfaces->dpp_configurator,
struct dpp_configurator, list) { struct dpp_configurator, list) {
if (conf->id > max_id) if (conf->id > max_id)
max_id = conf->id; max_id = conf->id;
@ -1486,7 +1486,7 @@ int hostapd_dpp_configurator_add(struct hostapd_data *hapd, const char *cmd)
goto fail; goto fail;
conf->id = hostapd_dpp_next_configurator_id(hapd); conf->id = hostapd_dpp_next_configurator_id(hapd);
dl_list_add(&hapd->dpp_configurator, &conf->list); dl_list_add(&hapd->iface->interfaces->dpp_configurator, &conf->list);
ret = conf->id; ret = conf->id;
conf = NULL; conf = NULL;
fail: fail:
@ -1498,12 +1498,12 @@ fail:
} }
static int dpp_configurator_del(struct hostapd_data *hapd, unsigned int id) static int dpp_configurator_del(struct hapd_interfaces *ifaces, unsigned int id)
{ {
struct dpp_configurator *conf, *tmp; struct dpp_configurator *conf, *tmp;
int found = 0; int found = 0;
dl_list_for_each_safe(conf, tmp, &hapd->dpp_configurator, dl_list_for_each_safe(conf, tmp, &ifaces->dpp_configurator,
struct dpp_configurator, list) { struct dpp_configurator, list) {
if (id && conf->id != id) if (id && conf->id != id)
continue; continue;
@ -1530,7 +1530,7 @@ int hostapd_dpp_configurator_remove(struct hostapd_data *hapd, const char *id)
return -1; return -1;
} }
return dpp_configurator_del(hapd, id_val); return dpp_configurator_del(hapd->iface->interfaces, id_val);
} }
@ -1649,8 +1649,6 @@ void hostapd_dpp_stop(struct hostapd_data *hapd)
int hostapd_dpp_init(struct hostapd_data *hapd) int hostapd_dpp_init(struct hostapd_data *hapd)
{ {
dl_list_init(&hapd->dpp_bootstrap);
dl_list_init(&hapd->dpp_configurator);
hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE; hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
hapd->dpp_init_done = 1; hapd->dpp_init_done = 1;
return 0; return 0;
@ -1670,8 +1668,6 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
if (!hapd->dpp_init_done) if (!hapd->dpp_init_done)
return; return;
dpp_bootstrap_del(hapd, 0);
dpp_configurator_del(hapd, 0);
dpp_auth_deinit(hapd->dpp_auth); dpp_auth_deinit(hapd->dpp_auth);
hapd->dpp_auth = NULL; hapd->dpp_auth = NULL;
hostapd_dpp_pkex_remove(hapd, "*"); hostapd_dpp_pkex_remove(hapd, "*");
@ -1679,3 +1675,20 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
os_free(hapd->dpp_configurator_params); os_free(hapd->dpp_configurator_params);
hapd->dpp_configurator_params = NULL; hapd->dpp_configurator_params = NULL;
} }
void hostapd_dpp_init_global(struct hapd_interfaces *ifaces)
{
dl_list_init(&ifaces->dpp_bootstrap);
dl_list_init(&ifaces->dpp_configurator);
ifaces->dpp_init_done = 1;
}
void hostapd_dpp_deinit_global(struct hapd_interfaces *ifaces)
{
if (!ifaces->dpp_init_done)
return;
dpp_bootstrap_del(ifaces, 0);
dpp_configurator_del(ifaces, 0);
}

View file

@ -33,5 +33,7 @@ int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id);
void hostapd_dpp_stop(struct hostapd_data *hapd); void hostapd_dpp_stop(struct hostapd_data *hapd);
int hostapd_dpp_init(struct hostapd_data *hapd); int hostapd_dpp_init(struct hostapd_data *hapd);
void hostapd_dpp_deinit(struct hostapd_data *hapd); void hostapd_dpp_deinit(struct hostapd_data *hapd);
void hostapd_dpp_init_global(struct hapd_interfaces *ifaces);
void hostapd_dpp_deinit_global(struct hapd_interfaces *ifaces);
#endif /* DPP_HOSTAPD_H */ #endif /* DPP_HOSTAPD_H */

View file

@ -57,6 +57,12 @@ struct hapd_interfaces {
struct dl_list eth_p_oui; /* OUI Extended EtherType handlers */ struct dl_list eth_p_oui; /* OUI Extended EtherType handlers */
#endif /* CONFIG_ETH_P_OUI */ #endif /* CONFIG_ETH_P_OUI */
int eloop_initialized; int eloop_initialized;
#ifdef CONFIG_DPP
int dpp_init_done;
struct dl_list dpp_bootstrap; /* struct dpp_bootstrap_info */
struct dl_list dpp_configurator; /* struct dpp_configurator */
#endif /* CONFIG_DPP */
}; };
enum hostapd_chan_status { enum hostapd_chan_status {
@ -338,8 +344,6 @@ struct hostapd_data {
int dhcp_sock; /* UDP socket used with the DHCP server */ int dhcp_sock; /* UDP socket used with the DHCP server */
#ifdef CONFIG_DPP #ifdef CONFIG_DPP
struct dl_list dpp_bootstrap; /* struct dpp_bootstrap_info */
struct dl_list dpp_configurator; /* struct dpp_configurator */
int dpp_init_done; int dpp_init_done;
struct dpp_authentication *dpp_auth; struct dpp_authentication *dpp_auth;
u8 dpp_allowed_roles; u8 dpp_allowed_roles;