Skip to content

Commit 5bbdd6b

Browse files
authored
[feature] OpenWrt: added support for EAP-PEAP
This patch adds an input field for authentication methods and updates the relevant documentation section for wireless station with WPA enterprise. EAP-TTLS/EAP-PEAP supports various authentication methods, but it used to be fixed to PAP because there was no input field for authentication methods. This patch is tested on these. - RADIUS authentication server: FreeRadius 3.0.25 - OpenWrt: latest (1b311aab3141bbea5667be4517e2599e6235cca0) - hardware: TP-Link Archer C6 v2 Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
1 parent 4ebbc8a commit 5bbdd6b

4 files changed

Lines changed: 304 additions & 14 deletions

File tree

docs/source/backends/openwrt.rst

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ UCI Output::
12251225
WPA2 Enterprise (802.1x) client
12261226
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12271227

1228-
*WPA2 Enterprise (802.1x)* client example:
1228+
*WPA2 Enterprise (802.1x)* client with EAP-TLS example:
12291229

12301230
.. code-block:: python
12311231
@@ -1438,6 +1438,106 @@ UCI Output::
14381438
option password 'test-password'
14391439
option ssid 'enterprise-client'
14401440

1441+
*WPA2 Enterprise (802.1x)* client with EAP-TTLS example:
1442+
1443+
.. code-block:: python
1444+
1445+
{
1446+
"interfaces": [
1447+
{
1448+
"name": "wlan0",
1449+
"type": "wireless",
1450+
"wireless": {
1451+
"radio": "radio0",
1452+
"mode": "station",
1453+
"ssid": "enterprise-client",
1454+
"bssid": "00:26:b9:20:5f:09",
1455+
"encryption": {
1456+
"protocol": "wpa2_enterprise",
1457+
"cipher": "auto",
1458+
"eap_type": "ttls",
1459+
"auth": "MSCHAPV2",
1460+
"identity": "test-identity",
1461+
"password": "test-password",
1462+
},
1463+
},
1464+
}
1465+
]
1466+
}
1467+
1468+
UCI Output::
1469+
1470+
package network
1471+
1472+
config interface 'wlan0'
1473+
option ifname 'wlan0'
1474+
option proto 'none'
1475+
1476+
package wireless
1477+
1478+
config wifi-iface 'wifi_wlan0'
1479+
option auth 'MSCHAPV2'
1480+
option bssid '00:26:b9:20:5f:09'
1481+
option device 'radio0'
1482+
option eap_type 'ttls'
1483+
option encryption 'wpa2'
1484+
option identity 'test-identity'
1485+
option ifname 'wlan0'
1486+
option mode 'sta'
1487+
option network 'wlan0'
1488+
option password 'test-password'
1489+
option ssid 'enterprise-client'
1490+
1491+
*WPA2 Enterprise (802.1x)* client with EAP-PEAP example:
1492+
1493+
.. code-block:: python
1494+
1495+
{
1496+
"interfaces": [
1497+
{
1498+
"name": "wlan0",
1499+
"type": "wireless",
1500+
"wireless": {
1501+
"radio": "radio0",
1502+
"mode": "station",
1503+
"ssid": "enterprise-client",
1504+
"bssid": "00:26:b9:20:5f:09",
1505+
"encryption": {
1506+
"protocol": "wpa2_enterprise",
1507+
"cipher": "auto",
1508+
"eap_type": "peap",
1509+
"auth": "EAP-MSCHAPV2",
1510+
"identity": "test-identity",
1511+
"password": "test-password",
1512+
},
1513+
},
1514+
}
1515+
]
1516+
}
1517+
1518+
UCI Output::
1519+
1520+
package network
1521+
1522+
config interface 'wlan0'
1523+
option ifname 'wlan0'
1524+
option proto 'none'
1525+
1526+
package wireless
1527+
1528+
config wifi-iface 'wifi_wlan0'
1529+
option auth 'EAP-MSCHAPV2'
1530+
option bssid '00:26:b9:20:5f:09'
1531+
option device 'radio0'
1532+
option eap_type 'peap'
1533+
option encryption 'wpa2'
1534+
option identity 'test-identity'
1535+
option ifname 'wlan0'
1536+
option mode 'sta'
1537+
option network 'wlan0'
1538+
option password 'test-password'
1539+
option ssid 'enterprise-client'
1540+
14411541
Dialup settings
14421542
---------------
14431543

