schema: add pass-point support

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2021-05-22 10:18:47 +02:00
parent bb7949b765
commit 98a577c13f
6 changed files with 192 additions and 70 deletions

View File

@@ -18,16 +18,19 @@
proto: ssid.encryption.proto,
key: ssid.encryption.key
};
warn(ssid.encryption.proto);
if (ssid.encryption.proto in [ "wpa", "wpa2", "wpa-mixed", "wpa3", "wpa3-mixed" ] &&
ssid.encryption.radius && ssid.encryption.radius.authentication &&
ssid.encryption.radius.authentication.host &&
ssid.encryption.radius.authentication.port &&
ssid.encryption.radius.authentication.secret)
ssid.radius && ssid.radius.authentication &&
ssid.radius.authentication.host &&
ssid.radius.authentication.port &&
ssid.radius.authentication.secret)
return {
proto: ssid.encryption.proto,
auth: ssid.encryption.ssid.encryption.radius.authentication,
acct: ssid.encryption.ssid.encryption.radius.accounting
auth: ssid.radius.authentication,
acct: ssid.radius.accounting,
radius: ssid.radius
};
warn("Can't find any valid encryption settings");
return false;
}
@@ -42,6 +45,16 @@
return index([ "wds-ap", "wds-sta", "wds-repeater" ], ssid.bss_mode);
}
function match_hs20_auth_type(auth_type) {
let types = {
"terms-and-conditions": "00",
"online-enrollment": "01",
"http-redirection": "02",
"dns-redirection": "03"
};
return (auth_type && auth_type.type) ? types[auth_type.type] : '';
}
let bss_mode = ssid.bss_mode;
if (ssid.bss_mode == "wds-ap")
bss_mode = "ap";
@@ -100,16 +113,51 @@ set wireless.{{ section }}.mcast_rate={{ ssid.rates.multicast }}
set wireless.{{ section }}.ieee80211w={{ match_ieee80211w() }}
set wireless.{{ section }}.encryption={{ crypto.proto }}
set wireless.{{ section }}.key={{ crypto.key }}
{% if (crypto.radius): %}
set wireless.{{ section }}.request_cui={{ b(crypto.radius.chargeable_user_id) }}
set wireless.{{ section }}.nasid={{ s(crypto.radius.nas_identifier) }}
{% endif %}
{% if (crypto.auth): %}
set wireless.{{ section }}.auth_server={{ crypto.auth.host }}
set wireless.{{ section }}.auth_port={{ crypto.auth.port }}
set wireless.{{ section }}.auth_secret={{ crypto.auth.secret }}
{% for (let request in crypto.auth.request_attribute): %}
add_list wireless.{{ section }}.radius_auth_req_attr={{ s(request.id + ':' + request.value) }}
{% endfor %}
{% endif %}
{% if (crypto.acct): %}
set wireless.{{ section }}.acct_server={{ crypto.acct.host }}
set wireless.{{ section }}.acct_port={{ crypto.acct.port }}
set wireless.{{ section }}.acct_secret={{ crypto.acct.secret }}
set wireless.{{ section }}.acct_interval={{ crypto.acct.interval }}
{% for (let request in crypto.acct.request_attribute): %}
add_list wireless.{{ section }}.radius_acct_req_attr={{ s(request.id + ':' + request.value) }}
{% endfor %}
{% endif %}
{% if (ssid.pass_point): %}
set wireless.{{ section }}.interworking=1
set wireless.{{ section }}.hs20=1
{% for (let name in ssid.pass_point.venue_name): %}
add_list wireless.{{ section }}.iw_venue_name={{ s(name) }}
{% endfor %}
set wireless.{{ section }}.iw_venue_group='{{ ssid.pass_point.venue_group }}'
set wireless.{{ section }}.iw_venue_type='{{ ssid.pass_point.venue_type }}'
{% for (let n, url in ssid.pass_point.venue_url): %}
add_list wireless.{{ section }}.iw_venue_url={{ s((n + 1) + ":" +url) }}
{% endfor %}
set wireless.{{ section }}.iw_network_auth_type='{{ match_hs20_auth_type(ssid.pass_point.auth_type) }}'
set wireless.{{ section }}.iw_domain_name={{ s(ssid.pass_point.domain_name) }}
{% for (let realm in ssid.pass_point.nai_realm): %}
set wireless.{{ section }}.iw_nai_realm='{{ realm }}'
{% endfor %}
set wireless.{{ section }}.osen={{ b(ssid.pass_point.osen) }}
set wireless.{{ section }}.anqp_domain_id='{{ ssid.pass_point.anqp_domain }}'
{% for (let name in ssid.pass_point.friendly_name): %}
add_list wireless.{{ section }}.hs20_oper_friendly_name={{ s(name) }}
{% endfor %}
{% for (let icon in ssid.pass_point.icon): %}
add_list wireless.{{ section }}.operator_icon={{ s(icon.uri) }}
{% endfor %}
{% endif %}
set wireless.{{ section }}.wds='{{ b(match_wds()) }}'
{% if (ssid.rate_limit && (ssid.rate_limit.ingress_rate || ssid.rate_limit.egress_rate)): %}

