hostapd.data.ubus = ubus;
hostapd.data.obj = ubus.publish("hostapd", main_obj);
+
+
+let auth_obj = {};
+hostapd.data.auth_obj = ubus.publish("hostapd-auth", auth_obj);
hostapd.udebug_set("hostapd", hostapd.data.ubus);
function bss_event(type, name, data) {
},
bss_remove: function(name, obj) {
bss_event("remove", name);
- }
+ },
+ sta_auth: function(iface, sta) {
+ let msg = { iface, sta };
+ let ret = {};
+ let data_cb = (type, data) => {
+ ret = { ...ret, ...data };
+ };
+ hostapd.data.auth_obj.notify("sta_auth", msg, data_cb, null, null, 1000);
+ return ret;
+ },
+ sta_connected: function(iface, sta, data) {
+ let msg = { iface, sta, ...data };
+ let ret = {};
+ let data_cb = (type, data) => {
+ ret = { ...ret, ...data };
+ };
+ hostapd.data.auth_obj.notify("sta_connected", msg, data_cb, null, null, 1000);
+ return ret;
+ },
};
}
},
"subscribe": [ "udebug" ],
- "publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*" ],
+ "publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*", "hostapd-auth" ],
"send": [ "bss.*", "wps_credentials" ]
}
#ifdef CONFIG_MATCH_IFACE
int matched;
#endif /* CONFIG_MATCH_IFACE */
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -3123,6 +3123,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
+@@ -1434,6 +1434,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
+@@ -195,6 +195,7 @@ 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;
++ 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
+@@ -347,6 +347,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)
+@@ -395,11 +396,12 @@ static const u8 * hostapd_wpa_auth_get_p
+ */
+ 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) {
++ for (pos = sta->psk; pos; pos = pos->next, psk_idx++) {
+ if (pos->is_passphrase) {
+ if (pbkdf2_sha1(pos->passphrase,
+ hapd->conf->ssid.ssid,
+@@ -416,6 +418,8 @@ static const u8 * hostapd_wpa_auth_get_p
+ break;
+ }
+ }
++ if (psk)
++ sta->psk_idx = psk_idx;
+ }
+ return psk;
+ }
int bridge_hairpin; /* hairpin_mode on bridge members */
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
-@@ -1777,8 +1777,12 @@ int hostapd_setup_wpa(struct hostapd_dat
+@@ -1781,8 +1781,12 @@ int hostapd_setup_wpa(struct hostapd_dat
wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) {
const char *ft_iface;
#include "ap_drv_ops.h"
#include "dfs.h"
#include "acs.h"
+#include "ieee802_11_auth.h"
#include <libubox/uloop.h>
static uc_resource_type_t *global_type, *bss_type, *iface_type;
return ret ? NULL : ucv_boolean_new(true);
}
+int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
+{
+ char addr[sizeof(MACSTR)];
+ uc_value_t *val, *cur;
+ int ret = 0;
+
+ if (wpa_ucode_call_prepare("sta_auth"))
+ return 0;
+
+ uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
+
+ snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr));
+ val = ucv_string_new(addr);
+ uc_value_push(ucv_get(val));
+
+ val = wpa_ucode_call(2);
+
+ cur = ucv_object_get(val, "psk", NULL);
+ if (ucv_type(cur) == UC_ARRAY) {
+ struct hostapd_sta_wpa_psk_short *p, **next;
+ size_t len = ucv_array_length(cur);
+
+ next = &sta->psk;
+ hostapd_free_psk_list(*next);
+ *next = NULL;
+
+ for (size_t i = 0; i < len; i++) {
+ uc_value_t *cur_psk;
+ const char *str;
+ size_t str_len;
+
+ cur_psk = ucv_array_get(cur, i);
+ str = ucv_string_get(cur_psk);
+ str_len = strlen(str);
+ if (!str || str_len < 8 || str_len > 64)
+ continue;
+
+ p = os_zalloc(sizeof(*p));
+ if (len == 64) {
+ if (hexstr2bin(str, p->psk, PMK_LEN) < 0) {
+ free(p);
+ continue;
+ }
+ } else {
+ p->is_passphrase = 1;
+ memcpy(p->passphrase, str, str_len + 1);
+ }
+
+ *next = p;
+ next = &p->next;
+ }
+ }
+
+ cur = ucv_object_get(val, "status", NULL);
+ if (ucv_type(cur) == UC_INTEGER)
+ ret = ucv_int64_get(cur);
+
+ ucv_put(val);
+ ucv_gc(vm);
+
+ return ret;
+}
+
+void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta)
+{
+ char addr[sizeof(MACSTR)];
+ uc_value_t *val, *cur;
+ int ret = 0;
+
+ if (wpa_ucode_call_prepare("sta_connected"))
+ return;
+
+ uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
+
+ snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr));
+ val = ucv_string_new(addr);
+ uc_value_push(ucv_get(val));
+
+ val = ucv_object_new(vm);
+ if (sta->psk_idx)
+ ucv_object_add(val, "psk_idx", ucv_int64_new(sta->psk_idx - 1));
+ uc_value_push(ucv_get(val));
+
+ val = wpa_ucode_call(3);
+ if (ucv_type(val) != UC_OBJECT)
+ goto out;
+
+ cur = ucv_object_get(val, "vlan", NULL);
+ if (ucv_type(cur) == UC_INTEGER) {
+ struct vlan_description vdesc = {
+ .notempty = 1,
+ .untagged = ucv_int64_get(cur),
+ };
+
+ ap_sta_set_vlan(hapd, sta, &vdesc);
+ ap_sta_bind_vlan(hapd, sta);
+ }
+
+out:
+ ucv_put(val);
+}
int hostapd_ucode_init(struct hapd_interfaces *ifaces)
{
void hostapd_ucode_free(void);
void hostapd_ucode_free_iface(struct hostapd_iface *iface);
+int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta);
+void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta);
void hostapd_ucode_add_bss(struct hostapd_data *hapd);
void hostapd_ucode_free_bss(struct hostapd_data *hapd);
void hostapd_ucode_reload_bss(struct hostapd_data *hapd);
static inline void hostapd_ucode_reload_bss(struct hostapd_data *hapd)
{
}
+static inline int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
+{
+ return 0;
+}
+static inline void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta)
+{
+}
static inline void hostapd_ucode_add_bss(struct hostapd_data *hapd)
{
}