From 14b9100f1c6e4b403270fb2e285daa9d130e4cfd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20M=C3=A9lotte?= Date: Thu, 4 Feb 2021 14:21:31 +0100 Subject: [PATCH] hostapd: reconfigure wps credentials on reload MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch fixes a bug that prevents updating Multi-AP credentials after hostapd has started. It was sent to upstream hostapd here: https://patchwork.ozlabs.org/bundle/rmelotte/hostapd:%20update%20WPS%20credentials%20on%20SIGHUP/ Signed-off-by: Raphaël Mélotte --- .../120-reconfigure-wps-credentials.patch | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 package/network/services/hostapd/patches/120-reconfigure-wps-credentials.patch diff --git a/package/network/services/hostapd/patches/120-reconfigure-wps-credentials.patch b/package/network/services/hostapd/patches/120-reconfigure-wps-credentials.patch new file mode 100644 index 00000000000..d9489aab367 --- /dev/null +++ b/package/network/services/hostapd/patches/120-reconfigure-wps-credentials.patch @@ -0,0 +1,187 @@ +From b389a77a0f6dccf495dbce5be9476000f6ec06a2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= +Date: Wed, 9 Dec 2020 19:55:53 +0100 +Subject: [PATCH] wps: reconfigure credentials on 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 | 86 +++++++++++++++++++++++++++++++++++++++-- + src/wps/wps.h | 6 +++ + src/wps/wps_registrar.c | 29 ++++++++++++++ + 3 files changed, 118 insertions(+), 3 deletions(-) + +diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c +index dc8aa8f65..ff942a67b 100644 +--- a/src/ap/wps_hostapd.c ++++ b/src/ap/wps_hostapd.c +@@ -1375,6 +1375,43 @@ static void hostapd_wps_nfc_clear(struct wps_context *wps) + #endif /* CONFIG_WPS_NFC */ + } + ++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 = -1; ++ ++ if ((conf->multi_ap & FRONTHAUL_BSS) && ++ conf->multi_ap_backhaul_ssid.ssid_len) { ++ 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 == NULL) ++ 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 == NULL) ++ 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) + { +@@ -1409,11 +1446,54 @@ void hostapd_update_wps(struct hostapd_data *hapd) + hapd->wps->upc = hapd->conf->upc; + #endif /* CONFIG_WPS_UPNP */ + +- hostapd_wps_set_vendor_ext(hapd, hapd->wps); +- hostapd_wps_set_application_ext(hapd, hapd->wps); ++ struct wps_context *wps = hapd->wps; ++ struct hostapd_bss_config *conf = hapd->conf; ++ ++ 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 == NULL) ++ 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 == NULL) ++ 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 == NULL) ++ 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); + + if (hapd->conf->wps_state) +- wps_registrar_update_ie(hapd->wps->registrar); ++ wps_registrar_update_ie(wps->registrar); + else + hostapd_deinit_wps(hapd); + } +diff --git a/src/wps/wps.h b/src/wps/wps.h +index 93888b011..110e3ea52 100644 +--- a/src/wps/wps.h ++++ b/src/wps/wps.h +@@ -938,6 +938,12 @@ struct wpabuf * wps_build_nfc_handover_sel_p2p(struct wps_context *ctx, + struct wpabuf *nfc_dh_pubkey, + struct wpabuf *nfc_dev_pw); + ++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); ++ + /* ndef.c */ + struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf); + struct wpabuf * ndef_build_wifi(const struct wpabuf *buf); +diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c +index 9e1ee36da..d6b27be28 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 != NULL) { ++ 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 != NULL) { ++ 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 == NULL) ++ 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, +-- +2.29.2 + -- 2.30.2