From 0856cd5cda623339abe983973c09ff57040182c9 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 4 Oct 2022 10:04:43 +0200 Subject: [PATCH] add support for wifi mac acl Signed-off-by: John Crispin --- renderer/templates/interface/ssid.uc | 7 ++++ schema/interface.ssid.acl.yml | 18 +++++++++ schema/interface.ssid.yml | 2 + schemareader.uc | 59 ++++++++++++++++++++++++++++ ucentral.schema.json | 22 +++++++++++ 5 files changed, 108 insertions(+) create mode 100644 schema/interface.ssid.acl.yml diff --git a/renderer/templates/interface/ssid.uc b/renderer/templates/interface/ssid.uc index 505b0fe..6a0f4e9 100644 --- a/renderer/templates/interface/ssid.uc +++ b/renderer/templates/interface/ssid.uc @@ -389,6 +389,13 @@ set wireless.{{ section }}.maxassoc={{ ssid.maximum_clients }} set wireless.{{ section }}.ratelimit=1 {% endif %} +{% if (ssid.access_control_list?.mode): %} +set wireless.{{ section }}.macfilter={{ s(ssid.access_control_list.mode) }} +{% for (let mac in ssid.access_control_list.mac_address): %} +add_list wireless.{{ section }}.maclist={{ s(mac) }} +{% endfor %} +{% endif %} + {% if (ssid.rrm): %} set wireless.{{ section }}.ieee80211k={{ b(ssid.rrm.neighbor_reporting) }} set wireless.{{ section }}.rnr={{ b(ssid.rrm.reduced_neighbor_reporting) }} diff --git a/schema/interface.ssid.acl.yml b/schema/interface.ssid.acl.yml new file mode 100644 index 0000000..a918754 --- /dev/null +++ b/schema/interface.ssid.acl.yml @@ -0,0 +1,18 @@ +description: + The MAC ACL that defines which clients are allowed or denied to associations. +type: object +properties: + mode: + description: + Defines if this is an allow or deny list. + type: string + enum: + - allow + - deny + mac-address: + description: + Association requests will be denied if the rssi is below this threshold. + type: array + items: + type: string + format: uc-mac diff --git a/schema/interface.ssid.yml b/schema/interface.ssid.yml index 00a69ae..d7ff144 100644 --- a/schema/interface.ssid.yml +++ b/schema/interface.ssid.yml @@ -136,6 +136,8 @@ properties: $ref: "https://ucentral.io/schema/v1/interface/ssid/pass-point/" quality-thresholds: $ref: "https://ucentral.io/schema/v1/interface/ssid/quality-thresholds/" + access-control-list: + $ref: "https://ucentral.io/schema/v1/interface/ssid/acl/" hostapd-bss-raw: description: This array allows passing raw hostapd.conf lines. diff --git a/schemareader.uc b/schemareader.uc index 546b09c..18eefbf 100644 --- a/schemareader.uc +++ b/schemareader.uc @@ -4157,6 +4157,61 @@ function instantiateInterfaceSsidQualityThresholds(location, value, errors) { return value; } +function instantiateInterfaceSsidAcl(location, value, errors) { + if (type(value) == "object") { + let obj = {}; + + function parseMode(location, value, errors) { + if (type(value) != "string") + push(errors, [ location, "must be of type string" ]); + + if (!(value in [ "allow", "deny" ])) + push(errors, [ location, "must be one of \"allow\" or \"deny\"" ]); + + return value; + } + + if (exists(value, "mode")) { + obj.mode = parseMode(location + "/mode", value["mode"], errors); + } + + function parseMacAddress(location, value, errors) { + if (type(value) == "array") { + function parseItem(location, value, errors) { + if (type(value) == "string") { + if (!matchUcMac(value)) + push(errors, [ location, "must be a valid MAC address" ]); + + } + + if (type(value) != "string") + push(errors, [ location, "must be of type string" ]); + + return value; + } + + return map(value, (item, i) => parseItem(location + "/" + i, item, errors)); + } + + if (type(value) != "array") + push(errors, [ location, "must be of type array" ]); + + return value; + } + + if (exists(value, "mac-address")) { + obj.mac_address = parseMacAddress(location + "/mac-address", value["mac-address"], errors); + } + + return obj; + } + + if (type(value) != "object") + push(errors, [ location, "must be of type object" ]); + + return value; +} + function instantiateInterfaceSsid(location, value, errors) { if (type(value) == "object") { let obj = {}; @@ -4474,6 +4529,10 @@ function instantiateInterfaceSsid(location, value, errors) { obj.quality_thresholds = instantiateInterfaceSsidQualityThresholds(location + "/quality-thresholds", value["quality-thresholds"], errors); } + if (exists(value, "access-control-list")) { + obj.access_control_list = instantiateInterfaceSsidAcl(location + "/access-control-list", value["access-control-list"], errors); + } + function parseHostapdBssRaw(location, value, errors) { if (type(value) == "array") { function parseItem(location, value, errors) { diff --git a/ucentral.schema.json b/ucentral.schema.json index ef88975..e547ed3 100644 --- a/ucentral.schema.json +++ b/ucentral.schema.json @@ -1586,6 +1586,25 @@ } } }, + "interface.ssid.acl": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": [ + "allow", + "deny" + ] + }, + "mac-address": { + "type": "array", + "items": { + "type": "string", + "format": "uc-mac" + } + } + } + }, "interface.ssid": { "type": "object", "properties": { @@ -1714,6 +1733,9 @@ "quality-thresholds": { "$ref": "#/$defs/interface.ssid.quality-thresholds" }, + "access-control-list": { + "$ref": "#/$defs/interface.ssid.acl" + }, "hostapd-bss-raw": { "type": "array", "items": {