at master 9.7 kB view raw
1{ pkgs, runTest }: 2 3let 4 5 inherit (pkgs) lib; 6 7 meta = with lib.maintainers; { 8 maintainers = [ 9 oddlama 10 rnhmjoj 11 ]; 12 }; 13 14 naughtyPassphrase = ''!,./;'[]\-=<>?:"{}|_+@$%^&*()`~ # ceci n'est pas un commentaire''; 15 16 runBssidTest = 17 name: expectedBssid: extraConfig: 18 runSimulatorTest name extraConfig '' 19 with subtest("Daemon can connect to the right access point"): 20 machine.wait_for_unit("wpa_supplicant-wlan1.service") 21 machine.wait_until_succeeds( 22 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 23 ) 24 machine.wait_until_succeeds( 25 "wpa_cli -i wlan1 status | grep -q bssid=${expectedBssid}" 26 ) 27 ''; 28 29 runConnectionTest = 30 name: extraConfig: 31 runSimulatorTest name extraConfig '' 32 with subtest("Daemon can connect to the access point"): 33 machine.wait_for_unit("wpa_supplicant-wlan1.service") 34 machine.wait_until_succeeds( 35 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 36 ) 37 ''; 38 39 runSimulatorTest = 40 name: extraConfig: extraTestScript: 41 runTest { 42 name = "wpa_supplicant-${name}"; 43 inherit meta; 44 45 nodes.machine = { 46 # add a virtual wlan interface 47 boot.kernelModules = [ "mac80211_hwsim" ]; 48 49 # wireless access point 50 services.hostapd = { 51 enable = true; 52 radios.wlan0 = { 53 band = "2g"; 54 channel = 6; 55 countryCode = "US"; 56 networks = { 57 wlan0 = { 58 ssid = "nixos-test-sae"; 59 authentication = { 60 mode = "wpa3-sae"; 61 saePasswords = [ { passwordFile = pkgs.writeText "password" naughtyPassphrase; } ]; 62 }; 63 bssid = "02:00:00:00:00:00"; 64 }; 65 wlan0-1 = { 66 ssid = "nixos-test-mixed"; 67 authentication = { 68 mode = "wpa3-sae-transition"; 69 saeAddToMacAllow = true; 70 saePasswordsFile = pkgs.writeText "password" naughtyPassphrase; 71 wpaPasswordFile = pkgs.writeText "password" naughtyPassphrase; 72 }; 73 bssid = "02:00:00:00:00:01"; 74 }; 75 wlan0-2 = { 76 ssid = "nixos-test-mixed"; 77 authentication = { 78 mode = "wpa3-sae-transition"; 79 saeAddToMacAllow = true; 80 saePasswordsFile = pkgs.writeText "password" naughtyPassphrase; 81 wpaPasswordFile = pkgs.writeText "password" naughtyPassphrase; 82 }; 83 bssid = "02:00:00:00:00:02"; 84 }; 85 wlan0-3 = { 86 ssid = "nixos-test-wpa2"; 87 authentication = { 88 mode = "wpa2-sha256"; 89 wpaPassword = naughtyPassphrase; 90 }; 91 bssid = "02:00:00:00:00:03"; 92 }; 93 }; 94 }; 95 }; 96 97 # wireless client 98 networking.wireless = lib.mkMerge [ 99 { 100 # the override is needed because the wifi is 101 # disabled with mkVMOverride in qemu-vm.nix. 102 enable = lib.mkOverride 0 true; 103 userControlled.enable = true; 104 interfaces = [ "wlan1" ]; 105 fallbackToWPA2 = lib.mkDefault true; 106 107 # secrets 108 secretsFile = pkgs.writeText "wpa-secrets" '' 109 psk_nixos_test=${naughtyPassphrase} 110 ''; 111 } 112 extraConfig 113 ]; 114 }; 115 116 testScript = '' 117 # save hostapd config file for manual inspection 118 machine.wait_for_unit("hostapd.service") 119 machine.copy_from_vm("/run/hostapd/wlan0.hostapd.conf") 120 121 ${extraTestScript} 122 ''; 123 }; 124 125in 126 127{ 128 # Test the basic setup: 129 # - automatic interface discovery 130 # - WPA2 fallbacks 131 # - connecting to the daemon 132 basic = runTest { 133 name = "wpa_supplicant-basic"; 134 inherit meta; 135 136 nodes.machine = { 137 # add a virtual wlan interface 138 boot.kernelModules = [ "mac80211_hwsim" ]; 139 140 # wireless client 141 networking.wireless = { 142 # the override is needed because the wifi is 143 # disabled with mkVMOverride in qemu-vm.nix. 144 enable = lib.mkOverride 0 true; 145 userControlled.enable = true; 146 fallbackToWPA2 = true; 147 148 networks = { 149 # test WPA2 fallback 150 mixed-wpa = { 151 psk = "password"; 152 authProtocols = [ 153 "WPA-PSK" 154 "SAE" 155 ]; 156 }; 157 sae-only = { 158 psk = "password"; 159 authProtocols = [ "SAE" ]; 160 }; 161 162 # Test duplicate SSID generation 163 duplicate1 = { 164 ssid = "duplicate"; 165 bssid = "00:00:00:00:00:01"; 166 psk = "password"; 167 }; 168 duplicate2 = { 169 ssid = "duplicate"; 170 bssid = "00:00:00:00:00:02"; 171 psk = "password"; 172 }; 173 }; 174 175 extraConfigFiles = [ 176 (pkgs.writeText "test1.conf" '' 177 network={ 178 ssid="test1" 179 key_mgmt=WPA-PSK 180 psk="password1" 181 } 182 '') 183 (pkgs.writeText "test2.conf" '' 184 network={ 185 ssid="test2" 186 key_mgmt=WPA-PSK 187 psk="password2" 188 } 189 '') 190 ]; 191 }; 192 }; 193 194 testScript = '' 195 with subtest("Daemon is running and accepting connections"): 196 machine.wait_for_unit("wpa_supplicant.service") 197 status = machine.wait_until_succeeds("wpa_cli status") 198 assert "Failed to connect" not in status, \ 199 "Failed to connect to the daemon" 200 201 # get the configuration file 202 cmdline = machine.succeed("cat /proc/$(pgrep wpa)/cmdline").split('\x00') 203 config_file = cmdline[cmdline.index("-c") + 1] 204 205 with subtest("WPA2 fallbacks have been generated"): 206 assert int(machine.succeed(f"grep -c sae-only {config_file}")) == 1 207 assert int(machine.succeed(f"grep -c mixed-wpa {config_file}")) == 2 208 209 with subtest("Duplicate SSID network blocks have been generated"): 210 # more duplication due to fallbacks 211 assert int(machine.succeed(f"grep -c duplicate {config_file}")) == 4 212 assert int(machine.succeed(f"grep -c bssid=00:00:00:00:00:01 {config_file}")) == 2 213 assert int(machine.succeed(f"grep -c bssid=00:00:00:00:00:02 {config_file}")) == 2 214 215 with subtest("Extra config files have been loaded"): 216 machine.wait_until_succeeds("wpa_cli -i wlan0 list_networks | grep -q test1") 217 machine.succeed("wpa_cli -i wlan0 list_networks | grep -q test2") 218 219 # save file for manual inspection 220 machine.copy_from_vm(config_file) 221 ''; 222 }; 223 224 # Test configuring the daemon imperatively 225 imperative = runTest { 226 name = "wpa_supplicant-imperative"; 227 inherit meta; 228 229 nodes.machine = { 230 # add a virtual wlan interface 231 boot.kernelModules = [ "mac80211_hwsim" ]; 232 233 # wireless client 234 networking.wireless = { 235 enable = lib.mkOverride 0 true; 236 userControlled.enable = true; 237 allowAuxiliaryImperativeNetworks = true; 238 interfaces = [ "wlan1" ]; 239 }; 240 }; 241 242 testScript = '' 243 with subtest("Daemon is running and accepting connections"): 244 machine.wait_for_unit("wpa_supplicant-wlan1.service") 245 status = machine.wait_until_succeeds("wpa_cli -i wlan1 status") 246 assert "Failed to connect" not in status, \ 247 "Failed to connect to the daemon" 248 249 with subtest("Daemon can be configured imperatively"): 250 machine.succeed("wpa_cli -i wlan1 add_network") 251 machine.succeed("wpa_cli -i wlan1 set_network 0 ssid '\"nixos-test\"'") 252 machine.succeed("wpa_cli -i wlan1 set_network 0 psk '\"reproducibility\"'") 253 machine.succeed("wpa_cli -i wlan1 save_config") 254 machine.succeed("grep -q nixos-test /etc/wpa_supplicant.conf") 255 ''; 256 }; 257 258 # Test connecting to a SAE-only hotspot using SAE 259 saeOnly = runConnectionTest "sae-only" { 260 fallbackToWPA2 = false; 261 networks.nixos-test-sae = { 262 pskRaw = "ext:psk_nixos_test"; 263 authProtocols = [ "SAE" ]; 264 }; 265 }; 266 267 # Test connecting to a mixed SAE/WPA2 hotspot using SAE 268 mixedUsingSae = runConnectionTest "mixed-using-sae" { 269 fallbackToWPA2 = false; 270 networks.nixos-test-mixed = { 271 pskRaw = "ext:psk_nixos_test"; 272 authProtocols = [ "SAE" ]; 273 }; 274 }; 275 276 # Test connecting to a mixed SAE/WPA2 hotspot using WPA2 277 mixedUsingWpa2 = runConnectionTest "mixed-using-wpa2" { 278 fallbackToWPA2 = true; 279 networks.nixos-test-mixed = { 280 pskRaw = "ext:psk_nixos_test"; 281 authProtocols = [ "WPA-PSK-SHA256" ]; 282 }; 283 }; 284 285 # Test connecting to a legacy WPA2-only hotspot using WPA2 286 legacy = runConnectionTest "legacy" { 287 fallbackToWPA2 = true; 288 networks.nixos-test-wpa2 = { 289 pskRaw = "ext:psk_nixos_test"; 290 authProtocols = [ "WPA-PSK-SHA256" ]; 291 }; 292 }; 293 294 # Test connection with the highest prio "matching" network block found. 295 # "Matching" meaning with the right SSID and BSSID 296 bssidGuard = runBssidTest "bssid-guard" "02:00:00:00:00:02" { 297 networks = { 298 "1_first" = { 299 ssid = "nixos-test-mixed"; 300 bssid = "02:00:00:00:00:01"; 301 pskRaw = "ext:psk_nixos_test"; 302 }; 303 "2_second" = { 304 ssid = "nixos-test-mixed"; 305 bssid = "02:00:00:00:00:02"; 306 pskRaw = "ext:psk_nixos_test"; 307 priority = 1; 308 }; 309 }; 310 }; 311 312}