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, proto: ssid.encryption.proto,
key: ssid.encryption.key key: ssid.encryption.key
}; };
warn(ssid.encryption.proto);
if (ssid.encryption.proto in [ "wpa", "wpa2", "wpa-mixed", "wpa3", "wpa3-mixed" ] && if (ssid.encryption.proto in [ "wpa", "wpa2", "wpa-mixed", "wpa3", "wpa3-mixed" ] &&
ssid.encryption.radius && ssid.encryption.radius.authentication && ssid.radius && ssid.radius.authentication &&
ssid.encryption.radius.authentication.host && ssid.radius.authentication.host &&
ssid.encryption.radius.authentication.port && ssid.radius.authentication.port &&
ssid.encryption.radius.authentication.secret) ssid.radius.authentication.secret)
return { return {
proto: ssid.encryption.proto, proto: ssid.encryption.proto,
auth: ssid.encryption.ssid.encryption.radius.authentication, auth: ssid.radius.authentication,
acct: ssid.encryption.ssid.encryption.radius.accounting acct: ssid.radius.accounting,
radius: ssid.radius
}; };
warn("Can't find any valid encryption settings");
return false; return false;
} }
@@ -42,6 +45,16 @@
return index([ "wds-ap", "wds-sta", "wds-repeater" ], ssid.bss_mode); 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; let bss_mode = ssid.bss_mode;
if (ssid.bss_mode == "wds-ap") if (ssid.bss_mode == "wds-ap")
bss_mode = "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 }}.ieee80211w={{ match_ieee80211w() }}
set wireless.{{ section }}.encryption={{ crypto.proto }} set wireless.{{ section }}.encryption={{ crypto.proto }}
set wireless.{{ section }}.key={{ crypto.key }} 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): %} {% if (crypto.auth): %}
set wireless.{{ section }}.auth_server={{ crypto.auth.host }} set wireless.{{ section }}.auth_server={{ crypto.auth.host }}
set wireless.{{ section }}.auth_port={{ crypto.auth.port }} set wireless.{{ section }}.auth_port={{ crypto.auth.port }}
set wireless.{{ section }}.auth_secret={{ crypto.auth.secret }} 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 %} {% endif %}
{% if (crypto.acct): %} {% if (crypto.acct): %}
set wireless.{{ section }}.acct_server={{ crypto.acct.host }} set wireless.{{ section }}.acct_server={{ crypto.acct.host }}
set wireless.{{ section }}.acct_port={{ crypto.acct.port }} set wireless.{{ section }}.acct_port={{ crypto.acct.port }}
set wireless.{{ section }}.acct_secret={{ crypto.acct.secret }} set wireless.{{ section }}.acct_secret={{ crypto.acct.secret }}
set wireless.{{ section }}.acct_interval={{ crypto.acct.interval }} 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 %} {% endif %}
set wireless.{{ section }}.wds='{{ b(match_wds()) }}' set wireless.{{ section }}.wds='{{ b(match_wds()) }}'
{% if (ssid.rate_limit && (ssid.rate_limit.ingress_rate || ssid.rate_limit.egress_rate)): %} {% if (ssid.rate_limit && (ssid.rate_limit.ingress_rate || ssid.rate_limit.egress_rate)): %}

View File

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

View File

@@ -57,8 +57,3 @@ properties:
value: Example Operator value: Example Operator
examples: examples:
- 126:s:Operator - 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. allowing us to connect to the AAA servers.
type: object type: object
properties: 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: local-users:
description: description:
Specifies a collection of local EAP user/psk/vid triplets. 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/" $ref: "https://ucentral.io/schema/v1/interface/ssid/radius/server/"
accounting: accounting:
$ref: "https://ucentral.io/schema/v1/interface/ssid/radius/server/" $ref: "https://ucentral.io/schema/v1/interface/ssid/radius/server/"
properties: interval:
interval: description:
description: The interim accounting update interval. This value is defined in seconds.
The interim accounting update interval. This value is defined in seconds. type: integer
type: integer maximum: 600
maximum: 600 minimum: 60
minimum: 60 default: 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); 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; return obj;
} }
@@ -1918,6 +1902,35 @@ function instantiateInterfaceSsidRadius(location, value, errors) {
let obj = {}; 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) { function parseLocalUsers(location, value, errors) {
if (type(value) != "array") { if (type(value) != "array") {
push(errors, [ location, "must be of type array" ]); push(errors, [ location, "must be of type array" ]);
@@ -1951,12 +1964,21 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
let obj = {}; let obj = {};
function parseVenueName(location, value, errors) { function parseVenueName(location, value, errors) {
if (type(value) != "string") { if (type(value) != "array") {
push(errors, [ location, "must be of type string" ]); push(errors, [ location, "must be of type array" ]);
return null; 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")) { if (exists(value, "venue-name")) {
@@ -1996,15 +2018,24 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
} }
function parseVenueUrl(location, value, errors) { function parseVenueUrl(location, value, errors) {
if (type(value) != "string") { if (type(value) != "array") {
push(errors, [ location, "must be of type string" ]); push(errors, [ location, "must be of type array" ]);
return null; return null;
} }
if (!matchUri(value)) function parseItem(location, value, errors) {
push(errors, [ location, "must be a valid URI" ]); 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")) { if (exists(value, "venue-url")) {
@@ -2075,12 +2106,21 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
} }
function parseNaiRealm(location, value, errors) { function parseNaiRealm(location, value, errors) {
if (type(value) != "string") { if (type(value) != "array") {
push(errors, [ location, "must be of type string" ]); push(errors, [ location, "must be of type array" ]);
return null; 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")) { if (exists(value, "nai-realm")) {
@@ -2120,12 +2160,21 @@ function instantiateInterfaceSsidPassPoint(location, value, errors) {
} }
function parseFriendlyName(location, value, errors) { function parseFriendlyName(location, value, errors) {
if (type(value) != "string") { if (type(value) != "array") {
push(errors, [ location, "must be of type string" ]); push(errors, [ location, "must be of type array" ]);
return null; 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")) { if (exists(value, "friendly-name")) {

View File

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