netjsonconfig/backends/openwrt/converters/wireless.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,16 @@ def __intermediate_encryption(self, wireless):
121121
# tell hostapd/wpa_supplicant key is not hex format
122122
if protocol == 'wep_open':
123123
uci['key1'] = 's:{0}'.format(uci['key1'])
124-
elif 'key' in encryption:
125-
uci['key'] = encryption['key']
124+
else:
125+
if (
126+
'enterprise' in protocol
127+
and 'eap_type' in uci
128+
and uci['eap_type'] == 'tls'
129+
and 'auth' in uci
130+
):
131+
del uci['auth']
132+
if 'key' in encryption:
133+
uci['key'] = encryption['key']
126134
# add ciphers
127135
cipher = encryption.get('cipher')
128136
if cipher and protocol.startswith('wpa') and cipher != 'auto':

netjsonconfig/schema.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -597,31 +597,58 @@
597597
"eap_type": {
598598
"title": "EAP protocol",
599599
"type": "string",
600-
"enum": ["tls", "ttls"],
601-
"options": {"enum_titles": ["EAP-TLS", "EAP-TTLS"]},
600+
"enum": ["tls", "ttls", "peap"],
601+
"options": {"enum_titles": ["EAP-TLS", "EAP-TTLS", "EAP-PEAP"]},
602602
"propertyOrder": 4,
603603
},
604-
"identity": {"type": "string", "propertyOrder": 5},
605-
"password": {"type": "string", "propertyOrder": 6},
604+
"auth": {
605+
"title": "authentication",
606+
"type": "string",
607+
"enum": [
608+
"PAP",
609+
"CHAP",
610+
"MSCHAP",
611+
"MSCHAPV2",
612+
"EAP-GTC",
613+
"EAP-MD5",
614+
"EAP-MSCHAPV2",
615+
"EAP-TLS",
616+
],
617+
"options": {
618+
"enum_titles": [
619+
"PAP",
620+
"CHAP",
621+
"MSCHAP",
622+
"MSCHAPv2",
623+
"EAP-GTC",
624+
"EAP-MD5",
625+
"EAP-MSCHAPv2",
626+
"EAP-TLS",
627+
]
628+
},
629+
"propertyOrder": 5,
630+
},
631+
"identity": {"type": "string", "propertyOrder": 6},
632+
"password": {"type": "string", "propertyOrder": 7},
606633
"ca_cert": {
607634
"type": "string",
608635
"title": "CA certificate (path)",
609-
"propertyOrder": 7,
636+
"propertyOrder": 8,
610637
},
611638
"client_cert": {
612639
"type": "string",
613640
"title": "client certificate (path)",
614-
"propertyOrder": 8,
641+
"propertyOrder": 9,
615642
},
616643
"priv_key": {
617644
"type": "string",
618645
"title": "private key (path)",
619-
"propertyOrder": 9,
646+
"propertyOrder": 10,
620647
},
621648
"priv_key_pwd": {
622649
"type": "string",
623650
"title": "private key password",
624-
"propertyOrder": 10,
651+
"propertyOrder": 11,
625652
},
626653
},
627654
},

tests/openwrt/test_encryption.py

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ def test_parse_wpa3_enterprise_client(self):
554554
o = OpenWrt(native=self._wpa3_enterprise_client_uci)
555555
self.assertEqual(o.config, self._wpa3_enterprise_client_netjson)
556556

