From 0d189171e13b0e6a1131ebe312d27359b8963b85 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 30 Oct 2025 19:38:56 +0000 Subject: [PATCH] wpa_supplicant: move per-interface ubus object to ucode Remove previous implementation Signed-off-by: Felix Fietkau --- .../services/hostapd/files/wpa_supplicant.uc | 63 +++ .../hostapd/patches/600-ubus_support.patch | 105 ---- .../hostapd/patches/601-ucode_support.patch | 510 +++++++++--------- .../hostapd/src/wpa_supplicant/ubus.c | 280 ---------- .../hostapd/src/wpa_supplicant/ubus.h | 55 -- .../hostapd/src/wpa_supplicant/ucode.c | 58 ++ .../hostapd/src/wpa_supplicant/ucode.h | 8 + 7 files changed, 384 insertions(+), 695 deletions(-) delete mode 100644 package/network/services/hostapd/src/wpa_supplicant/ubus.c delete mode 100644 package/network/services/hostapd/src/wpa_supplicant/ubus.h diff --git a/package/network/services/hostapd/files/wpa_supplicant.uc b/package/network/services/hostapd/files/wpa_supplicant.uc index b2a61090f3..b77e0648e9 100644 --- a/package/network/services/hostapd/files/wpa_supplicant.uc +++ b/package/network/services/hostapd/files/wpa_supplicant.uc @@ -16,6 +16,7 @@ libubus.guard(ex_handler); wpas.data.mld = {}; wpas.data.config = {}; wpas.data.iface_phy = {}; +wpas.data.iface_ubus = {}; wpas.data.macaddr_list = {}; function iface_stop(iface) @@ -720,6 +721,62 @@ function iface_channel_switch(ifname, iface, info) ubus.call("hostapd", "apsta_state", msg); } +function iface_ubus_remove(ifname) +{ + let obj = wpas.data.iface_ubus[ifname]; + if (!obj) + return; + + obj.remove(); + delete wpas.data.iface_ubus[ifname]; +} + +function iface_ubus_add(ifname) +{ + let ubus = wpas.data.ubus; + + iface_ubus_remove(ifname); + + let obj = ubus.publish(`wpa_supplicant.${ifname}`, { + reload: { + args: {}, + call: (req) => { + let iface = wpas.interfaces[ifname]; + if (!iface) + return libubus.STATUS_NOT_FOUND; + + iface.ctrl("RECONFIGURE"); + return 0; + }, + }, + wps_start: { + args: { + multi_ap: true + }, + call: (req) => { + let iface = wpas.interfaces[ifname]; + if (!iface) + return libubus.STATUS_NOT_FOUND; + + iface.ctrl(`WPS_PBC multi_ap=${+req.args.multi_ap}`); + return 0; + }, + }, + wps_cancel: { + args: {}, + call: (req) => { + let iface = wpas.interfaces[ifname]; + if (!iface) + return libubus.STATUS_NOT_FOUND; + + iface.ctrl("WPS_CANCEL"); + return 0; + }, + }, + }); + wpas.data.iface_ubus[ifname] = obj; +} + return { shutdown: function() { for (let phy in wpas.data.config) @@ -734,10 +791,12 @@ return { return mld_bss_allowed(mld, bss); }, iface_add: function(name, obj) { + iface_ubus_add(name); iface_event("add", name); }, iface_remove: function(name, obj) { iface_event("remove", name); + iface_ubus_remove(name); }, state: function(ifname, iface, state) { let event_data = iface.status(); @@ -773,5 +832,9 @@ return { event: function(ifname, iface, ev, info) { if (ev == "CH_SWITCH_STARTED") iface_channel_switch(ifname, iface, info); + }, + wps_credentials: function(ifname, iface, cred) { + cred.ifname = ifname; + ubus.event("wps_credentials", cred); } }; diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index 66cc75f37d..0c132b9d27 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -636,32 +636,6 @@ probe/assoc/auth requests via object subscribe. + + eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); +} ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -191,6 +191,13 @@ ifdef CONFIG_EAPOL_TEST - CFLAGS += -Werror -DEAPOL_TEST - endif - -+ifdef CONFIG_UBUS -+CFLAGS += -DUBUS_SUPPORT -+OBJS += ubus.o -+OBJS += ../src/utils/uloop.o -+LIBS += -lubox -lubus -+endif -+ - ifdef CONFIG_CODE_COVERAGE - CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE - LIBS += -lgcov -@@ -1046,6 +1053,9 @@ ifdef CONFIG_CTRL_IFACE_MIB - CFLAGS += -DCONFIG_CTRL_IFACE_MIB - endif - OBJS += ../src/ap/ctrl_iface_ap.o -+ifdef CONFIG_UBUS -+OBJS += ../src/ap/ubus.o -+endif - endif - - CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY --- a/wpa_supplicant/main.c +++ b/wpa_supplicant/main.c @@ -203,7 +203,7 @@ int main(int argc, char *argv[]) @@ -683,82 +657,3 @@ probe/assoc/auth requests via object subscribe. case 'o': params.override_driver = optarg; break; ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -8289,6 +8289,8 @@ struct wpa_supplicant * wpa_supplicant_a - } - #endif /* CONFIG_P2P */ - -+ wpas_ubus_add_bss(wpa_s); -+ - return wpa_s; - } - -@@ -8315,6 +8317,8 @@ int wpa_supplicant_remove_iface(struct w - struct wpa_supplicant *parent = wpa_s->parent; - #endif /* CONFIG_MESH */ - -+ wpas_ubus_free_bss(wpa_s); -+ - /* Remove interface from the global list of interfaces */ - prev = global->ifaces; - if (prev == wpa_s) { -@@ -8661,8 +8665,12 @@ int wpa_supplicant_run(struct wpa_global - eloop_register_signal_terminate(wpa_supplicant_terminate, global); - eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); - -+ wpas_ubus_add(global); -+ - eloop_run(); - -+ wpas_ubus_free(global); -+ - return 0; - } - ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -21,6 +21,7 @@ - #include "config_ssid.h" - #include "wmm_ac.h" - #include "pasn/pasn_common.h" -+#include "ubus.h" - - extern const char *const wpa_supplicant_version; - extern const char *const wpa_supplicant_license; -@@ -319,6 +320,8 @@ struct wpa_global { - #endif /* CONFIG_WIFI_DISPLAY */ - - struct psk_list_entry *add_psk; /* From group formation */ -+ -+ struct ubus_object ubus_global; - }; - - -@@ -697,6 +700,7 @@ struct wpa_supplicant { - unsigned char own_addr[ETH_ALEN]; - unsigned char perm_addr[ETH_ALEN]; - char ifname[100]; -+ struct wpas_ubus_bss ubus; - #ifdef CONFIG_MATCH_IFACE - int matched; - #endif /* CONFIG_MATCH_IFACE */ ---- a/wpa_supplicant/wps_supplicant.c -+++ b/wpa_supplicant/wps_supplicant.c -@@ -33,6 +33,7 @@ - #include "p2p/p2p.h" - #include "p2p_supplicant.h" - #include "wps_supplicant.h" -+#include "ubus.h" - - - #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG -@@ -401,6 +402,8 @@ static int wpa_supplicant_wps_cred(void - wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", - cred->cred_attr, cred->cred_attr_len); - -+ wpas_ubus_notify(wpa_s, cred); -+ - if (wpa_s->conf->wps_cred_processing == 1) - return 0; - diff --git a/package/network/services/hostapd/patches/601-ucode_support.patch b/package/network/services/hostapd/patches/601-ucode_support.patch index 7bbf781275..f72f2601c3 100644 --- a/package/network/services/hostapd/patches/601-ucode_support.patch +++ b/package/network/services/hostapd/patches/601-ucode_support.patch @@ -6,6 +6,104 @@ This implements vastly improved dynamic configuration reload support. It can handle configuration changes on individual wifi interfaces, as well as adding/removing interfaces. +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1278,6 +1278,7 @@ void wpa_supplicant_set_state(struct wpa + sme_sched_obss_scan(wpa_s, 0); + } + wpa_s->wpa_state = state; ++ wpas_ucode_update_state(wpa_s); + + #ifndef CONFIG_NO_ROBUST_AV + if (state == WPA_COMPLETED && dl_list_len(&wpa_s->active_scs_ids) && +@@ -8289,6 +8290,8 @@ struct wpa_supplicant * wpa_supplicant_a + } + #endif /* CONFIG_P2P */ + ++ wpas_ucode_add_bss(wpa_s); ++ + return wpa_s; + } + +@@ -8315,6 +8318,8 @@ int wpa_supplicant_remove_iface(struct w + struct wpa_supplicant *parent = wpa_s->parent; + #endif /* CONFIG_MESH */ + ++ wpas_ucode_free_bss(wpa_s); ++ + /* Remove interface from the global list of interfaces */ + prev = global->ifaces; + if (prev == wpa_s) { +@@ -8623,6 +8628,7 @@ struct wpa_global * wpa_supplicant_init( + + eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, + wpas_periodic, global, NULL); ++ wpas_ucode_init(global); + + return global; + } +@@ -8695,6 +8701,8 @@ void wpa_supplicant_deinit(struct wpa_gl + + wpas_notify_supplicant_deinitialized(global); + ++ wpas_ucode_free(); ++ + eap_peer_unregister_methods(); + #ifdef CONFIG_AP + eap_server_unregister_methods(); +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h +@@ -15,12 +15,14 @@ + #include "common/sae.h" + #include "common/wpa_ctrl.h" + #include "common/dpp.h" ++#include "common/ieee802_11_common.h" + #include "crypto/sha384.h" + #include "eapol_supp/eapol_supp_sm.h" + #include "wps/wps_defs.h" + #include "config_ssid.h" + #include "wmm_ac.h" + #include "pasn/pasn_common.h" ++#include "ucode.h" + + extern const char *const wpa_supplicant_version; + extern const char *const wpa_supplicant_license; +@@ -697,6 +699,7 @@ struct wpa_supplicant { + unsigned char own_addr[ETH_ALEN]; + unsigned char perm_addr[ETH_ALEN]; + char ifname[100]; ++ struct wpas_ucode_bss ucode; + #ifdef CONFIG_MATCH_IFACE + int matched; + #endif /* CONFIG_MATCH_IFACE */ +@@ -1564,6 +1567,8 @@ struct wpa_supplicant { + unsigned int enabled_4addr_mode:1; + unsigned int multi_bss_support:1; + unsigned int drv_authorized_port:1; ++ ++ struct multi_ap_params multi_ap; + unsigned int multi_ap_ie:1; + unsigned int multi_ap_backhaul:1; + unsigned int multi_ap_fronthaul:1; +--- a/wpa_supplicant/wps_supplicant.c ++++ b/wpa_supplicant/wps_supplicant.c +@@ -33,6 +33,7 @@ + #include "p2p/p2p.h" + #include "p2p_supplicant.h" + #include "wps_supplicant.h" ++#include "ucode.h" + + + #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG +@@ -401,6 +402,8 @@ static int wpa_supplicant_wps_cred(void + wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", + cred->cred_attr, cred->cred_attr_len); + ++ wpas_ucode_wps_complete(wpa_s, cred); ++ + if (wpa_s->conf->wps_cred_processing == 1) + return 0; + --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -169,9 +169,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm. @@ -310,6 +408,152 @@ as adding/removing interfaces. void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -659,12 +659,17 @@ const char * sae_get_password(struct hos + struct sae_pt **s_pt, + const struct sae_pk **s_pk) + { ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct hostapd_ssid *ssid = &conf->ssid; + const char *password = NULL; +- struct sae_password_entry *pw; ++ struct sae_password_entry *pw = NULL; + struct sae_pt *pt = NULL; + const struct sae_pk *pk = NULL; + struct hostapd_sta_wpa_psk_short *psk = NULL; + ++ if (sta && sta->use_sta_psk) ++ goto use_sta_psk; ++ + /* With sae_track_password functionality enabled, try to first find the + * next viable wildcard-address password if a password identifier was + * not used. Select an wildcard-addr entry if the STA is known to have +@@ -725,12 +730,30 @@ const char * sae_get_password(struct hos + pt = hapd->conf->ssid.pt; + } + ++use_sta_psk: + if (!password && sta && !rx_id) { + for (psk = sta->psk; psk; psk = psk->next) { +- if (psk->is_passphrase) { +- password = psk->passphrase; ++ if (!psk->is_passphrase) ++ continue; ++ ++ password = psk->passphrase; ++ if (!sta->use_sta_psk) ++ break; ++ ++#ifdef CONFIG_SAE ++ if (sta->sae_pt) { ++ pt = sta->sae_pt; + break; + } ++ ++ pt = sae_derive_pt(conf->sae_groups, ssid->ssid, ++ ssid->ssid_len, ++ (const u8 *) password, ++ os_strlen(password), ++ NULL); ++ sta->sae_pt = pt; ++ break; ++#endif + } + } + +@@ -3489,6 +3512,12 @@ static void handle_auth(struct hostapd_d + goto fail; + } + ++ res = hostapd_ucode_sta_auth(hapd, sta); ++ if (res) { ++ resp = res; ++ goto fail; ++ } ++ + sta->flags &= ~WLAN_STA_PREAUTH; + ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); + +--- a/src/ap/sta_info.c ++++ b/src/ap/sta_info.c +@@ -477,6 +477,11 @@ void ap_free_sta(struct hostapd_data *ha + forced_memzero(sta->last_tk, WPA_TK_MAX_LEN); + #endif /* CONFIG_TESTING_OPTIONS */ + ++#ifdef CONFIG_SAE ++ if (sta->sae_pt) ++ sae_deinit_pt(sta->sae_pt); ++#endif ++ + os_free(sta); + } + +@@ -1576,6 +1581,8 @@ void ap_sta_set_authorized_event(struct + #endif /* CONFIG_P2P */ + const u8 *ip_ptr = NULL; + ++ if (authorized) ++ hostapd_ucode_sta_connected(hapd, sta); + #ifdef CONFIG_P2P + if (hapd->p2p_group == NULL) { + if (sta->p2p_ie != NULL && +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -180,6 +180,9 @@ struct sta_info { + int vlan_id_bound; /* updated by ap_sta_bind_vlan() */ + /* PSKs from RADIUS authentication server */ + struct hostapd_sta_wpa_psk_short *psk; ++ struct sae_pt *sae_pt; ++ int use_sta_psk; ++ int psk_idx; + + char *identity; /* User-Name from RADIUS */ + char *radius_cui; /* Chargeable-User-Identity from RADIUS */ +--- a/src/ap/wpa_auth_glue.c ++++ b/src/ap/wpa_auth_glue.c +@@ -392,6 +392,7 @@ static const u8 * hostapd_wpa_auth_get_p + struct sta_info *sta = ap_get_sta(hapd, addr); + const u8 *psk; + ++ sta->psk_idx = 0; + if (vlan_id) + *vlan_id = 0; + if (psk_len) +@@ -442,13 +443,18 @@ static const u8 * hostapd_wpa_auth_get_p + * returned psk which should not be returned again. + * logic list (all hostapd_get_psk; all sta->psk) + */ ++ if (sta && sta->use_sta_psk) ++ psk = NULL; + if (sta && sta->psk && !psk) { + struct hostapd_sta_wpa_psk_short *pos; ++ int psk_idx = 1; + + if (vlan_id) + *vlan_id = 0; + psk = sta->psk->psk; +- for (pos = sta->psk; pos; pos = pos->next) { ++ if (vlan_id) ++ sta->psk_idx = psk_idx; ++ for (pos = sta->psk; pos; pos = pos->next, psk_idx++) { + if (pos->is_passphrase) { + if (pbkdf2_sha1(pos->passphrase, + hapd->conf->ssid.ssid, +@@ -462,9 +468,13 @@ static const u8 * hostapd_wpa_auth_get_p + } + if (pos->psk == prev_psk) { + psk = pos->next ? pos->next->psk : NULL; ++ if (vlan_id) ++ sta->psk_idx = psk_idx + 1; + break; + } + } ++ if (vlan_id && !psk) ++ sta->psk_idx = 0; + } + return psk; + } --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4072,6 +4072,25 @@ struct wpa_driver_ops { @@ -668,32 +912,25 @@ as adding/removing interfaces. extern int wpa_debug_timestamp; --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -194,8 +194,20 @@ endif - ifdef CONFIG_UBUS - CFLAGS += -DUBUS_SUPPORT - OBJS += ubus.o -+LIBS += -lubus -+NEED_ULOOP:=y -+endif -+ +@@ -191,6 +191,14 @@ ifdef CONFIG_EAPOL_TEST + CFLAGS += -Werror -DEAPOL_TEST + endif + +ifdef CONFIG_UCODE +CFLAGS += -DUCODE_SUPPORT +OBJS += ../src/utils/ucode.o ++OBJS += ../src/utils/uloop.o +OBJS += ucode.o -+NEED_ULOOP:=y ++LIBS += -lubox +endif + -+ifdef NEED_ULOOP - OBJS += ../src/utils/uloop.o --LIBS += -lubox -lubus -+LIBS += -lubox - endif - ifdef CONFIG_CODE_COVERAGE -@@ -1056,6 +1068,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o - ifdef CONFIG_UBUS - OBJS += ../src/ap/ubus.o + CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE + LIBS += -lgcov +@@ -1046,6 +1054,9 @@ ifdef CONFIG_CTRL_IFACE_MIB + CFLAGS += -DCONFIG_CTRL_IFACE_MIB endif + OBJS += ../src/ap/ctrl_iface_ap.o +ifdef CONFIG_UCODE +OBJS += ../src/ap/ucode.o +endif @@ -758,240 +995,3 @@ as adding/removing interfaces. switch (event) { case EVENT_AUTH: #ifdef CONFIG_FST ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -1278,6 +1278,7 @@ void wpa_supplicant_set_state(struct wpa - sme_sched_obss_scan(wpa_s, 0); - } - wpa_s->wpa_state = state; -+ wpas_ucode_update_state(wpa_s); - - #ifndef CONFIG_NO_ROBUST_AV - if (state == WPA_COMPLETED && dl_list_len(&wpa_s->active_scs_ids) && -@@ -8290,6 +8291,7 @@ struct wpa_supplicant * wpa_supplicant_a - #endif /* CONFIG_P2P */ - - wpas_ubus_add_bss(wpa_s); -+ wpas_ucode_add_bss(wpa_s); - - return wpa_s; - } -@@ -8317,6 +8319,7 @@ int wpa_supplicant_remove_iface(struct w - struct wpa_supplicant *parent = wpa_s->parent; - #endif /* CONFIG_MESH */ - -+ wpas_ucode_free_bss(wpa_s); - wpas_ubus_free_bss(wpa_s); - - /* Remove interface from the global list of interfaces */ -@@ -8627,6 +8630,7 @@ struct wpa_global * wpa_supplicant_init( - - eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, - wpas_periodic, global, NULL); -+ wpas_ucode_init(global); - - return global; - } -@@ -8665,12 +8669,8 @@ int wpa_supplicant_run(struct wpa_global - eloop_register_signal_terminate(wpa_supplicant_terminate, global); - eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); - -- wpas_ubus_add(global); -- - eloop_run(); - -- wpas_ubus_free(global); -- - return 0; - } - -@@ -8703,6 +8703,8 @@ void wpa_supplicant_deinit(struct wpa_gl - - wpas_notify_supplicant_deinitialized(global); - -+ wpas_ucode_free(); -+ - eap_peer_unregister_methods(); - #ifdef CONFIG_AP - eap_server_unregister_methods(); ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -15,6 +15,7 @@ - #include "common/sae.h" - #include "common/wpa_ctrl.h" - #include "common/dpp.h" -+#include "common/ieee802_11_common.h" - #include "crypto/sha384.h" - #include "eapol_supp/eapol_supp_sm.h" - #include "wps/wps_defs.h" -@@ -22,6 +23,7 @@ - #include "wmm_ac.h" - #include "pasn/pasn_common.h" - #include "ubus.h" -+#include "ucode.h" - - extern const char *const wpa_supplicant_version; - extern const char *const wpa_supplicant_license; -@@ -701,6 +703,7 @@ struct wpa_supplicant { - unsigned char perm_addr[ETH_ALEN]; - char ifname[100]; - struct wpas_ubus_bss ubus; -+ struct wpas_ucode_bss ucode; - #ifdef CONFIG_MATCH_IFACE - int matched; - #endif /* CONFIG_MATCH_IFACE */ -@@ -1568,6 +1571,8 @@ struct wpa_supplicant { - unsigned int enabled_4addr_mode:1; - unsigned int multi_bss_support:1; - unsigned int drv_authorized_port:1; -+ -+ struct multi_ap_params multi_ap; - unsigned int multi_ap_ie:1; - unsigned int multi_ap_backhaul:1; - unsigned int multi_ap_fronthaul:1; ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -659,12 +659,17 @@ const char * sae_get_password(struct hos - struct sae_pt **s_pt, - const struct sae_pk **s_pk) - { -+ struct hostapd_bss_config *conf = hapd->conf; -+ struct hostapd_ssid *ssid = &conf->ssid; - const char *password = NULL; -- struct sae_password_entry *pw; -+ struct sae_password_entry *pw = NULL; - struct sae_pt *pt = NULL; - const struct sae_pk *pk = NULL; - struct hostapd_sta_wpa_psk_short *psk = NULL; - -+ if (sta && sta->use_sta_psk) -+ goto use_sta_psk; -+ - /* With sae_track_password functionality enabled, try to first find the - * next viable wildcard-address password if a password identifier was - * not used. Select an wildcard-addr entry if the STA is known to have -@@ -725,12 +730,30 @@ const char * sae_get_password(struct hos - pt = hapd->conf->ssid.pt; - } - -+use_sta_psk: - if (!password && sta && !rx_id) { - for (psk = sta->psk; psk; psk = psk->next) { -- if (psk->is_passphrase) { -- password = psk->passphrase; -+ if (!psk->is_passphrase) -+ continue; -+ -+ password = psk->passphrase; -+ if (!sta->use_sta_psk) -+ break; -+ -+#ifdef CONFIG_SAE -+ if (sta->sae_pt) { -+ pt = sta->sae_pt; - break; - } -+ -+ pt = sae_derive_pt(conf->sae_groups, ssid->ssid, -+ ssid->ssid_len, -+ (const u8 *) password, -+ os_strlen(password), -+ NULL); -+ sta->sae_pt = pt; -+ break; -+#endif - } - } - -@@ -3489,6 +3512,12 @@ static void handle_auth(struct hostapd_d - goto fail; - } - -+ res = hostapd_ucode_sta_auth(hapd, sta); -+ if (res) { -+ resp = res; -+ goto fail; -+ } -+ - sta->flags &= ~WLAN_STA_PREAUTH; - ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); - ---- a/src/ap/sta_info.c -+++ b/src/ap/sta_info.c -@@ -477,6 +477,11 @@ void ap_free_sta(struct hostapd_data *ha - forced_memzero(sta->last_tk, WPA_TK_MAX_LEN); - #endif /* CONFIG_TESTING_OPTIONS */ - -+#ifdef CONFIG_SAE -+ if (sta->sae_pt) -+ sae_deinit_pt(sta->sae_pt); -+#endif -+ - os_free(sta); - } - -@@ -1576,6 +1581,8 @@ void ap_sta_set_authorized_event(struct - #endif /* CONFIG_P2P */ - const u8 *ip_ptr = NULL; - -+ if (authorized) -+ hostapd_ucode_sta_connected(hapd, sta); - #ifdef CONFIG_P2P - if (hapd->p2p_group == NULL) { - if (sta->p2p_ie != NULL && ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -180,6 +180,9 @@ struct sta_info { - int vlan_id_bound; /* updated by ap_sta_bind_vlan() */ - /* PSKs from RADIUS authentication server */ - struct hostapd_sta_wpa_psk_short *psk; -+ struct sae_pt *sae_pt; -+ int use_sta_psk; -+ int psk_idx; - - char *identity; /* User-Name from RADIUS */ - char *radius_cui; /* Chargeable-User-Identity from RADIUS */ ---- a/src/ap/wpa_auth_glue.c -+++ b/src/ap/wpa_auth_glue.c -@@ -392,6 +392,7 @@ static const u8 * hostapd_wpa_auth_get_p - struct sta_info *sta = ap_get_sta(hapd, addr); - const u8 *psk; - -+ sta->psk_idx = 0; - if (vlan_id) - *vlan_id = 0; - if (psk_len) -@@ -442,13 +443,18 @@ static const u8 * hostapd_wpa_auth_get_p - * returned psk which should not be returned again. - * logic list (all hostapd_get_psk; all sta->psk) - */ -+ if (sta && sta->use_sta_psk) -+ psk = NULL; - if (sta && sta->psk && !psk) { - struct hostapd_sta_wpa_psk_short *pos; -+ int psk_idx = 1; - - if (vlan_id) - *vlan_id = 0; - psk = sta->psk->psk; -- for (pos = sta->psk; pos; pos = pos->next) { -+ if (vlan_id) -+ sta->psk_idx = psk_idx; -+ for (pos = sta->psk; pos; pos = pos->next, psk_idx++) { - if (pos->is_passphrase) { - if (pbkdf2_sha1(pos->passphrase, - hapd->conf->ssid.ssid, -@@ -462,9 +468,13 @@ static const u8 * hostapd_wpa_auth_get_p - } - if (pos->psk == prev_psk) { - psk = pos->next ? pos->next->psk : NULL; -+ if (vlan_id) -+ sta->psk_idx = psk_idx + 1; - break; - } - } -+ if (vlan_id && !psk) -+ sta->psk_idx = 0; - } - return psk; - } diff --git a/package/network/services/hostapd/src/wpa_supplicant/ubus.c b/package/network/services/hostapd/src/wpa_supplicant/ubus.c deleted file mode 100644 index 1c477f0c0c..0000000000 --- a/package/network/services/hostapd/src/wpa_supplicant/ubus.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * wpa_supplicant / ubus support - * Copyright (c) 2018, Daniel Golle - * Copyright (c) 2013, Felix Fietkau - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "utils/includes.h" -#include "utils/common.h" -#include "utils/eloop.h" -#include "utils/wpabuf.h" -#include "common/ieee802_11_defs.h" -#include "wpa_supplicant_i.h" -#include "wps_supplicant.h" -#include "ubus.h" - -static struct ubus_context *ctx; -static struct blob_buf b; -static int ctx_ref; - -static inline struct wpa_global *get_wpa_global_from_object(struct ubus_object *obj) -{ - return container_of(obj, struct wpa_global, ubus_global); -} - -static inline struct wpa_supplicant *get_wpas_from_object(struct ubus_object *obj) -{ - return container_of(obj, struct wpa_supplicant, ubus.obj); -} - -static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) -{ - if (ubus_reconnect(ctx, NULL)) { - eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); - return; - } - - ubus_add_uloop(ctx); -} - -static void wpas_ubus_connection_lost(struct ubus_context *ctx) -{ - uloop_fd_delete(&ctx->sock); - eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -} - -static bool wpas_ubus_init(void) -{ - if (ctx) - return true; - - eloop_add_uloop(); - ctx = ubus_connect(NULL); - if (!ctx) - return false; - - ctx->connection_lost = wpas_ubus_connection_lost; - ubus_add_uloop(ctx); - - return true; -} - -static void wpas_ubus_ref_inc(void) -{ - ctx_ref++; -} - -static void wpas_ubus_ref_dec(void) -{ - ctx_ref--; - if (!ctx) - return; - - if (ctx_ref) - return; - - uloop_fd_delete(&ctx->sock); - ubus_free(ctx); - ctx = NULL; -} - -static int -wpas_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); - - blob_buf_init(&b, 0); - blobmsg_add_u8(&b, "ht_supported", ht_supported(wpa_s->hw.modes)); - blobmsg_add_u8(&b, "vht_supported", vht_supported(wpa_s->hw.modes)); - ubus_send_reply(ctx, req, b.head); - - return 0; -} - -static int -wpas_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); - - if (wpa_supplicant_reload_configuration(wpa_s)) - return UBUS_STATUS_UNKNOWN_ERROR; - else - return 0; -} - -#ifdef CONFIG_WPS -enum { - WPS_START_MULTI_AP, - __WPS_START_MAX -}; - -static const struct blobmsg_policy wps_start_policy[] = { - [WPS_START_MULTI_AP] = { "multi_ap", BLOBMSG_TYPE_BOOL }, -}; - -static int -wpas_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - int rc; - struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); - struct blob_attr *tb[__WPS_START_MAX], *cur; - int multi_ap = 0; - - blobmsg_parse(wps_start_policy, __WPS_START_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); - - if (tb[WPS_START_MULTI_AP]) - multi_ap = blobmsg_get_bool(tb[WPS_START_MULTI_AP]); - - rc = wpas_wps_start_pbc(wpa_s, NULL, 0, multi_ap); - - if (rc != 0) - return UBUS_STATUS_NOT_SUPPORTED; - - return 0; -} - -static int -wpas_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - int rc; - struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); - - rc = wpas_wps_cancel(wpa_s); - - if (rc != 0) - return UBUS_STATUS_NOT_SUPPORTED; - - return 0; -} -#endif - -static const struct ubus_method bss_methods[] = { - UBUS_METHOD_NOARG("reload", wpas_bss_reload), - UBUS_METHOD_NOARG("get_features", wpas_bss_get_features), -#ifdef CONFIG_WPS - UBUS_METHOD_NOARG("wps_start", wpas_bss_wps_start), - UBUS_METHOD_NOARG("wps_cancel", wpas_bss_wps_cancel), -#endif -}; - -static struct ubus_object_type bss_object_type = - UBUS_OBJECT_TYPE("wpas_bss", bss_methods); - -void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) -{ - struct ubus_object *obj = &wpa_s->ubus.obj; - char *name; - int ret; - - if (!wpas_ubus_init()) - return; - - if (asprintf(&name, "wpa_supplicant.%s", wpa_s->ifname) < 0) - return; - - obj->name = name; - obj->type = &bss_object_type; - obj->methods = bss_object_type.methods; - obj->n_methods = bss_object_type.n_methods; - ret = ubus_add_object(ctx, obj); - wpas_ubus_ref_inc(); -} - -void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) -{ - struct ubus_object *obj = &wpa_s->ubus.obj; - char *name = (char *) obj->name; - - if (!ctx) - return; - - if (obj->id) { - ubus_remove_object(ctx, obj); - wpas_ubus_ref_dec(); - } - - free(name); -} - -#ifdef CONFIG_WPS -void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) -{ - u16 auth_type; - char *ifname, *encryption, *ssid, *key; - size_t ifname_len; - - if (!cred) - return; - - auth_type = cred->auth_type; - - if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) - auth_type = WPS_AUTH_WPA2PSK; - - if (auth_type != WPS_AUTH_OPEN && - auth_type != WPS_AUTH_WPAPSK && - auth_type != WPS_AUTH_WPA2PSK) { - wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for " - "unsupported authentication type 0x%x", - auth_type); - return; - } - - if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) { - if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) { - wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with " - "invalid Network Key length %lu", - (unsigned long) cred->key_len); - return; - } - } - - blob_buf_init(&b, 0); - - ifname_len = strlen(wpa_s->ifname); - ifname = blobmsg_alloc_string_buffer(&b, "ifname", ifname_len + 1); - memcpy(ifname, wpa_s->ifname, ifname_len + 1); - ifname[ifname_len] = '\0'; - blobmsg_add_string_buffer(&b); - - switch (auth_type) { - case WPS_AUTH_WPA2PSK: - encryption = "psk2"; - break; - case WPS_AUTH_WPAPSK: - encryption = "psk"; - break; - default: - encryption = "none"; - break; - } - - blobmsg_add_string(&b, "encryption", encryption); - - ssid = blobmsg_alloc_string_buffer(&b, "ssid", cred->ssid_len + 1); - memcpy(ssid, cred->ssid, cred->ssid_len); - ssid[cred->ssid_len] = '\0'; - blobmsg_add_string_buffer(&b); - - if (cred->key_len > 0) { - key = blobmsg_alloc_string_buffer(&b, "key", cred->key_len + 1); - memcpy(key, cred->key, cred->key_len); - key[cred->key_len] = '\0'; - blobmsg_add_string_buffer(&b); - } - -// ubus_notify(ctx, &wpa_s->ubus.obj, "wps_credentials", b.head, -1); - ubus_send_event(ctx, "wps_credentials", b.head); -} -#endif /* CONFIG_WPS */ diff --git a/package/network/services/hostapd/src/wpa_supplicant/ubus.h b/package/network/services/hostapd/src/wpa_supplicant/ubus.h deleted file mode 100644 index f6681cb26d..0000000000 --- a/package/network/services/hostapd/src/wpa_supplicant/ubus.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * wpa_supplicant / ubus support - * Copyright (c) 2018, Daniel Golle - * Copyright (c) 2013, Felix Fietkau - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ -#ifndef __WPAS_UBUS_H -#define __WPAS_UBUS_H - -struct wpa_supplicant; -struct wpa_global; - -#include "wps_supplicant.h" - -#ifdef UBUS_SUPPORT -#include - -struct wpas_ubus_bss { - struct ubus_object obj; -}; - -void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s); -void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s); - -#ifdef CONFIG_WPS -void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); -#endif - -#else -struct wpas_ubus_bss {}; - -static inline void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) -{ -} - -static inline void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) -{ -} - -static inline void wpas_ubus_notify(struct wpa_supplicant *wpa_s, struct wps_credential *cred) -{ -} - -static inline void wpas_ubus_add(struct wpa_global *global) -{ -} - -static inline void wpas_ubus_free(struct wpa_global *global) -{ -} -#endif - -#endif diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.c b/package/network/services/hostapd/src/wpa_supplicant/ucode.c index 761649498c..fd0d3405c9 100644 --- a/package/network/services/hostapd/src/wpa_supplicant/ucode.c +++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.c @@ -157,6 +157,64 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d ucv_put(wpa_ucode_call(4)); } +void wpas_ucode_wps_complete(struct wpa_supplicant *wpa_s, + const struct wps_credential *cred) +{ +#ifdef CONFIG_WPS + uc_value_t *val; + char *ifname, *encryption, *ssid, *key; + size_t ifname_len; + + if (!cred) + return; + + switch (cred->auth_type) { + case WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK: + case WPS_AUTH_WPA2PSK: + encryption = "psk2"; + break; + case WPS_AUTH_WPAPSK: + encryption = "psk"; + break; + case WPS_AUTH_OPEN: + encryption = "none"; + break; + default: + wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for " + "unsupported authentication type 0x%x", + cred->auth_type); + return; + } + + if (cred->auth_type != WPS_AUTH_OPEN && + (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN)) { + wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with " + "invalid Network Key length %lu", + (unsigned long) cred->key_len); + return; + } + + val = wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); + if (!val) + return; + + if (wpa_ucode_call_prepare("wps_credentials")) + return; + + uc_value_push(ucv_string_new(wpa_s->ifname)); + uc_value_push(ucv_get(val)); + + val = ucv_object_new(vm); + uc_value_push(val); + + ucv_object_add(val, "encryption", ucv_string_new(encryption)); + ucv_object_add(val, "ssid", ucv_string_new_length(cred->ssid, cred->ssid_len)); + ucv_object_add(val, "key", ucv_string_new_length(cred->key, cred->key_len)); + + ucv_put(wpa_ucode_call(3)); +#endif /* CONFIG_WPS */ +} + static const char *obj_stringval(uc_value_t *obj, const char *name) { uc_value_t *val = ucv_object_get(obj, name, NULL); diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.h b/package/network/services/hostapd/src/wpa_supplicant/ucode.h index fd339fa3e9..de9930bec5 100644 --- a/package/network/services/hostapd/src/wpa_supplicant/ucode.h +++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.h @@ -3,9 +3,11 @@ #include "utils/ucode.h" +struct wpa_bss; struct wpa_global; union wpa_event_data; struct wpa_supplicant; +struct wps_credential; struct wpas_ucode_bss { #ifdef UCODE_SUPPORT @@ -21,6 +23,8 @@ void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s); void wpas_ucode_update_state(struct wpa_supplicant *wpa_s); void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data); bool wpas_ucode_bss_allowed(struct wpa_supplicant *wpa_s, struct wpa_bss *bss); +void wpas_ucode_wps_complete(struct wpa_supplicant *wpa_s, + const struct wps_credential *cred); #else static inline int wpas_ucode_init(struct wpa_global *gl) { @@ -49,6 +53,10 @@ static inline bool wpas_ucode_bss_allowed(struct wpa_supplicant *wpa_s, struct w { return true; } + +static inline void wpas_ucode_wps_complete(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) +{ +} #endif #endif -- 2.30.2