View File

@@ -6,7 +6,9 @@ properties:
description:
This parameter can be used to configure one or more Venue Name Duples
for Venue Name ANQP information.
type: string
type: array
items:
type: string
venue-group:
description:
The available values are defined in 802.11u.
@@ -21,8 +23,10 @@ properties:
description:
This parameter can be used to configure one or more Venue URL Duples to
provide additional information corresponding to Venue Name information.
type: string
format: uri
type: array
items:
type: string
format: uri
auth-type:
description:
This parameter indicates what type of network authentication is used in
@@ -56,7 +60,9 @@ properties:
nai-realm:
description:
NAI Realm information
type: string
type: array
items:
type: string
osen:
description:
OSU Server-Only Authenticated L2 Encryption Network;
@@ -72,7 +78,9 @@ properties:
description:
This parameter can be used to configure one or more Operator Friendly
Name Duples.
type: string
type: array
items:
type: string
icon:
description:
The operator icons.

View File

@@ -57,8 +57,3 @@ properties:
value: Example Operator
examples:
- 126:s:Operator
request-cui:
description:
This will enable support for Chargeable-User-Identity (RFC 4372).
type: boolean
default: false

View File

@@ -3,6 +3,16 @@ description:
allowing us to connect to the AAA servers.
type: object
properties:
nas-identifier:
description:
NAS-Identifier string for RADIUS messages. When used, this should be unique
to the NAS within the scope of the RADIUS server.
type: string
chargeable-user-id:
description:
This will enable support for Chargeable-User-Identity (RFC 4372).
type: boolean
default: false
local-users:
description:
Specifies a collection of local EAP user/psk/vid triplets.
@@ -13,11 +23,10 @@ properties:
$ref: "https://ucentral.io/schema/v1/interface/ssid/radius/server/"
accounting:
$ref: "https://ucentral.io/schema/v1/interface/ssid/radius/server/"
properties:
interval:
description:
The interim accounting update interval. This value is defined in seconds.
type: integer
maximum: 600
minimum: 60
default: 60
interval:
description:
The interim accounting update interval. This value is defined in seconds.
type: integer
maximum: 600
minimum: 60
default: 60

View File

