mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-12 05:16:25 +03:00
nixos/wireless: reimplement secrets using ext_password_backend (#180872)
This commit is contained in:
commit
b94f259714
4 changed files with 205 additions and 225 deletions
|
@ -1101,7 +1101,7 @@ in {
|
|||
without-nix = handleTest ./without-nix.nix {};
|
||||
wmderland = handleTest ./wmderland.nix {};
|
||||
workout-tracker = handleTest ./workout-tracker.nix {};
|
||||
wpa_supplicant = handleTest ./wpa_supplicant.nix {};
|
||||
wpa_supplicant = import ./wpa_supplicant.nix { inherit pkgs runTest; };
|
||||
wordpress = handleTest ./wordpress.nix {};
|
||||
wrappers = handleTest ./wrappers.nix {};
|
||||
writefreely = handleTest ./web-apps/writefreely.nix {};
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
import ./make-test-python.nix ({ pkgs, lib, ...}:
|
||||
{
|
||||
name = "wpa_supplicant";
|
||||
{ pkgs, runTest }:
|
||||
|
||||
let
|
||||
|
||||
inherit (pkgs) lib;
|
||||
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ oddlama rnhmjoj ];
|
||||
};
|
||||
|
||||
nodes = let
|
||||
machineWithHostapd = extraConfigModule: { ... }: {
|
||||
imports = [
|
||||
../modules/profiles/minimal.nix
|
||||
extraConfigModule
|
||||
];
|
||||
runConnectionTest = name: extraConfig: runTest {
|
||||
name = "wpa_supplicant-${name}";
|
||||
inherit meta;
|
||||
|
||||
nodes.machine = {
|
||||
# add a virtual wlan interface
|
||||
boot.kernelModules = [ "mac80211_hwsim" ];
|
||||
|
||||
|
@ -53,27 +54,49 @@ import ./make-test-python.nix ({ pkgs, lib, ...}:
|
|||
};
|
||||
|
||||
# wireless client
|
||||
networking.wireless = {
|
||||
# the override is needed because the wifi is
|
||||
# disabled with mkVMOverride in qemu-vm.nix.
|
||||
enable = lib.mkOverride 0 true;
|
||||
userControlled.enable = true;
|
||||
interfaces = [ "wlan1" ];
|
||||
fallbackToWPA2 = lib.mkDefault true;
|
||||
networking.wireless = lib.mkMerge [
|
||||
{
|
||||
# the override is needed because the wifi is
|
||||
# disabled with mkVMOverride in qemu-vm.nix.
|
||||
enable = lib.mkOverride 0 true;
|
||||
userControlled.enable = true;
|
||||
interfaces = [ "wlan1" ];
|
||||
fallbackToWPA2 = lib.mkDefault true;
|
||||
|
||||
# networks will be added on-demand below for the specific
|
||||
# network that should be tested
|
||||
|
||||
# secrets
|
||||
environmentFile = pkgs.writeText "wpa-secrets" ''
|
||||
PSK_NIXOS_TEST="reproducibility"
|
||||
'';
|
||||
};
|
||||
# secrets
|
||||
secretsFile = pkgs.writeText "wpa-secrets" ''
|
||||
psk_nixos_test=reproducibility
|
||||
'';
|
||||
}
|
||||
extraConfig
|
||||
];
|
||||
};
|
||||
in {
|
||||
basic = { ... }: {
|
||||
imports = [ ../modules/profiles/minimal.nix ];
|
||||
|
||||
testScript = ''
|
||||
# save hostapd config file for manual inspection
|
||||
machine.wait_for_unit("hostapd.service")
|
||||
machine.copy_from_vm("/run/hostapd/wlan0.hostapd.conf")
|
||||
|
||||
with subtest("Daemon can connect to the access point"):
|
||||
machine.wait_for_unit("wpa_supplicant-wlan1.service")
|
||||
machine.wait_until_succeeds(
|
||||
"wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED"
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
# Test the basic setup:
|
||||
# - automatic interface discovery
|
||||
# - WPA2 fallbacks
|
||||
# - connecting to the daemon
|
||||
basic = runTest {
|
||||
name = "wpa_supplicant-basic";
|
||||
inherit meta;
|
||||
|
||||
nodes.machine = {
|
||||
# add a virtual wlan interface
|
||||
boot.kernelModules = [ "mac80211_hwsim" ];
|
||||
|
||||
|
@ -83,7 +106,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...}:
|
|||
# disabled with mkVMOverride in qemu-vm.nix.
|
||||
enable = lib.mkOverride 0 true;
|
||||
userControlled.enable = true;
|
||||
interfaces = [ "wlan1" ];
|
||||
fallbackToWPA2 = true;
|
||||
|
||||
networks = {
|
||||
|
@ -96,28 +118,34 @@ import ./make-test-python.nix ({ pkgs, lib, ...}:
|
|||
psk = "password";
|
||||
authProtocols = [ "SAE" ];
|
||||
};
|
||||
|
||||
# secrets substitution test cases
|
||||
test1.psk = "@PSK_VALID@"; # should be replaced
|
||||
test2.psk = "@PSK_SPECIAL@"; # should be replaced
|
||||
test3.psk = "@PSK_MISSING@"; # should not be replaced
|
||||
test4.psk = "P@ssowrdWithSome@tSymbol"; # should not be replaced
|
||||
test5.psk = "@PSK_AWK_REGEX@"; # should be replaced
|
||||
};
|
||||
|
||||
# secrets
|
||||
environmentFile = pkgs.writeText "wpa-secrets" ''
|
||||
PSK_VALID="S0m3BadP4ssw0rd";
|
||||
# taken from https://github.com/minimaxir/big-list-of-naughty-strings
|
||||
PSK_SPECIAL=",./;'[]\/\-= <>?:\"{}|_+ !@#$%^&*()`~";
|
||||
PSK_AWK_REGEX="PassowrdWith&symbol";
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
imperative = { ... }: {
|
||||
imports = [ ../modules/profiles/minimal.nix ];
|
||||
testScript = ''
|
||||
config_file = "/etc/static/wpa_supplicant.conf"
|
||||
|
||||
with subtest("Daemon is running and accepting connections"):
|
||||
machine.wait_for_unit("wpa_supplicant.service")
|
||||
status = machine.wait_until_succeeds("wpa_cli status")
|
||||
assert "Failed to connect" not in status, \
|
||||
"Failed to connect to the daemon"
|
||||
|
||||
with subtest("WPA2 fallbacks have been generated"):
|
||||
assert int(machine.succeed(f"grep -c sae-only {config_file}")) == 1
|
||||
assert int(machine.succeed(f"grep -c mixed-wpa {config_file}")) == 2
|
||||
|
||||
# save file for manual inspection
|
||||
machine.copy_from_vm(config_file)
|
||||
'';
|
||||
};
|
||||
|
||||
# Test configuring the daemon imperatively
|
||||
imperative = runTest {
|
||||
name = "wpa_supplicant-imperative";
|
||||
inherit meta;
|
||||
|
||||
nodes.machine = {
|
||||
# add a virtual wlan interface
|
||||
boot.kernelModules = [ "mac80211_hwsim" ];
|
||||
|
||||
|
@ -130,108 +158,55 @@ import ./make-test-python.nix ({ pkgs, lib, ...}:
|
|||
};
|
||||
};
|
||||
|
||||
# Test connecting to the SAE-only hotspot using SAE
|
||||
machineSae = machineWithHostapd {
|
||||
networking.wireless = {
|
||||
fallbackToWPA2 = false;
|
||||
networks.nixos-test-sae = {
|
||||
psk = "@PSK_NIXOS_TEST@";
|
||||
authProtocols = [ "SAE" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Test connecting to the SAE and WPA2 mixed hotspot using SAE
|
||||
machineMixedUsingSae = machineWithHostapd {
|
||||
networking.wireless = {
|
||||
fallbackToWPA2 = false;
|
||||
networks.nixos-test-mixed = {
|
||||
psk = "@PSK_NIXOS_TEST@";
|
||||
authProtocols = [ "SAE" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Test connecting to the SAE and WPA2 mixed hotspot using WPA2
|
||||
machineMixedUsingWpa2 = machineWithHostapd {
|
||||
networking.wireless = {
|
||||
fallbackToWPA2 = true;
|
||||
networks.nixos-test-mixed = {
|
||||
psk = "@PSK_NIXOS_TEST@";
|
||||
authProtocols = [ "WPA-PSK-SHA256" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Test connecting to the WPA2 legacy hotspot using WPA2
|
||||
machineWpa2 = machineWithHostapd {
|
||||
networking.wireless = {
|
||||
fallbackToWPA2 = true;
|
||||
networks.nixos-test-wpa2 = {
|
||||
psk = "@PSK_NIXOS_TEST@";
|
||||
authProtocols = [ "WPA-PSK-SHA256" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
''
|
||||
config_file = "/run/wpa_supplicant/wpa_supplicant.conf"
|
||||
|
||||
with subtest("Configuration file is inaccessible to other users"):
|
||||
basic.wait_for_file(config_file)
|
||||
basic.fail(f"sudo -u nobody ls {config_file}")
|
||||
|
||||
with subtest("Secrets variables have been substituted"):
|
||||
basic.fail(f"grep -q @PSK_VALID@ {config_file}")
|
||||
basic.fail(f"grep -q @PSK_SPECIAL@ {config_file}")
|
||||
basic.succeed(f"grep -q @PSK_MISSING@ {config_file}")
|
||||
basic.succeed(f"grep -q P@ssowrdWithSome@tSymbol {config_file}")
|
||||
basic.succeed(f"grep -q 'PassowrdWith&symbol' {config_file}")
|
||||
|
||||
with subtest("WPA2 fallbacks have been generated"):
|
||||
assert int(basic.succeed(f"grep -c sae-only {config_file}")) == 1
|
||||
assert int(basic.succeed(f"grep -c mixed-wpa {config_file}")) == 2
|
||||
|
||||
# save file for manual inspection
|
||||
basic.copy_from_vm(config_file)
|
||||
|
||||
testScript = ''
|
||||
with subtest("Daemon is running and accepting connections"):
|
||||
basic.wait_for_unit("wpa_supplicant-wlan1.service")
|
||||
status = basic.succeed("wpa_cli -i wlan1 status")
|
||||
machine.wait_for_unit("wpa_supplicant-wlan1.service")
|
||||
status = machine.wait_until_succeeds("wpa_cli -i wlan1 status")
|
||||
assert "Failed to connect" not in status, \
|
||||
"Failed to connect to the daemon"
|
||||
|
||||
with subtest("Daemon can be configured imperatively"):
|
||||
imperative.wait_for_unit("wpa_supplicant-wlan1.service")
|
||||
imperative.wait_until_succeeds("wpa_cli -i wlan1 status")
|
||||
imperative.succeed("wpa_cli -i wlan1 add_network")
|
||||
imperative.succeed("wpa_cli -i wlan1 set_network 0 ssid '\"nixos-test\"'")
|
||||
imperative.succeed("wpa_cli -i wlan1 set_network 0 psk '\"reproducibility\"'")
|
||||
imperative.succeed("wpa_cli -i wlan1 save_config")
|
||||
imperative.succeed("grep -q nixos-test /etc/wpa_supplicant.conf")
|
||||
|
||||
machineSae.wait_for_unit("hostapd.service")
|
||||
machineSae.copy_from_vm("/run/hostapd/wlan0.hostapd.conf")
|
||||
with subtest("Daemon can connect to the SAE access point using SAE"):
|
||||
machineSae.wait_until_succeeds(
|
||||
"wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED"
|
||||
)
|
||||
|
||||
with subtest("Daemon can connect to the SAE and WPA2 mixed access point using SAE"):
|
||||
machineMixedUsingSae.wait_until_succeeds(
|
||||
"wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED"
|
||||
)
|
||||
|
||||
with subtest("Daemon can connect to the SAE and WPA2 mixed access point using WPA2"):
|
||||
machineMixedUsingWpa2.wait_until_succeeds(
|
||||
"wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED"
|
||||
)
|
||||
|
||||
with subtest("Daemon can connect to the WPA2 access point using WPA2"):
|
||||
machineWpa2.wait_until_succeeds(
|
||||
"wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED"
|
||||
)
|
||||
machine.succeed("wpa_cli -i wlan1 add_network")
|
||||
machine.succeed("wpa_cli -i wlan1 set_network 0 ssid '\"nixos-test\"'")
|
||||
machine.succeed("wpa_cli -i wlan1 set_network 0 psk '\"reproducibility\"'")
|
||||
machine.succeed("wpa_cli -i wlan1 save_config")
|
||||
machine.succeed("grep -q nixos-test /etc/wpa_supplicant.conf")
|
||||
'';
|
||||
})
|
||||
};
|
||||
|
||||
# Test connecting to a SAE-only hotspot using SAE
|
||||
saeOnly = runConnectionTest "sae-only" {
|
||||
fallbackToWPA2 = false;
|
||||
networks.nixos-test-sae = {
|
||||
pskRaw = "ext:psk_nixos_test";
|
||||
authProtocols = [ "SAE" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Test connecting to a mixed SAE/WPA2 hotspot using SAE
|
||||
mixedUsingSae = runConnectionTest "mixed-using-sae" {
|
||||
fallbackToWPA2 = false;
|
||||
networks.nixos-test-mixed = {
|
||||
pskRaw = "ext:psk_nixos_test";
|
||||
authProtocols = [ "SAE" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Test connecting to a mixed SAE/WPA2 hotspot using WPA2
|
||||
mixedUsingWpa2 = runConnectionTest "mixed-using-wpa2" {
|
||||
fallbackToWPA2 = true;
|
||||
networks.nixos-test-mixed = {
|
||||
pskRaw = "ext:psk_nixos_test";
|
||||
authProtocols = [ "WPA-PSK-SHA256" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Test connecting to a legacy WPA2-only hotspot using WPA2
|
||||
legacy = runConnectionTest "legacy" {
|
||||
fallbackToWPA2 = true;
|
||||
networks.nixos-test-wpa2 = {
|
||||
pskRaw = "ext:psk_nixos_test";
|
||||
authProtocols = [ "WPA-PSK-SHA256" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue