diff --git a/.yamllint.yml b/.yamllint.yml index fd511b7..7ee87dd 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -19,12 +19,15 @@ rules: truthy: disable line-length: ignore: | - /tests/tests_wireless_plugin_installation_nm.yml - /tests/tests_team_plugin_installation_nm.yml + /tests/tasks/setup_mock_wifi_wpa3_owe.yml + /tests/tasks/setup_mock_wifi_wpa3_sae.yml /tests/tests_ethtool_coalesce_initscripts.yml /tests/tests_ethtool_ring_initscripts.yml + /tests/tests_team_plugin_installation_nm.yml + /tests/tests_wireless_plugin_installation_nm.yml /tests/tests_wireless_wpa3_owe_nm.yml /tests/tasks/setup_mock_wifi_wpa3_owe.yml /tests/tests_auto_gateway_initscripts.yml /tests/tests_bond_deprecated_initscripts.yml /tests/tests_ethtool_features_initscripts.yml + /tests/tests_wireless_wpa3_sae_nm.yml diff --git a/README.md b/README.md index 078217c..dc2a9a5 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ the ansible role. #### `type: wireless` The `wireless` type supports WPA-PSK (password) authentication, WPA-EAP (802.1x) -authentication, and Enhanced Open (OWE). +authentication, WPA3-Personal SAE (password) authentication and Enhanced Open (OWE). `nm` (NetworkManager) is the only supported `network_provider` for this type. @@ -276,10 +276,11 @@ The following options are supported: Any key from following key list: - `owe` + - `sae` - `wpa-eap` - `wpa-psk` -- `password`: password for the network (required if `wpa-psk` is used) +- `password`: password for the network (required if `wpa-psk` or `sae` is used) ### `autoconnect` diff --git a/examples/wireless_wpa3_sae.yml b/examples/wireless_wpa3_sae.yml new file mode 100644 index 0000000..d6c86a8 --- /dev/null +++ b/examples/wireless_wpa3_sae.yml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: BSD-3-Clause +--- +- hosts: network-test + vars: + network_connections: + - name: wlan0 + type: wireless + wireless: + ssid: "My WPA3-Personal Network" + key_mgmt: "sae" + # recommend vault encrypting the wireless password + # see https://docs.ansible.com/ansible/latest/user_guide/vault.html + password: "p@55w0rD" + + + roles: + - linux-system-roles.network diff --git a/library/network_connections.py b/library/network_connections.py index cb14577..0023623 100644 --- a/library/network_connections.py +++ b/library/network_connections.py @@ -925,7 +925,10 @@ class NMUtil: connection["wireless"]["key_mgmt"], ) - if connection["wireless"]["key_mgmt"] == "wpa-psk": + if ( + connection["wireless"]["key_mgmt"] == "wpa-psk" + or connection["wireless"]["key_mgmt"] == "sae" + ): s_wireless_sec.set_property( NM.SETTING_WIRELESS_SECURITY_PSK, connection["wireless"]["password"] ) diff --git a/module_utils/network_lsr/argument_validator.py b/module_utils/network_lsr/argument_validator.py index 189e0b2..6f953b7 100644 --- a/module_utils/network_lsr/argument_validator.py +++ b/module_utils/network_lsr/argument_validator.py @@ -1218,9 +1218,10 @@ class ArgValidator_Dict802_1X(ArgValidatorDict): class ArgValidator_DictWireless(ArgValidatorDict): VALID_KEY_MGMT = [ - "wpa-psk", - "wpa-eap", "owe", + "sae", + "wpa-eap", + "wpa-psk", ] def __init__(self): @@ -1238,17 +1239,19 @@ class ArgValidator_DictWireless(ArgValidatorDict): ) def _validate_post(self, value, name, result): - if result["key_mgmt"] == "wpa-psk": + if result["key_mgmt"] == "wpa-psk" or result["key_mgmt"] == "sae": if result["password"] is None: raise ValidationError( name, - "must supply a password if using 'wpa-psk' key management", + "must supply a password if using {0} key management".format( + result["key_mgmt"] + ), ) else: if result["password"] is not None: raise ValidationError( name, - "password only allowed if using 'wpa-psk' key management", + "password only allowed if using 'wpa-psk' or 'sae' key management", ) return result diff --git a/tests/ensure_provider_tests.py b/tests/ensure_provider_tests.py index df36d5b..73b502c 100755 --- a/tests/ensure_provider_tests.py +++ b/tests/ensure_provider_tests.py @@ -95,6 +95,12 @@ RHEL 7(dist-tag). Failed in setting up mock wifi on RHEL 8", ansible_distribution == 'CentOS' or\n ansible_distribution_major_version > '32' \ and ansible_distribution == 'Fedora'", }, + "playbooks/tests_wireless_wpa3_sae.yml": { + "comment": "# SAE has not been supported by NetworkManager 1.18.8 on \ +RHEL 7. Failed in setting up mock wifi on RHEL 8", + EXTRA_RUN_CONDITION: "ansible_distribution_major_version != '7' and \ +ansible_distribution != 'RedHat'", + }, } # NM_CONDITIONAL_TESTS is used to store the test playbooks which are demanding for NM # minimum version or extra running condition, test playbooks in NM_CONDITIONAL_TESTS diff --git a/tests/playbooks/tests_wireless_wpa3_sae.yml b/tests/playbooks/tests_wireless_wpa3_sae.yml new file mode 100644 index 0000000..c18a468 --- /dev/null +++ b/tests/playbooks/tests_wireless_wpa3_sae.yml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: BSD-3-Clause +--- +- hosts: all + vars: + interface: wlan0 + tasks: + - name: "INIT: wireless tests" + include_tasks: tasks/setup_mock_wifi_wpa3_sae.yml + when: ansible_distribution in ['CentOS', 'Fedora'] + + - name: "TEST: wireless connection with WPA3 Personal" + import_role: + name: linux-system-roles.network + vars: + network_allow_restart: true + network_connections: + - name: "{{ interface }}" + # set `state: down` on RHEL 8 since we failed in setting up mock + # wifi on RHEL 8 + state: "{{ 'down' if ansible_distribution == 'RedHat' else 'up' }}" + type: wireless + ip: + address: + - 203.0.113.2/24 + dhcp4: "no" + auto6: "no" + wireless: + ssid: "hostapd-sae" + key_mgmt: "sae" + password: "p@55w0rD" + + - name: Verify wireless profile KEY_MGMT entry + shell: | + set -euxo pipefail + nmcli c show {{ interface }} | grep 802-11-wireless-security.key-mgmt + register: key_mgmt + ignore_errors: yes + changed_when: false + + - name: "Assert that WPA3 Personal is configured correctly" + assert: + that: + - "'sae' in key_mgmt.stdout" + msg: "WPA3 Personal is configured incorrectly" diff --git a/tests/tasks/setup_mock_wifi_wpa3_sae.yml b/tests/tasks/setup_mock_wifi_wpa3_sae.yml new file mode 100644 index 0000000..61674fd --- /dev/null +++ b/tests/tasks/setup_mock_wifi_wpa3_sae.yml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: BSD-3-Clause +--- +- name: Install packages required to set up mock wifi network + package: + name: + - NetworkManager + - wpa_supplicant + state: present + +# Even though hostapd can be installed via EPEL 8, Simultaneous Authentication +# of Equals (SAE) has not been enabled by default. To warrant the test support +# on CentOS 8, we setup hostapd copr repo to enable SAE option. +- name: install hostapd and mac80211_hwsim kernel module in CentOS 8 + shell: | + dnf -y copr enable liangwen12year/hostapd-owe + dnf -y install hostapd + release=$(uname -r) + tmp="${release/-//}" + tmp="${tmp/.x//x}" + dnf -y install https://koji.mbox.centos.org/pkgs/packages/kernel/$tmp/kernel-core-$release.rpm + dnf -y install https://koji.mbox.centos.org/pkgs/packages/kernel/$tmp/kernel-modules-$release.rpm + dnf -y install https://koji.mbox.centos.org/pkgs/packages/kernel/$tmp/kernel-modules-internal-$release.rpm + when: + - ansible_distribution_major_version == '8' + - ansible_distribution == 'CentOS' + +- name: install hostapd in Fedora + package: + name: + - hostapd + state: present + when: + - ansible_distribution == 'Fedora' + +# Since DNF package manager can not warrant installing the kernel module with the same +# version as the kernel in target machine, install the kernel module from koji instead +- name: install mac80211_hwsim kernel module in Fedora + shell: | + dnf -y install koji + koji download-build --arch=$(uname -p) kernel-modules-internal-$(uname -r) + dnf -y install kernel-modules*.rpm + args: + warn: false + when: + - ansible_distribution == 'Fedora' + +- name: Create hostapd config + copy: + content: | + interface=wlan1 + ssid=hostapd-sae + hw_mode=g + channel=6 + wpa=2 + wpa_passphrase=p@55w0rD + wpa_key_mgmt=SAE + rsn_pairwise=CCMP + ieee80211w=2 + dest: /etc/hostapd/wireless.conf + mode: "0644" + +- include_tasks: tasks/start_mock_wifi.yml diff --git a/tests/tests_wireless_wpa3_sae_nm.yml b/tests/tests_wireless_wpa3_sae_nm.yml new file mode 100644 index 0000000..b294d58 --- /dev/null +++ b/tests/tests_wireless_wpa3_sae_nm.yml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: BSD-3-Clause +# This file was generated by ensure_provider_tests.py +--- +# set network provider and gather facts +- hosts: all + name: Run playbook 'playbooks/tests_wireless_wpa3_sae.yml' with nm as provider + tasks: + - name: Set network provider to 'nm' + set_fact: + network_provider: nm + tags: + - always + + +# The test requires or should run with NetworkManager, therefore it cannot run +# on RHEL/CentOS 6 +# SAE has not been supported by NetworkManager 1.18.8 on RHEL 7. Failed in setting up mock wifi on RHEL 8 +- import_playbook: playbooks/tests_wireless_wpa3_sae.yml + when: + - ansible_distribution_major_version != '6' + - ansible_distribution_major_version != '7'