From 90d090d28dc4c209c0ae39cf844357b05def46e4 Mon Sep 17 00:00:00 2001 From: isaacyang Date: Fri, 13 Dec 2024 18:51:22 +0800 Subject: [PATCH] wifi: add support for wpa-psk-sha256 https://pad.lv/2085320 https://pad.lv/2084237 --- doc/netplan-yaml.md | 3 +- src/abi.h | 1 + src/names.c | 1 + src/networkd.c | 4 +++ src/nm.c | 1 + src/parse-nm.c | 3 ++ src/parse.c | 7 +++++ src/util.c | 1 + tests/generator/test_wifis.py | 54 +++++++++++++++++++++++++++++++++++ tests/parser/test_keyfile.py | 51 +++++++++++++++++++++++++++++++++ 10 files changed, 125 insertions(+), 1 deletion(-) diff --git a/doc/netplan-yaml.md b/doc/netplan-yaml.md index d6c1cb400..b22755755 100644 --- a/doc/netplan-yaml.md +++ b/doc/netplan-yaml.md @@ -910,7 +910,8 @@ interfaces, as well as individual Wi-Fi networks, by means of the `auth` block. - **`key-management`** (scalar) > The supported key management modes are `none` (no key management); - > `psk` (WPA with pre-shared key, common for home Wi-Fi); `eap` (WPA + > `psk` (WPA with pre-shared key, common for home Wi-Fi); `psk-sha256` + > (WPA2 with pre-shared key, common for home Wi-Fi); `eap` (WPA > with EAP, common for enterprise Wi-Fi); `eap-sha256` (used with WPA3-Enterprise); > `eap-suite-b-192` (used with WPA3-Enterprise); `sae` (used by WPA3); > and `802.1x` (used primarily for wired Ethernet connections). diff --git a/src/abi.h b/src/abi.h index b4b19453c..3bb25d31d 100644 --- a/src/abi.h +++ b/src/abi.h @@ -145,6 +145,7 @@ typedef enum { NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192, NETPLAN_AUTH_KEY_MANAGEMENT_8021X, NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE, + NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSKSHA256, NETPLAN_AUTH_KEY_MANAGEMENT_MAX, } NetplanAuthKeyManagementType; diff --git a/src/names.c b/src/names.c index 69ac0ffc3..9c1a91ded 100644 --- a/src/names.c +++ b/src/names.c @@ -59,6 +59,7 @@ static const char* const netplan_auth_key_management_type_to_str[NETPLAN_AUTH_KEY_MANAGEMENT_MAX] = { [NETPLAN_AUTH_KEY_MANAGEMENT_NONE] = "none", [NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK] = "psk", + [NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSKSHA256] = "psk-sha256", [NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP] = "eap", [NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256] = "eap-sha256", [NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192] = "eap-suite-b-192", diff --git a/src/networkd.c b/src/networkd.c index aed0273f6..982d18cb9 100644 --- a/src/networkd.c +++ b/src/networkd.c @@ -1188,6 +1188,10 @@ append_wpa_auth_conf(GString* s, const NetplanAuthenticationSettings* auth, cons g_string_append(s, " key_mgmt=WPA-PSK\n"); break; + case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSKSHA256: + g_string_append(s, " key_mgmt=WPA-PSK WPA-PSK-SHA256\n"); + break; + case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP: g_string_append(s, " key_mgmt=WPA-EAP\n"); break; diff --git a/src/nm.c b/src/nm.c index 573d62a27..3a449841b 100644 --- a/src/nm.c +++ b/src/nm.c @@ -514,6 +514,7 @@ write_wifi_auth_parameters(const NetplanAuthenticationSettings* auth, GKeyFile * case NETPLAN_AUTH_KEY_MANAGEMENT_NONE: break; case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK: + case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSKSHA256: g_key_file_set_string(kf, "wifi-security", "key-mgmt", "wpa-psk"); break; case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP: diff --git a/src/parse-nm.c b/src/parse-nm.c index 3708f594b..3d4f6d380 100644 --- a/src/parse-nm.c +++ b/src/parse-nm.c @@ -1019,6 +1019,9 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e */ if (ap->auth.key_management == NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP) ap->auth.key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256; + /*The same logic is used for WPA-PSK*/ + else if (ap->auth.key_management == NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK) + ap->auth.key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSKSHA256; break; case 3: diff --git a/src/parse.c b/src/parse.c index db9c8d4fd..64a9a809f 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1015,6 +1015,13 @@ handle_auth_key_management(NetplanParser* npp, yaml_node_t* node, __unused const auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_NONE; else if (strcmp(scalar(node), "psk") == 0) auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK; + else if (strcmp(scalar(node), "psk-sha256") == 0) { + /* WPA-PSK-SHA256 is commonly used with Protected Management Frames + * so let's set it as optional + */ + auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSKSHA256; + auth->pmf_mode = NETPLAN_AUTH_PMF_MODE_OPTIONAL; + } else if (strcmp(scalar(node), "eap") == 0) auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP; else if (strcmp(scalar(node), "eap-sha256") == 0) { diff --git a/src/util.c b/src/util.c index 294a2f457..1b2852dce 100644 --- a/src/util.c +++ b/src/util.c @@ -1235,6 +1235,7 @@ gboolean _is_auth_key_management_psk(const NetplanAuthenticationSettings* auth) { return ( auth->key_management == NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK + || auth->key_management == NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSKSHA256 || auth->key_management == NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE); } diff --git a/tests/generator/test_wifis.py b/tests/generator/test_wifis.py index 5809b40e7..f7c4645e2 100644 --- a/tests/generator/test_wifis.py +++ b/tests/generator/test_wifis.py @@ -275,6 +275,27 @@ def test_wifi_wowlan_default(self): self.assertTrue(os.path.islink(os.path.join( self.workdir.name, 'run/systemd/system/systemd-networkd.service.wants/netplan-wpa-wl0.service'))) + def test_wifi_wpa_sha256(self): + self.generate('''network: + version: 2 + wifis: + wl0: + access-points: + homenet: + auth: + key-management: psk-sha256 + password: "********"''') + + self.assert_wpa_supplicant("wl0", """ctrl_interface=/run/wpa_supplicant + +network={ + ssid=P"homenet" + key_mgmt=WPA-PSK WPA-PSK-SHA256 + ieee80211w=1 + psk="********" +} +""") + def test_wifi_wpa3_personal(self): self.generate('''network: version: 2 @@ -794,6 +815,39 @@ def test_wifi_adhoc_wpa_5ghz(self): } """) + def test_wifi_wpa_sha256(self): + self.generate('''network: + version: 2 + renderer: NetworkManager + wifis: + wl0: + access-points: + homenet: + auth: + key-management: psk-sha256 + password: "********"''') + + self.assert_nm({'wl0-homenet': '''[connection] +id=netplan-wl0-homenet +type=wifi +interface-name=wl0 + +[ipv4] +method=link-local + +[ipv6] +method=ignore + +[wifi] +ssid=homenet +mode=infrastructure + +[wifi-security] +key-mgmt=wpa-psk +pmf=2 +psk=******** +'''}) + def test_wifi_wpa3_personal(self): self.generate('''network: version: 2 diff --git a/tests/parser/test_keyfile.py b/tests/parser/test_keyfile.py index e178f7729..1781f1c42 100644 --- a/tests/parser/test_keyfile.py +++ b/tests/parser/test_keyfile.py @@ -1505,6 +1505,57 @@ def test_keyfile_wpa3_sae(self): name: "test2" '''.format(UUID, UUID)}) + def test_keyfile_wpa_sha256(self): + self.generate_from_keyfile('''[connection] +id=test2 +uuid={} +type=wifi +interface-name=wlan0 + +[wifi] +mode=infrastructure +ssid=ubuntu-wpa-sha256 + +[wifi-security] +key-mgmt=wpa-psk +pmf=2 +psk=test1234 + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=stable-privacy +method=auto + +[proxy] +'''.format(UUID)) + self.assert_netplan({UUID: '''network: + version: 2 + wifis: + NM-{}: + renderer: NetworkManager + match: + name: "wlan0" + dhcp4: true + dhcp6: true + ipv6-address-generation: "stable-privacy" + access-points: + "ubuntu-wpa-sha256": + auth: + key-management: "psk-sha256" + password: "test1234" + networkmanager: + uuid: "ff9d6ebc-226d-4f82-a485-b7ff83b9607f" + name: "test2" + passthrough: + ipv6.ip6-privacy: "-1" + proxy._: "" + networkmanager: + uuid: "{}" + name: "test2" +'''.format(UUID, UUID)}) + def test_keyfile_wpa3_enterprise_eap_sha256(self): self.generate_from_keyfile('''[connection] id=test2