wifi-scripts: ucode: fix EAP certificate constraint handling

The supplicant config generator emitted the altsubject_match,
domain_match and domain_suffix_match server certificate constraints
through the plain (unquoted) variable list. As these are UCI arrays,
they were rendered space-separated and without quotes, e.g.

  altsubject_match=DNS:a.example.com DNS:b.example.com

wpa_supplicant parses an unquoted string value as a hex blob, so such a
line fails to parse and the constraint is dropped. wpa_supplicant
expects a single quoted, semicolon-separated string:

  altsubject_match="DNS:a.example.com;DNS:b.example.com"

Join these lists with semicolons and emit them as quoted strings.

The inner-tunnel (phase 2) constraints subject_match2, altsubject_match2,
domain_match2 and domain_suffix_match2 were not written to the config at
all; emit them as well. Add the matching inner EAP-TLS options ca_cert2,
client_cert2, private_key2 and private_key2_passwd to the schema so they
validate cleanly.

Fixes: 218f3884d2 ("wifi-scripts: add ucode based scripts")
Assisted-by: Claude:claude-opus-4-8
Link: https://github.com/openwrt/openwrt/pull/24088
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Hauke Mehrtens 2026-07-05 19:38:25 +02:00
parent 0cdf956ee1
commit 7be144ad83
2 changed files with 32 additions and 2 deletions

View file

@ -196,6 +196,10 @@
"description": "Specifies the path the CA certificate used for authentication",
"type": "string"
},
"ca_cert2": {
"description": "Path to the inner-tunnel (phase 2) CA certificate for EAP-TLS",
"type": "string"
},
"ca_cert2_usesystem": {
"type": "boolean"
},
@ -215,6 +219,10 @@
"description": "File path to client certificate file (PEM/DER)",
"type": "string"
},
"client_cert2": {
"description": "File path to the inner-tunnel (phase 2) client certificate for EAP-TLS",
"type": "string"
},
"dae_client": {
"type": "alias",
"default": "radius_das_client"
@ -854,10 +862,18 @@
"description": "Private key matching with the server certificate for EAP-TLS/PEAP/TTLS",
"type": "string"
},
"private_key2": {
"description": "Inner-tunnel (phase 2) private key for EAP-TLS",
"type": "string"
},
"private_key_passwd": {
"description": "Passphrase for private key",
"type": "string"
},
"private_key2_passwd": {
"description": "Passphrase for the inner-tunnel (phase 2) private key",
"type": "string"
},
"proxy_arp": {
"description": "Proxy ARP",
"type": "boolean"

View file

@ -211,9 +211,24 @@ function setup_sta(data, config) {
config.mcast_rate = ratestr(config.mcast_rate);
/*
* Certificate constraint lists are semicolon-separated strings in the
* wpa_supplicant config, while UCI stores them as arrays. Join them here
* so they are emitted as a single quoted value below.
*/
for (let key in [ 'altsubject_match', 'altsubject_match2',
'domain_match', 'domain_match2',
'domain_suffix_match', 'domain_suffix_match2' ])
if (type(config[key]) == 'array')
config[key] = length(config[key]) ? join(';', config[key]) : null;
network_append_string_vars(config, [ 'ssid',
'identity', 'anonymous_identity', 'password',
'ca_cert', 'ca_cert2', 'client_cert', 'client_cert2', 'subject_match',
'ca_cert', 'ca_cert2', 'client_cert', 'client_cert2',
'subject_match', 'subject_match2',
'altsubject_match', 'altsubject_match2',
'domain_match', 'domain_match2',
'domain_suffix_match', 'domain_suffix_match2',
'private_key', 'private_key_passwd', 'private_key2', 'private_key2_passwd',
]);
network_append_vars(config, [
@ -222,7 +237,6 @@ function setup_sta(data, config) {
'proto', 'mesh_fwding', 'mesh_rssi_threshold', 'frequency', 'fixed_freq',
'disable_ht', 'disable_ht40', 'disable_vht', 'vht', 'max_oper_chwidth',
'ht40', 'beacon_int', 'ieee80211w', 'rates', 'mesh_basic_rates', 'mcast_rate',
'altsubject_match', 'domain_match', 'domain_suffix_match',
'bssid_blacklist', 'bssid_whitelist', 'erp', 'eap', 'phase2',
'dpp_connector', 'dpp_csign', 'dpp_netaccesskey',
]);