at 23.11-beta 6.9 kB view raw
1import ./make-test-python.nix ({ pkgs, lib, ...}: 2{ 3 name = "wpa_supplicant"; 4 meta = with lib.maintainers; { 5 maintainers = [ oddlama rnhmjoj ]; 6 }; 7 8 nodes = let 9 machineWithHostapd = extraConfigModule: { ... }: { 10 imports = [ 11 ../modules/profiles/minimal.nix 12 extraConfigModule 13 ]; 14 15 # add a virtual wlan interface 16 boot.kernelModules = [ "mac80211_hwsim" ]; 17 18 # wireless access point 19 services.hostapd = { 20 enable = true; 21 radios.wlan0 = { 22 band = "2g"; 23 countryCode = "US"; 24 networks = { 25 wlan0 = { 26 ssid = "nixos-test-sae"; 27 authentication = { 28 mode = "wpa3-sae"; 29 saePasswords = [ { password = "reproducibility"; } ]; 30 }; 31 bssid = "02:00:00:00:00:00"; 32 }; 33 wlan0-1 = { 34 ssid = "nixos-test-mixed"; 35 authentication = { 36 mode = "wpa3-sae-transition"; 37 saeAddToMacAllow = true; 38 saePasswordsFile = pkgs.writeText "password" "reproducibility"; 39 wpaPasswordFile = pkgs.writeText "password" "reproducibility"; 40 }; 41 bssid = "02:00:00:00:00:01"; 42 }; 43 wlan0-2 = { 44 ssid = "nixos-test-wpa2"; 45 authentication = { 46 mode = "wpa2-sha256"; 47 wpaPassword = "reproducibility"; 48 }; 49 bssid = "02:00:00:00:00:02"; 50 }; 51 }; 52 }; 53 }; 54 55 # wireless client 56 networking.wireless = { 57 # the override is needed because the wifi is 58 # disabled with mkVMOverride in qemu-vm.nix. 59 enable = lib.mkOverride 0 true; 60 userControlled.enable = true; 61 interfaces = [ "wlan1" ]; 62 fallbackToWPA2 = lib.mkDefault true; 63 64 # networks will be added on-demand below for the specific 65 # network that should be tested 66 67 # secrets 68 environmentFile = pkgs.writeText "wpa-secrets" '' 69 PSK_NIXOS_TEST="reproducibility" 70 ''; 71 }; 72 }; 73 in { 74 basic = { ... }: { 75 imports = [ ../modules/profiles/minimal.nix ]; 76 77 # add a virtual wlan interface 78 boot.kernelModules = [ "mac80211_hwsim" ]; 79 80 # wireless client 81 networking.wireless = { 82 # the override is needed because the wifi is 83 # disabled with mkVMOverride in qemu-vm.nix. 84 enable = lib.mkOverride 0 true; 85 userControlled.enable = true; 86 interfaces = [ "wlan1" ]; 87 fallbackToWPA2 = true; 88 89 networks = { 90 # test WPA2 fallback 91 mixed-wpa = { 92 psk = "password"; 93 authProtocols = [ "WPA-PSK" "SAE" ]; 94 }; 95 sae-only = { 96 psk = "password"; 97 authProtocols = [ "SAE" ]; 98 }; 99 100 # secrets substitution test cases 101 test1.psk = "@PSK_VALID@"; # should be replaced 102 test2.psk = "@PSK_SPECIAL@"; # should be replaced 103 test3.psk = "@PSK_MISSING@"; # should not be replaced 104 test4.psk = "P@ssowrdWithSome@tSymbol"; # should not be replaced 105 }; 106 107 # secrets 108 environmentFile = pkgs.writeText "wpa-secrets" '' 109 PSK_VALID="S0m3BadP4ssw0rd"; 110 # taken from https://github.com/minimaxir/big-list-of-naughty-strings 111 PSK_SPECIAL=",./;'[]\-= <>?:\"{}|_+ !@#$%^\&*()`~"; 112 ''; 113 }; 114 }; 115 116 # Test connecting to the SAE-only hotspot using SAE 117 machineSae = machineWithHostapd { 118 networking.wireless = { 119 fallbackToWPA2 = false; 120 networks.nixos-test-sae = { 121 psk = "@PSK_NIXOS_TEST@"; 122 authProtocols = [ "SAE" ]; 123 }; 124 }; 125 }; 126 127 # Test connecting to the SAE and WPA2 mixed hotspot using SAE 128 machineMixedUsingSae = machineWithHostapd { 129 networking.wireless = { 130 fallbackToWPA2 = false; 131 networks.nixos-test-mixed = { 132 psk = "@PSK_NIXOS_TEST@"; 133 authProtocols = [ "SAE" ]; 134 }; 135 }; 136 }; 137 138 # Test connecting to the SAE and WPA2 mixed hotspot using WPA2 139 machineMixedUsingWpa2 = machineWithHostapd { 140 networking.wireless = { 141 fallbackToWPA2 = true; 142 networks.nixos-test-mixed = { 143 psk = "@PSK_NIXOS_TEST@"; 144 authProtocols = [ "WPA-PSK-SHA256" ]; 145 }; 146 }; 147 }; 148 149 # Test connecting to the WPA2 legacy hotspot using WPA2 150 machineWpa2 = machineWithHostapd { 151 networking.wireless = { 152 fallbackToWPA2 = true; 153 networks.nixos-test-wpa2 = { 154 psk = "@PSK_NIXOS_TEST@"; 155 authProtocols = [ "WPA-PSK-SHA256" ]; 156 }; 157 }; 158 }; 159 }; 160 161 testScript = 162 '' 163 config_file = "/run/wpa_supplicant/wpa_supplicant.conf" 164 165 with subtest("Configuration file is inaccessible to other users"): 166 basic.wait_for_file(config_file) 167 basic.fail(f"sudo -u nobody ls {config_file}") 168 169 with subtest("Secrets variables have been substituted"): 170 basic.fail(f"grep -q @PSK_VALID@ {config_file}") 171 basic.fail(f"grep -q @PSK_SPECIAL@ {config_file}") 172 basic.succeed(f"grep -q @PSK_MISSING@ {config_file}") 173 basic.succeed(f"grep -q P@ssowrdWithSome@tSymbol {config_file}") 174 175 with subtest("WPA2 fallbacks have been generated"): 176 assert int(basic.succeed(f"grep -c sae-only {config_file}")) == 1 177 assert int(basic.succeed(f"grep -c mixed-wpa {config_file}")) == 2 178 179 # save file for manual inspection 180 basic.copy_from_vm(config_file) 181 182 with subtest("Daemon is running and accepting connections"): 183 basic.wait_for_unit("wpa_supplicant-wlan1.service") 184 status = basic.succeed("wpa_cli -i wlan1 status") 185 assert "Failed to connect" not in status, \ 186 "Failed to connect to the daemon" 187 188 machineSae.wait_for_unit("hostapd.service") 189 machineSae.copy_from_vm("/run/hostapd/wlan0.hostapd.conf") 190 with subtest("Daemon can connect to the SAE access point using SAE"): 191 machineSae.wait_until_succeeds( 192 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 193 ) 194 195 with subtest("Daemon can connect to the SAE and WPA2 mixed access point using SAE"): 196 machineMixedUsingSae.wait_until_succeeds( 197 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 198 ) 199 200 with subtest("Daemon can connect to the SAE and WPA2 mixed access point using WPA2"): 201 machineMixedUsingWpa2.wait_until_succeeds( 202 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 203 ) 204 205 with subtest("Daemon can connect to the WPA2 access point using WPA2"): 206 machineWpa2.wait_until_succeeds( 207 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 208 ) 209 ''; 210})