From 9a04d5cb669f27e1392847f17d2e834584ab4ccc Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 2 Oct 2023 17:20:45 +0200 Subject: [PATCH] uspot: add CoA support Fixes: WIFI-12103 Signed-off-by: John Crispin --- feeds/ipq807x_v5.4/hostapd/files/hostapd.sh | 10 ++--- .../hostapd/patches/901-coa-ubus.patch | 28 ++++++++++++ feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c | 3 +- feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.h | 1 + feeds/ucentral/ucentral-schema/Makefile | 4 +- .../etc/ucentral/examples/captive-uam.json | 7 +++ .../uspot/files/usr/share/uspot/uspot.uc | 44 +++++++++++++++++++ feeds/wifi-ax/hostapd/files/hostapd.sh | 10 ++--- .../hostapd/patches/901-coa-ubus.patch | 28 ++++++++++++ feeds/wifi-ax/hostapd/src/src/ap/ubus.c | 3 +- feeds/wifi-ax/hostapd/src/src/ap/ubus.h | 1 + 11 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 feeds/ipq807x_v5.4/hostapd/patches/901-coa-ubus.patch create mode 100644 feeds/wifi-ax/hostapd/patches/901-coa-ubus.patch diff --git a/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh b/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh index e7fd78799..1ac4d6443 100644 --- a/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh +++ b/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh @@ -603,7 +603,7 @@ append_radius_server() { set_default dae_port 3799 set_default request_cui 0 - [ "$eap_server" -eq 0 ] && { + [ "$eap_server" -eq 0 -a -n "$auth_server" ] && { append bss_conf "auth_server_addr=$auth_server" "$N" append bss_conf "auth_server_port=$auth_port" "$N" append bss_conf "auth_server_shared_secret=$auth_secret" "$N" @@ -772,9 +772,7 @@ hostapd_set_bss_options() { # with WPS enabled, we got to be in unconfigured state. wps_not_configured=1 vlan_possible=1 - [ "$macfilter" = radius ] && { - append_radius_server - } + append_radius_server ;; psk|sae|psk-sae) json_get_vars key wpa_psk_file @@ -793,10 +791,8 @@ hostapd_set_bss_options() { } [ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N" + append_radius_server set_default dynamic_vlan 0 - [ "$macfilter" = radius ] && { - append_radius_server - } vlan_possible=1 wps_possible=1 ;; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/901-coa-ubus.patch b/feeds/ipq807x_v5.4/hostapd/patches/901-coa-ubus.patch new file mode 100644 index 000000000..d525c7946 --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/patches/901-coa-ubus.patch @@ -0,0 +1,28 @@ +Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c ++++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +@@ -1034,6 +1034,23 @@ hostapd_das_disconnect(void *ctx, struct + struct hostapd_data *hapd = ctx; + struct sta_info *sta; + int multi; ++ int ubus_resp; ++ struct hostapd_ubus_request req = { ++ .type = HOSTAPD_UBUS_COA, ++ .mgmt_frame = 0, ++ .ssi_signal = 0, ++ .addr = attr->sta_addr, ++ }; ++ ++ if (hostapd_ubus_handle_event(hapd, &req)) { ++ wpa_printf(MSG_INFO, "DAS: disconnect due approved via ubus"); ++ sta = ap_get_sta(hapd, attr->sta_addr); ++ if (sta) { ++ hostapd_drv_sta_deauth(hapd, attr->sta_addr, 2); ++ ap_sta_deauthenticate(hapd, sta, 2); ++ } ++ return RADIUS_DAS_SUCCESS; ++ } + + if (hostapd_das_nas_mismatch(hapd, attr)) + return RADIUS_DAS_NAS_MISMATCH; diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c index c214d62c9..474bd6b24 100644 --- a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c +++ b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c @@ -1638,6 +1638,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req [HOSTAPD_UBUS_PROBE_REQ] = "probe", [HOSTAPD_UBUS_AUTH_REQ] = "auth", [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", + [HOSTAPD_UBUS_COA] = "coa", }; const char *type = "mgmt"; struct ubus_event_req ureq = {}; @@ -1707,7 +1708,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req } } - if (!hapd->ubus.notify_response) { + if (!hapd->ubus.notify_response && req->type != HOSTAPD_UBUS_COA) { ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); return WLAN_STATUS_SUCCESS; } diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.h b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.h index ce23ee3a5..237631aa9 100644 --- a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.h +++ b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.h @@ -12,6 +12,7 @@ enum hostapd_ubus_event_type { HOSTAPD_UBUS_PROBE_REQ, HOSTAPD_UBUS_AUTH_REQ, HOSTAPD_UBUS_ASSOC_REQ, + HOSTAPD_UBUS_COA, HOSTAPD_UBUS_TYPE_MAX }; diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 1b749ada4..8e7710704 100644 --- a/feeds/ucentral/ucentral-schema/Makefile +++ b/feeds/ucentral/ucentral-schema/Makefile @@ -4,10 +4,10 @@ PKG_NAME:=ucentral-schema PKG_RELEASE:=1 PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git -PKG_MIRROR_HASH:=13ac49c727ad9bbceb02f8742e68f95b97ff907ea9120425656cf0d4d6f681be +PKG_MIRROR_HASH:=f85296fa27a52d494f9787a5e4bde135653121608ad36a54252ca5c6dd46baf5 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=aa79c72358293314581953226f11092eb2313bca +PKG_SOURCE_VERSION:=19c5923382f5bb7407bec46b285ef4c63d2f31e0 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause diff --git a/feeds/ucentral/ucentral-schema/files/etc/ucentral/examples/captive-uam.json b/feeds/ucentral/ucentral-schema/files/etc/ucentral/examples/captive-uam.json index 216d9e536..1fa8be2fc 100644 --- a/feeds/ucentral/ucentral-schema/files/etc/ucentral/examples/captive-uam.json +++ b/feeds/ucentral/ucentral-schema/files/etc/ucentral/examples/captive-uam.json @@ -48,6 +48,13 @@ "proto": "psk2", "key": "OpenWifi", "ieee80211w": "optional" + }, + "radius": { + "dynamic-authorization": { + "host": "0.0.0.0", + "port": 3333, + "secret": "secret" + } } } ] diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/uspot.uc b/feeds/ucentral/uspot/files/usr/share/uspot/uspot.uc index d9c5e2ba5..fef9aec9a 100755 --- a/feeds/ucentral/uspot/files/usr/share/uspot/uspot.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/uspot.uc @@ -7,6 +7,7 @@ let uloop = require('uloop'); let ubus = require('ubus').connect(); let uci = require('uci').cursor(); let interfaces = {}; +let hapd_subscriber; let uciload = uci.foreach('uspot', 'uspot', (d) => { if (!d[".anonymous"]) { @@ -119,6 +120,13 @@ const radtc_idleto = 4; // Idle Timeout const radtc_sessionto = 5; // Session Timeout const radtc_adminreset = 6; // Admin Reset +function interface_find(mac) { + for (let k, v in interfaces) + if (v.clients[mac]) + return k; + return null; +} + function radius_terminate(interface, mac, cause) { if (!interfaces[interface].clients[mac].radius) return; @@ -350,6 +358,34 @@ function accounting(interface) { } } +function hapd_subscriber_notify_cb(notify) { + if (notify.type != 'coa') + return 0; + notify.data.address = uc(notify.data.address); + let iface = interface_find(notify.data.address); + if (!iface) + return 0; + client_kick(iface, notify.data.address, true); + return 1; +} + +function hapd_subscriber_remove_cb(remove) { + printf('remove: %.J\n', remove); +} + +function listener_cb(event, payload) { + unsub_object(event == 'ubus.object.add', payload.id, payload.path); +} + +function unsub_object(add, id, path) { + let object = split(path, '.'); + + if (object[0] == 'hostapd' && object[1] && add) { + printf('adding %s\n', path); + hapd_subscriber.subscribe(path); + } +} + function start() { let seen = {}; @@ -367,6 +403,14 @@ function start() seen[server][nasid] = 1; radius_accton(interface); } + hapd_subscriber = ubus.subscriber(hapd_subscriber_notify_cb, hapd_subscriber_remove_cb); + + let list = ubus.list(); + for (let k, path in list) + unsub_object(true, 0, path); + + ubus.listener('ubus.object.add', listener_cb); + ubus.listener('ubus.object.remove', listener_cb); } function stop() diff --git a/feeds/wifi-ax/hostapd/files/hostapd.sh b/feeds/wifi-ax/hostapd/files/hostapd.sh index d313ce0bf..1ac4d6443 100644 --- a/feeds/wifi-ax/hostapd/files/hostapd.sh +++ b/feeds/wifi-ax/hostapd/files/hostapd.sh @@ -603,7 +603,7 @@ append_radius_server() { set_default dae_port 3799 set_default request_cui 0 - [ "$eap_server" -eq 0 ] && { + [ "$eap_server" -eq 0 -a -n "$auth_server" ] && { append bss_conf "auth_server_addr=$auth_server" "$N" append bss_conf "auth_server_port=$auth_port" "$N" append bss_conf "auth_server_shared_secret=$auth_secret" "$N" @@ -772,9 +772,7 @@ hostapd_set_bss_options() { # with WPS enabled, we got to be in unconfigured state. wps_not_configured=1 vlan_possible=1 - [ "$macfilter" = radius ] && { - append_radius_server - } + append_radius_server ;; psk|sae|psk-sae) json_get_vars key wpa_psk_file @@ -793,9 +791,7 @@ hostapd_set_bss_options() { } [ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N" - [ "$macfilter" = radius ] && { - append_radius_server - } + append_radius_server set_default dynamic_vlan 0 vlan_possible=1 wps_possible=1 diff --git a/feeds/wifi-ax/hostapd/patches/901-coa-ubus.patch b/feeds/wifi-ax/hostapd/patches/901-coa-ubus.patch new file mode 100644 index 000000000..d525c7946 --- /dev/null +++ b/feeds/wifi-ax/hostapd/patches/901-coa-ubus.patch @@ -0,0 +1,28 @@ +Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c ++++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +@@ -1034,6 +1034,23 @@ hostapd_das_disconnect(void *ctx, struct + struct hostapd_data *hapd = ctx; + struct sta_info *sta; + int multi; ++ int ubus_resp; ++ struct hostapd_ubus_request req = { ++ .type = HOSTAPD_UBUS_COA, ++ .mgmt_frame = 0, ++ .ssi_signal = 0, ++ .addr = attr->sta_addr, ++ }; ++ ++ if (hostapd_ubus_handle_event(hapd, &req)) { ++ wpa_printf(MSG_INFO, "DAS: disconnect due approved via ubus"); ++ sta = ap_get_sta(hapd, attr->sta_addr); ++ if (sta) { ++ hostapd_drv_sta_deauth(hapd, attr->sta_addr, 2); ++ ap_sta_deauthenticate(hapd, sta, 2); ++ } ++ return RADIUS_DAS_SUCCESS; ++ } + + if (hostapd_das_nas_mismatch(hapd, attr)) + return RADIUS_DAS_NAS_MISMATCH; diff --git a/feeds/wifi-ax/hostapd/src/src/ap/ubus.c b/feeds/wifi-ax/hostapd/src/src/ap/ubus.c index 5f8bab526..5e3a7b474 100644 --- a/feeds/wifi-ax/hostapd/src/src/ap/ubus.c +++ b/feeds/wifi-ax/hostapd/src/src/ap/ubus.c @@ -1638,6 +1638,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req [HOSTAPD_UBUS_PROBE_REQ] = "probe", [HOSTAPD_UBUS_AUTH_REQ] = "auth", [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", + [HOSTAPD_UBUS_COA] = "coa", }; const char *type = "mgmt"; struct ubus_event_req ureq = {}; @@ -1707,7 +1708,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req } } - if (!hapd->ubus.notify_response) { + if (!hapd->ubus.notify_response && req->type != HOSTAPD_UBUS_COA) { ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); return WLAN_STATUS_SUCCESS; } diff --git a/feeds/wifi-ax/hostapd/src/src/ap/ubus.h b/feeds/wifi-ax/hostapd/src/src/ap/ubus.h index ce23ee3a5..237631aa9 100644 --- a/feeds/wifi-ax/hostapd/src/src/ap/ubus.h +++ b/feeds/wifi-ax/hostapd/src/src/ap/ubus.h @@ -12,6 +12,7 @@ enum hostapd_ubus_event_type { HOSTAPD_UBUS_PROBE_REQ, HOSTAPD_UBUS_AUTH_REQ, HOSTAPD_UBUS_ASSOC_REQ, + HOSTAPD_UBUS_COA, HOSTAPD_UBUS_TYPE_MAX };