557-
_wpa2_enterprise_client_netjson = {
557+
_wpa2_enterprise_tls_client_netjson = {
558558
"interfaces": [
559559
{
560560
"name": "wlan0",
@@ -599,13 +599,168 @@ def test_parse_wpa3_enterprise_client(self):
599599
"""
600600

601601
def test_render_wpa2_enterprise_client(self):
602-
o = OpenWrt(self._wpa2_enterprise_client_netjson)
602+
o = OpenWrt(self._wpa2_enterprise_tls_client_netjson)
603603
expected = self._tabs(self._wpa2_enterprise_client_uci)
604604
self.assertEqual(o.render(), expected)
605605

606606
def test_parse_wpa2_enterprise_client(self):
607607
o = OpenWrt(native=self._wpa2_enterprise_client_uci)
608-
self.assertEqual(o.config, self._wpa2_enterprise_client_netjson)
608+
self.assertEqual(o.config, self._wpa2_enterprise_tls_client_netjson)
609+
610+
_wpa2_enterprise_ttls_client_netjson = {
611+
"interfaces": [
612+
{
613+
"name": "wlan0",
614+
"type": "wireless",
615+
"wireless": {
616+
"radio": "radio0",
617+
"mode": "station",
618+
"ssid": "enterprise-client",
619+
"bssid": "00:26:b9:20:5f:09",
620+
"encryption": {
621+
"protocol": "wpa2_enterprise",
622+
"cipher": "auto",
623+
"eap_type": "ttls",
624+
"auth": "MSCHAPV2",
625+
"identity": "test-identity",
626+
"password": "test-password",
627+
},
628+
},
629+
}
630+
]
631+
}
632+
_wpa2_enterprise_ttls_client_uci = """package network
633+
634+
config interface 'wlan0'
635+
option ifname 'wlan0'
636+
option proto 'none'
637+
638+
package wireless
639+
640+
config wifi-iface 'wifi_wlan0'
641+
option auth 'MSCHAPV2'
642+
option bssid '00:26:b9:20:5f:09'
643+
option device 'radio0'
644+
option eap_type 'ttls'
645+
option encryption 'wpa2'
646+
option identity 'test-identity'
647+
option ifname 'wlan0'
648+
option mode 'sta'
649+
option network 'wlan0'
650+
option password 'test-password'
651+
option ssid 'enterprise-client'
652+
"""
653+
654+
def test_render_wpa2_enterprise_ttls_client(self):
655+
o = OpenWrt(self._wpa2_enterprise_ttls_client_netjson)
656+
expected = self._tabs(self._wpa2_enterprise_ttls_client_uci)
657+
self.assertEqual(o.render(), expected)
658+
659+
def test_parse_wpa2_enterprise_ttls_client(self):
660+
o = OpenWrt(native=self._wpa2_enterprise_ttls_client_uci)
661+
self.assertEqual(o.config, self._wpa2_enterprise_ttls_client_netjson)
662+
663+
_wpa2_enterprise_peap_client_netjson = {
664+
"interfaces": [
665+
{
666+
"name": "wlan0",
667+
"type": "wireless",
668+
"wireless": {
669+
"radio": "radio0",
670+
"mode": "station",
671+
"ssid": "enterprise-client",
672+
"bssid": "00:26:b9:20:5f:09",
673+
"encryption": {
674+
"protocol": "wpa2_enterprise",
675+
"cipher": "auto",
676+
"eap_type": "peap",
677+
"auth": "EAP-MSCHAPV2",
678+
"identity": "test-identity",
679+
"password": "test-password",
680+
},
681+
},
682+
}
683+
]
684+
}
685+
_wpa2_enterprise_peap_client_uci = """package network
686+
687+
config interface 'wlan0'
688+
option ifname 'wlan0'
689+
option proto 'none'
690+
691+
package wireless
692+
693+
config wifi-iface 'wifi_wlan0'
694+
option auth 'EAP-MSCHAPV2'
695+
option bssid '00:26:b9:20:5f:09'
696+
option device 'radio0'
697+
option eap_type 'peap'
698+
option encryption 'wpa2'
699+
option identity 'test-identity'
700+
option ifname 'wlan0'
701+
option mode 'sta'
702+
option network 'wlan0'
703+
option password 'test-password'
704+
option ssid 'enterprise-client'
705+
"""
706+
707+
def test_render_wpa2_enterprise_peap_client(self):
708+
o = OpenWrt(self._wpa2_enterprise_peap_client_netjson)
709+
expected = self._tabs(self._wpa2_enterprise_peap_client_uci)
710+
self.assertEqual(o.render(), expected)
711+
712+
def test_parse_wpa2_enterprise_peap_client(self):
713+
o = OpenWrt(native=self._wpa2_enterprise_peap_client_uci)
714+
self.assertEqual(o.config, self._wpa2_enterprise_peap_client_netjson)
715+
716+
_wpa2_enterprise_tls_client_auth_netjson = {
717+
"interfaces": [
718+
{
719+
"name": "wlan0",
720+
"type": "wireless",
721+
"wireless": {
722+
"radio": "radio0",
723+
"mode": "station",
724+
"ssid": "enterprise-client",
725+
"bssid": "00:26:b9:20:5f:09",
726+
"encryption": {
727+
"protocol": "wpa2_enterprise",
728+
"cipher": "auto",
729+
"eap_type": "tls",
730+
"auth": "MSCHAPV2",
731+
"identity": "test-identity",
732+
"password": "test-password",
733+
},
734+
},
735+
}
736+
]
737+
}
738+
739+
_wpa2_enterprise_tls_client_auth_uci = """package network
740+
741+
config interface 'wlan0'
742+
option ifname 'wlan0'
743+
option proto 'none'
744+
745+
package wireless
746+
747+
config wifi-iface 'wifi_wlan0'
748+
option bssid '00:26:b9:20:5f:09'
749+
option device 'radio0'
750+
option eap_type 'tls'
751+
option encryption 'wpa2'
752+
option identity 'test-identity'
753+
option ifname 'wlan0'
754+
option mode 'sta'
755+
option network 'wlan0'
756+
option password 'test-password'
757+
option ssid 'enterprise-client'
758+
"""
759+
760+
def test_render_wpa2_enterprise_tls_client_auth(self):
761+
o = OpenWrt(self._wpa2_enterprise_tls_client_auth_netjson)
762+
expected = self._tabs(self._wpa2_enterprise_tls_client_auth_uci)
763+
self.assertEqual(o.render(), expected)
609764

610765
_wep_open_netjson = {
611766
"interfaces": [

0 commit comments

Comments
 (0)