at 25.11-pre 6.8 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 runConnectionTest = 17 name: extraConfig: 18 runTest { 19 name = "wpa_supplicant-${name}"; 20 inherit meta; 21 22 nodes.machine = { 23 # add a virtual wlan interface 24 boot.kernelModules = [ "mac80211_hwsim" ]; 25 26 # wireless access point 27 services.hostapd = { 28 enable = true; 29 radios.wlan0 = { 30 band = "2g"; 31 channel = 6; 32 countryCode = "US"; 33 networks = { 34 wlan0 = { 35 ssid = "nixos-test-sae"; 36 authentication = { 37 mode = "wpa3-sae"; 38 saePasswords = [ { passwordFile = pkgs.writeText "password" naughtyPassphrase; } ]; 39 }; 40 bssid = "02:00:00:00:00:00"; 41 }; 42 wlan0-1 = { 43 ssid = "nixos-test-mixed"; 44 authentication = { 45 mode = "wpa3-sae-transition"; 46 saeAddToMacAllow = true; 47 saePasswordsFile = pkgs.writeText "password" naughtyPassphrase; 48 wpaPasswordFile = pkgs.writeText "password" naughtyPassphrase; 49 }; 50 bssid = "02:00:00:00:00:01"; 51 }; 52 wlan0-2 = { 53 ssid = "nixos-test-wpa2"; 54 authentication = { 55 mode = "wpa2-sha256"; 56 wpaPassword = naughtyPassphrase; 57 }; 58 bssid = "02:00:00:00:00:02"; 59 }; 60 }; 61 }; 62 }; 63 64 # wireless client 65 networking.wireless = lib.mkMerge [ 66 { 67 # the override is needed because the wifi is 68 # disabled with mkVMOverride in qemu-vm.nix. 69 enable = lib.mkOverride 0 true; 70 userControlled.enable = true; 71 interfaces = [ "wlan1" ]; 72 fallbackToWPA2 = lib.mkDefault true; 73 74 # secrets 75 secretsFile = pkgs.writeText "wpa-secrets" '' 76 psk_nixos_test=${naughtyPassphrase} 77 ''; 78 } 79 extraConfig 80 ]; 81 }; 82 83 testScript = '' 84 # save hostapd config file for manual inspection 85 machine.wait_for_unit("hostapd.service") 86 machine.copy_from_vm("/run/hostapd/wlan0.hostapd.conf") 87 88 with subtest("Daemon can connect to the access point"): 89 machine.wait_for_unit("wpa_supplicant-wlan1.service") 90 machine.wait_until_succeeds( 91 "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" 92 ) 93 ''; 94 }; 95 96in 97 98{ 99 # Test the basic setup: 100 # - automatic interface discovery 101 # - WPA2 fallbacks 102 # - connecting to the daemon 103 basic = runTest { 104 name = "wpa_supplicant-basic"; 105 inherit meta; 106 107 nodes.machine = { 108 # add a virtual wlan interface 109 boot.kernelModules = [ "mac80211_hwsim" ]; 110 111 # wireless client 112 networking.wireless = { 113 # the override is needed because the wifi is 114 # disabled with mkVMOverride in qemu-vm.nix. 115 enable = lib.mkOverride 0 true; 116 userControlled.enable = true; 117 fallbackToWPA2 = true; 118 119 networks = { 120 # test WPA2 fallback 121 mixed-wpa = { 122 psk = "password"; 123 authProtocols = [ 124 "WPA-PSK" 125 "SAE" 126 ]; 127 }; 128 sae-only = { 129 psk = "password"; 130 authProtocols = [ "SAE" ]; 131 }; 132 }; 133 }; 134 }; 135 136 testScript = '' 137 with subtest("Daemon is running and accepting connections"): 138 machine.wait_for_unit("wpa_supplicant.service") 139 status = machine.wait_until_succeeds("wpa_cli status") 140 assert "Failed to connect" not in status, \ 141 "Failed to connect to the daemon" 142 143 # get the configuration file 144 cmdline = machine.succeed("cat /proc/$(pgrep wpa)/cmdline").split('\x00') 145 config_file = cmdline[cmdline.index("-c") + 1] 146 147 with subtest("WPA2 fallbacks have been generated"): 148 assert int(machine.succeed(f"grep -c sae-only {config_file}")) == 1 149 assert int(machine.succeed(f"grep -c mixed-wpa {config_file}")) == 2 150 151 # save file for manual inspection 152 machine.copy_from_vm(config_file) 153 ''; 154 }; 155 156 # Test configuring the daemon imperatively 157 imperative = runTest { 158 name = "wpa_supplicant-imperative"; 159 inherit meta; 160 161 nodes.machine = { 162 # add a virtual wlan interface 163 boot.kernelModules = [ "mac80211_hwsim" ]; 164 165 # wireless client 166 networking.wireless = { 167 enable = lib.mkOverride 0 true; 168 userControlled.enable = true; 169 allowAuxiliaryImperativeNetworks = true; 170 interfaces = [ "wlan1" ]; 171 }; 172 }; 173 174 testScript = '' 175 with subtest("Daemon is running and accepting connections"): 176 machine.wait_for_unit("wpa_supplicant-wlan1.service") 177 status = machine.wait_until_succeeds("wpa_cli -i wlan1 status") 178 assert "Failed to connect" not in status, \ 179 "Failed to connect to the daemon" 180 181 with subtest("Daemon can be configured imperatively"): 182 machine.succeed("wpa_cli -i wlan1 add_network") 183 machine.succeed("wpa_cli -i wlan1 set_network 0 ssid '\"nixos-test\"'") 184 machine.succeed("wpa_cli -i wlan1 set_network 0 psk '\"reproducibility\"'") 185 machine.succeed("wpa_cli -i wlan1 save_config") 186 machine.succeed("grep -q nixos-test /etc/wpa_supplicant.conf") 187 ''; 188 }; 189 190 # Test connecting to a SAE-only hotspot using SAE 191 saeOnly = runConnectionTest "sae-only" { 192 fallbackToWPA2 = false; 193 networks.nixos-test-sae = { 194 pskRaw = "ext:psk_nixos_test"; 195 authProtocols = [ "SAE" ]; 196 }; 197 }; 198 199 # Test connecting to a mixed SAE/WPA2 hotspot using SAE 200 mixedUsingSae = runConnectionTest "mixed-using-sae" { 201 fallbackToWPA2 = false; 202 networks.nixos-test-mixed = { 203 pskRaw = "ext:psk_nixos_test"; 204 authProtocols = [ "SAE" ]; 205 }; 206 }; 207 208 # Test connecting to a mixed SAE/WPA2 hotspot using WPA2 209 mixedUsingWpa2 = runConnectionTest "mixed-using-wpa2" { 210 fallbackToWPA2 = true; 211 networks.nixos-test-mixed = { 212 pskRaw = "ext:psk_nixos_test"; 213 authProtocols = [ "WPA-PSK-SHA256" ]; 214 }; 215 }; 216 217 # Test connecting to a legacy WPA2-only hotspot using WPA2 218 legacy = runConnectionTest "legacy" { 219 fallbackToWPA2 = true; 220 networks.nixos-test-wpa2 = { 221 pskRaw = "ext:psk_nixos_test"; 222 authProtocols = [ "WPA-PSK-SHA256" ]; 223 }; 224 }; 225}