@@ -1891,22 +1891,6 @@ function instantiateInterfaceSsidRadiusServer(location, value, errors) {
obj.request_attribute = parseRequestAttribute(location + "/request-attribute", value["request-attribute"], errors);
}
function parseRequestCui(location, value, errors) {
if (type(value) != "bool") {
push(errors, [ location, "must be of type boolean" ]);
return null;
}
return value;
}
if (exists(value, "request-cui")) {
obj.request_cui = parseRequestCui(location + "/request-cui", value["request-cui"], errors);
}
else {
obj.request_cui = false;
}
return obj;
}
@@ -1918,6 +1902,35 @@ function instantiateInterfaceSsidRadius(location, value, errors) {
let obj = {};
function parseNasIdentifier(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
return null;
}
return value;
}
if (exists(value, "nas-identifier")) {
obj.nas_identifier = parseNasIdentifier(location + "/nas-identifier", value["nas-identifier"], errors);
}
function parseChargeableUserId(location, value, errors) {
if (type(value) != "bool") {
push(errors, [ location, "must be of type boolean" ]);
return null;
}
return value;
}
if (exists(value, "chargeable-user-id")) {
obj.chargeable_user_id = parseChargeableUserId(location + "/chargeable-user-id", value["chargeable-user-id"], errors);
}
else {
obj.chargeable_user_id = false;
}
function parseLocalUsers(location, value, errors) {
if (type(value) != "array") {
push(errors, [ location, "must be of type array" ]);
@@ -1951,12 +1964,21 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
let obj = {};
function parseVenueName(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
if (type(value) != "array") {
push(errors, [ location, "must be of type array" ]);
return null;
}
return value;
function parseItem(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
return null;
}
return value;
}
return map(value, (item, i) => parseItem(location + "/" + i, item, errors));
}
if (exists(value, "venue-name")) {
@@ -1996,15 +2018,24 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
}
function parseVenueUrl(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
if (type(value) != "array") {
push(errors, [ location, "must be of type array" ]);
return null;
}
if (!matchUri(value))
push(errors, [ location, "must be a valid URI" ]);
function parseItem(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
return null;
}
return value;
if (!matchUri(value))
push(errors, [ location, "must be a valid URI" ]);
return value;
}
return map(value, (item, i) => parseItem(location + "/" + i, item, errors));
}
if (exists(value, "venue-url")) {
@@ -2075,12 +2106,21 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
}
function parseNaiRealm(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
if (type(value) != "array") {
push(errors, [ location, "must be of type array" ]);
return null;
}
return value;
function parseItem(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
return null;
}
return value;
}
return map(value, (item, i) => parseItem(location + "/" + i, item, errors));
}
if (exists(value, "nai-realm")) {
@@ -2120,12 +2160,21 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
}
function parseFriendlyName(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
if (type(value) != "array") {
push(errors, [ location, "must be of type array" ]);
return null;
}
return value;
function parseItem(location, value, errors) {
if (type(value) != "string") {
push(errors, [ location, "must be of type string" ]);
return null;
}
return value;
}
return map(value, (item, i) => parseItem(location + "/" + i, item, errors));
}
if (exists(value, "friendly-name")) {

View File

@@ -773,16 +773,19 @@
"examples": [
"126:s:Operator"
]
},
"request-cui": {
"type": "boolean",
"default": false
}
}
},
"interface.ssid.radius": {
"type": "object",
"properties": {
"nas-identifier": {
"type": "string"
},
"chargeable-user-id": {
"type": "boolean",
"default": false
},
"local-users": {
"type": "array",
"items": {
@@ -794,13 +797,11 @@
},
"accounting": {
"$ref": "#/$defs/interface.ssid.radius.server",
"properties": {
"interval": {
"type": "integer",
"maximum": 600,
"minimum": 60,
"default": 60
}
"interval": {
"type": "integer",
"maximum": 600,
"minimum": 60,
"default": 60
}
}
}
@@ -809,7 +810,10 @@
"type": "object",
"properties": {
"venue-name": {
"type": "string"
"type": "array",
"items": {
"type": "string"
}
},
"venue-group": {
"type": "integer",
@@ -820,8 +824,11 @@
"maximum": 32
},
"venue-url": {
"type": "string",
"format": "uri"
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"auth-type": {
"type": "object",
@@ -852,7 +859,10 @@
"format": "hostname"
},
"nai-realm": {
"type": "string"
"type": "array",
"items": {
"type": "string"
}
},
"osen": {
"type": "boolean"
@@ -863,7 +873,10 @@
"minimum": 0
},
"friendly-name": {
"type": "string"
"type": "array",
"items": {
"type": "string"
}
},
"icon": {
"type": "array",