From f95ccc102a6e55bb2543ba68164d6a007a188b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= Date: Thu, 4 Feb 2021 16:36:13 +0100 Subject: [PATCH] WPS: Reconfigure credentials on hostapd config reload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When new credentials are configured and hostapd is reconfigured using SIGHUP (or RELOAD on the ctrl_iface), also update the WPS credentials. Before these changes, when WPS is triggered the Registar always serves the credentials that were configured when hostapd started. Signed-off-by: Raphaël Mélotte --- src/ap/wps_hostapd.c | 82 +++++++++++++++++++++++++++++++++++++++++ src/wps/wps.h | 5 +++ src/wps/wps_registrar.c | 29 +++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index 867e55a0f..e97dbf996 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -1376,6 +1376,48 @@ static void hostapd_wps_nfc_clear(struct wps_context *wps) } +static int hostapd_wps_update_multi_ap(struct hostapd_data *hapd, + struct wps_registrar *reg) +{ + struct hostapd_bss_config *conf = hapd->conf; + u8 *multi_ap_backhaul_network_key = NULL; + size_t multi_ap_backhaul_network_key_len = 0; + int ret; + + if (!(conf->multi_ap & FRONTHAUL_BSS) || + !conf->multi_ap_backhaul_ssid.ssid_len) + return 0; + + if (conf->multi_ap_backhaul_ssid.wpa_passphrase) { + multi_ap_backhaul_network_key = + (u8 *) os_strdup( + conf->multi_ap_backhaul_ssid.wpa_passphrase); + if (!multi_ap_backhaul_network_key) + return -1; + multi_ap_backhaul_network_key_len = + os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase); + } else if (conf->multi_ap_backhaul_ssid.wpa_psk) { + multi_ap_backhaul_network_key = os_malloc(2 * PMK_LEN + 1); + if (!multi_ap_backhaul_network_key) + return -1; + wpa_snprintf_hex((char *) multi_ap_backhaul_network_key, + 2 * PMK_LEN + 1, + conf->multi_ap_backhaul_ssid.wpa_psk->psk, + PMK_LEN); + multi_ap_backhaul_network_key_len = 2 * PMK_LEN; + } + + ret = wps_registrar_update_multi_ap( + reg, conf->multi_ap_backhaul_ssid.ssid, + conf->multi_ap_backhaul_ssid.ssid_len, + multi_ap_backhaul_network_key, + multi_ap_backhaul_network_key_len); + os_free(multi_ap_backhaul_network_key); + + return ret; +} + + void hostapd_deinit_wps(struct hostapd_data *hapd) { eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL); @@ -1412,6 +1454,46 @@ void hostapd_update_wps(struct hostapd_data *hapd) wps->upc = conf->upc; #endif /* CONFIG_WPS_UPNP */ + os_memcpy(wps->ssid, conf->ssid.ssid, conf->ssid.ssid_len); + wps->ssid_len = conf->ssid.ssid_len; + + /* Clear WPS settings, then fill them again */ + os_free(wps->network_key); + wps->network_key = NULL; + wps->network_key_len = 0; + wps->psk_set = 0; + if (conf->ssid.wpa_psk_file) { + /* Use per-device PSKs */ + } else if (conf->ssid.wpa_passphrase) { + wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase); + if (!wps->network_key) + return; + wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase); + } else if (conf->ssid.wpa_psk) { + wps->network_key = os_malloc(2 * PMK_LEN + 1); + if (!wps->network_key) + return; + wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1, + conf->ssid.wpa_psk->psk, PMK_LEN); + wps->network_key_len = 2 * PMK_LEN; +#ifdef CONFIG_WEP + } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) { + wps->network_key = os_malloc(conf->ssid.wep.len[0]); + if (!wps->network_key) + return; + os_memcpy(wps->network_key, conf->ssid.wep.key[0], + conf->ssid.wep.len[0]); + wps->network_key_len = conf->ssid.wep.len[0]; +#endif /* CONFIG_WEP */ + } + + if (conf->ssid.wpa_psk) { + os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN); + wps->psk_set = 1; + } + + hostapd_wps_update_multi_ap(hapd, wps->registrar); + hostapd_wps_set_vendor_ext(hapd, wps); hostapd_wps_set_application_ext(hapd, wps); diff --git a/src/wps/wps.h b/src/wps/wps.h index 93888b011..6a12255c8 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -873,6 +873,11 @@ int wps_registrar_add_nfc_password_token(struct wps_registrar *reg, const u8 *oob_dev_pw, size_t oob_dev_pw_len); void wps_registrar_flush(struct wps_registrar *reg); +int wps_registrar_update_multi_ap(struct wps_registrar *reg, + const u8 *multi_ap_backhaul_ssid, + size_t multi_ap_backhaul_ssid_len, + const u8 *multi_ap_backhaul_network_key, + size_t multi_ap_backhaul_network_key_len); int wps_build_credential_wrap(struct wpabuf *msg, const struct wps_credential *cred); diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 9e1ee36da..0db936744 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -3669,6 +3669,35 @@ int wps_registrar_config_ap(struct wps_registrar *reg, } +int wps_registrar_update_multi_ap(struct wps_registrar *reg, + const u8 *multi_ap_backhaul_ssid, + size_t multi_ap_backhaul_ssid_len, + const u8 *multi_ap_backhaul_network_key, + size_t multi_ap_backhaul_network_key_len) +{ + if (multi_ap_backhaul_ssid) { + os_memcpy(reg->multi_ap_backhaul_ssid, + multi_ap_backhaul_ssid, multi_ap_backhaul_ssid_len); + reg->multi_ap_backhaul_ssid_len = multi_ap_backhaul_ssid_len; + } + + os_free(reg->multi_ap_backhaul_network_key); + reg->multi_ap_backhaul_network_key = NULL; + reg->multi_ap_backhaul_network_key_len = 0; + if (multi_ap_backhaul_network_key) { + reg->multi_ap_backhaul_network_key = + os_memdup(multi_ap_backhaul_network_key, + multi_ap_backhaul_network_key_len); + if (!reg->multi_ap_backhaul_network_key) + return -1; + reg->multi_ap_backhaul_network_key_len = + multi_ap_backhaul_network_key_len; + } + + return 0; +} + + #ifdef CONFIG_WPS_NFC int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,