Skip to content

Commit fe6a5aa

Browse files
masapnemesifier
authored andcommitted
[feature] OpenWrt: Added support for WPA3-Personal #194
This patch is tested on these. - OpenWrt: latest (4b587f25614f3f7215360f96807ce760fa4ef3aa) - hardware: TP-Link Archer C6 v2 Related to #194 Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
1 parent dc574be commit fe6a5aa

3 files changed

Lines changed: 127 additions & 0 deletions

File tree

netjsonconfig/backends/openwrt/converters/wireless.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def __intermediate_encryption(self, wireless):
9393
'wep_shared': 'wep-shared',
9494
'wpa_personal': 'psk',
9595
'wpa2_personal': 'psk2',
96+
'wpa3_personal': 'sae',
9697
'wpa_personal_mixed': 'psk-mixed',
9798
'wpa_enterprise': 'wpa',
9899
'wpa2_enterprise': 'wpa2',
@@ -121,6 +122,8 @@ def __intermediate_encryption(self, wireless):
121122
uci['key'] = encryption['key']
122123
# add ciphers
123124
cipher = encryption.get('cipher')
125+
if protocol == 'wpa3_personal':
126+
cipher = 'ccmp'
124127
if cipher and protocol.startswith('wpa') and cipher != 'auto':
125128
uci['encryption'] += '+{0}'.format(cipher)
126129
return uci
@@ -254,6 +257,7 @@ def __netjson_encryption(self, wifi):
254257
'wep-shared': 'wep_shared',
255258
'psk': 'wpa_personal',
256259
'psk2': 'wpa2_personal',
260+
'sae': 'wpa3_personal',
257261
'psk-mixed': 'wpa_personal_mixed',
258262
'wpa': 'wpa_enterprise',
259263
'wpa2': 'wpa2_enterprise',

netjsonconfig/schema.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@
358358
"propertyOrder": 20,
359359
"oneOf": [
360360
{"$ref": "#/definitions/encryption_none"},
361+
{"$ref": "#/definitions/encryption_wpa3_personal"},
361362
{"$ref": "#/definitions/encryption_wpa_personal"},
362363
{"$ref": "#/definitions/encryption_wpa_enterprise_ap"},
363364
{"$ref": "#/definitions/encryption_wps"},
@@ -375,6 +376,7 @@
375376
"propertyOrder": 20,
376377
"oneOf": [
377378
{"$ref": "#/definitions/encryption_none"},
379+
{"$ref": "#/definitions/encryption_wpa3_personal"},
378380
{"$ref": "#/definitions/encryption_wpa_personal"},
379381
{"$ref": "#/definitions/encryption_wpa_enterprise_sta"},
380382
{"$ref": "#/definitions/encryption_wep"},
@@ -454,6 +456,35 @@
454456
}
455457
}
456458
},
459+
"encryption_mfp_property_required": {
460+
"required": ["ieee80211w"],
461+
"properties": {
462+
"ieee80211w": {
463+
"type": "string",
464+
"title": "management frame protection",
465+
"enum": ["2"],
466+
"options": {"enum_titles": ["required"]},
467+
"propertyOrder": 4,
468+
}
469+
},
470+
},
471+
"encryption_wpa3_personal": {
472+
"title": "WPA3 only Personal",
473+
"allOf": [
474+
{"$ref": "#/definitions/encryption_base_settings"},
475+
{"$ref": "#/definitions/encryption_cipher_property"},
476+
{"$ref": "#/definitions/encryption_mfp_property_required"},
477+
{
478+
"properties": {
479+
"protocol": {
480+
"enum": ["wpa3_personal"],
481+
"options": {"enum_titles": ["WPA3 Personal"]},
482+
},
483+
"key": {"minLength": 8},
484+
}
485+
},
486+
],
487+
},
457488
"encryption_wpa_personal": {
458489
"title": "WPA2/WPA Personal",
459490
"allOf": [

tests/openwrt/test_encryption.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,53 @@
77
class TestEncryption(unittest.TestCase, _TabsMixin):
88
maxDiff = None
99

10+
_wpa3_personal_netjson = {
11+
"interfaces": [
12+
{
13+
"name": "wlan0",
14+
"type": "wireless",
15+
"wireless": {
16+
"radio": "radio0",
17+
"mode": "access_point",
18+
"ssid": "wpa3-personal",
19+
"encryption": {
20+
"protocol": "wpa3_personal",
21+
"cipher": "ccmp",
22+
"key": "passphrase012345",
23+
"ieee80211w": "2",
24+
},
25+
},
26+
}
27+
]
28+
}
29+
_wpa3_personal_uci = """package network
30+
31+
config interface 'wlan0'
32+
option ifname 'wlan0'
33+
option proto 'none'
34+
35+
package wireless
36+
37+
config wifi-iface 'wifi_wlan0'
38+
option device 'radio0'
39+
option encryption 'sae+ccmp'
40+
option ieee80211w '2'
41+
option ifname 'wlan0'
42+
option key 'passphrase012345'
43+
option mode 'ap'
44+
option network 'wlan0'
45+
option ssid 'wpa3-personal'
46+
"""
47+
48+
def test_render_wpa3_personal(self):
49+
o = OpenWrt(self._wpa3_personal_netjson)
50+
expected = self._tabs(self._wpa3_personal_uci)
51+
self.assertEqual(o.render(), expected)
52+
53+
def test_parse_wpa3_personal(self):
54+
o = OpenWrt(native=self._wpa3_personal_uci)
55+
self.assertEqual(o.config, self._wpa3_personal_netjson)
56+
1057
_wpa2_personal_netjson = {
1158
"interfaces": [
1259
{
@@ -660,3 +707,48 @@ def test_render_wps_ap(self):
660707
def test_parse_wps_ap(self):
661708
o = OpenWrt(native=self._wps_ap_uci)
662709
self.assertEqual(o.config, self._wps_ap_netjson)
710+
711+
def test_render_ieee80211w(self):
712+
_netjson_wpa3_personal_cipher_tkip = {
713+
"interfaces": [
714+
{
715+
"name": "wlan0",
716+
"type": "wireless",
717+
"wireless": {
718+
"radio": "radio0",
719+
"mode": "access_point",
720+
"ssid": "wpa3-personal",
721+
"encryption": {
722+
"protocol": "wpa3_personal",
723+
"cipher": "tkip",
724+
"key": "passphrase012345",
725+
"ieee80211w": "2",
726+
},
727+
},
728+
}
729+
]
730+
}
731+
_uci_wpa3_personal_cipher_tkip = self._tabs(
732+
"""package network
733+
734+
config interface 'wlan0'
735+
option ifname 'wlan0'
736+
option proto 'none'
737+
738+
package wireless
739+
740+
config wifi-iface 'wifi_wlan0'
741+
option device 'radio0'
742+
option encryption 'sae+ccmp'
743+
option ieee80211w '2'
744+
option ifname 'wlan0'
745+
option key 'passphrase012345'
746+
option mode 'ap'
747+
option network 'wlan0'
748+
option ssid 'wpa3-personal'
749+
"""
750+
)
751+
self.assertEqual(
752+
OpenWrt(_netjson_wpa3_personal_cipher_tkip).render(),
753+
_uci_wpa3_personal_cipher_tkip,
754+
)

0 commit comments

Comments
 (0)