at 24.11-pre 8.1 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 test5.psk = "@PSK_AWK_REGEX@"; # should be replaced 106 }; 107 108 # secrets 109 environmentFile = pkgs.writeText "wpa-secrets" '' 110 PSK_VALID="S0m3BadP4ssw0rd"; 111 # taken from https://github.com/minimaxir/big-list-of-naughty-strings 112 PSK_SPECIAL=",./;'[]\/\-= <>?:\"{}|_+ !@#$%^&*()`~"; 113 PSK_AWK_REGEX="PassowrdWith&symbol"; 114 ''; 115 }; 116 }; 117 118 imperative = { ... }: { 119 imports = [ ../modules/profiles/minimal.nix ]; 120 121 # add a virtual wlan interface 122 boot.kernelModules = [ "mac80211_hwsim" ]; 123 124 # wireless client 125 networking.wireless = { 126 enable = lib.mkOverride 0 true; 127 userControlled.enable = true; 128 allowAuxiliaryImperativeNetworks = true; 129 interfaces = [ "wlan1" ]; 130 }; 131 }; 132 133 # Test connecting to the SAE-only hotspot using SAE 134 machineSae = machineWithHostapd { 135 networking.wireless = { 136 fallbackToWPA2 = false; 137 networks.nixos-test-sae = { 138 psk = "@PSK_NIXOS_TEST@"; 139 authProtocols = [ "SAE" ]; 140 }; 141 }; 142 }; 143 144 # Test connecting to the SAE and WPA2 mixed hotspot using SAE 145 machineMixedUsingSae = machineWithHostapd { 146 networking.wireless = { 147 fallbackToWPA2 = false; 148 networks.nixos-test-mixed = { 149 psk = "@PSK_NIXOS_TEST@"; 150 authProtocols = [ "SAE" ]; 151 }; 152 }; 153 }; 154 155 # Test connecting to the SAE and WPA2 mixed hotspot using WPA2 156 machineMixedUsingWpa2 = machineWithHostapd { 157 networking.wireless = { 158 fallbackToWPA2 = true; 159 networks.nixos-test-mixed = { 160 psk = "@PSK_NIXOS_TEST@"; 161 authProtocols = [ "WPA-PSK-SHA256" ]; 162 }; 163 }; 164 }; 165 166 # Test connecting to the WPA2 legacy hotspot using WPA2 167 machineWpa2 = machineWithHostapd { 168 networking.wireless = { 169 fallbackToWPA2 = true; 170 networks.nixos-test-wpa2 = { 171 psk = "@PSK_NIXOS_TEST@"; 172 authProtocols = [ "WPA-PSK-SHA256" ]; 173 }; 174 }; 175 }; 176 }; 177 178 testScript = 179 '' 180 config_file = "/run/wpa_supplicant/wpa_supplicant.conf" 181 182 with subtest("Configuration file is inaccessible to other users"): 183 basic.wait_for_file(config_file) 184 basic.fail(f"sudo -u nobody ls {config_file}") 185 186 with subtest("Secrets variables have been substituted"): 187 basic.fail(f"grep -q @PSK_VALID@ {config_file}") 188 basic.fail(f"grep -q @PSK_SPECIAL@ {config_file}") 189 basic.succeed(f"grep -q @PSK_MISSING@ {config_file}") 190 basic.succeed(f"grep -q P@ssowrdWithSome@tSymbol {config_file}") 191 basic.succeed(f"grep -q 'PassowrdWith&symbol' {config_file}") 192 193 with subtest("WPA2 fallbacks have been generated"): 194 assert int(basic.succeed(f"grep -c sae-only {config_file}")) == 1 195 assert int(basic.succeed(f"grep -c mixed-wpa {config_file}")) == 2 196 197 # save file for manual inspection 198 basic.copy_from_vm(config_file) 199 200 with subtest("Daemon is running and accepting connections"): 201 basic.wait_for_unit("wpa_supplicant-wlan1.service") 202 status = basic.succeed("wpa_cli -i wlan1 status") 203 assert "Failed to connect" not in status, \ 204 "Failed to connect to the daemon" 205 206 with subtest("Daemon can be configured imperatively"): 207 imperative.wait_for_unit("wpa_supplicant-wlan1.service") 208 imperative.wait_until_succeeds("wpa_cli -i wlan1 status") 209 imperative.succeed("wpa_cli -i wlan1 add_network") 210 imperative.succeed("wpa_cli -i wlan1 set_network 0 ssid '\"nixos-test\"'") 211 imperative.succeed("wpa_cli -i wlan1 set_network 0 psk '\"reproducibility\"'") 212 imperative.succeed("wpa_cli -i wlan1 save_config") 213 imperative.succeed("grep -q nixos-test /etc/wpa_supplicant.conf") 214 215 machineSae.wait_for_unit("hostapd.service") 216 machineSae.copy_from_vm("/run/hostapd/wlan0.hostapd.conf") 217 with subtest("Daemon can connect to the SAE access point using SAE"): 218 machineSae.wait_until_succeeds( 219 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 220 ) 221 222 with subtest("Daemon can connect to the SAE and WPA2 mixed access point using SAE"): 223 machineMixedUsingSae.wait_until_succeeds( 224 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 225 ) 226 227 with subtest("Daemon can connect to the SAE and WPA2 mixed access point using WPA2"): 228 machineMixedUsingWpa2.wait_until_succeeds( 229 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 230 ) 231 232 with subtest("Daemon can connect to the WPA2 access point using WPA2"): 233 machineWpa2.wait_until_succeeds( 234 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 235 ) 236 ''; 237})