Unverified Commit f59c39a3 authored by Michele Guerini Rocco's avatar Michele Guerini Rocco Committed by GitHub
Browse files

nixos/wpa_supplicant: allow duplicate network blocks (#441410)

parents 11fde5c8 aa61310a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -250,6 +250,8 @@

- `services.gitea` supports sending notifications with sendmail again. To do this, activate the parameter `services.gitea.mailerUseSendmail` and configure SMTP server.

- `networking.wireless.networks.<name>` now has an option to specify SSID, hence allowing duplicated SSID setup. The BSSID option is added along side with this.

- Revamp of the ACME certificate acquisication and renewal process to help scale systems with lots (100+) of certificates.

  Units and targets have been reshaped to better support more specific dependency propagation and avoid
+186 −158
Original line number Diff line number Diff line
@@ -37,7 +37,9 @@ let
  mkWPA2Fallback = opts: opts // { authProtocols = subtractLists wpa3Protocols opts.authProtocols; };

  # Networks attrset as a list
  networkList = mapAttrsToList (ssid: opts: opts // { inherit ssid; }) cfg.networks;
  # We use the ssid from the options, which defaults to the ssid but can be overridden.
  # The ssid in attrNames is hence unused here.
  networkList = attrValues cfg.networks;

  # List of all networks (normal + generated fallbacks)
  allNetworks =
@@ -89,6 +91,7 @@ let
            "key_mgmt=NONE"
        )
      ]
      ++ optional (opts.bssid != null) "bssid=${opts.bssid}"
      ++ optional opts.hidden "scan_ssid=1"
      ++ optional (pskString != null) "psk=${pskString}"
      ++ optionals (opts.auth != null) (filter (x: x != "") (splitString "\n" opts.auth))
@@ -280,8 +283,32 @@ in

      networks = mkOption {
        type = types.attrsOf (
          types.submodule {
          types.submodule (
            { name, ... }:
            {
              options = {
                ssid = mkOption {
                  type = types.str;
                  default = name;
                  description = ''
                    You could use this field to override the network's ssid.
                    This can be useful to, for example, specify two networks
                    that share the same SSID but not the same password.
                    Specifying the BSSID of the network can make two entries of
                    the same SSID show up as different ones in wpa_cli.
                  '';
                };

                bssid = mkOption {
                  type = types.nullOr types.str;
                  default = null;
                  example = "02:00:00:00:00:01";
                  description = ''
                    If set, this network block is used only when associating with
                    the AP using the configured BSSID.
                  '';
                };

                psk = mkOption {
                  type = types.nullOr (types.strMatching "[[:print:]]{8,63}");
                  default = null;
@@ -444,6 +471,7 @@ in

              };
            }
          )
        );
        description = ''
          The network definitions to automatically connect to when
+72 −6
Original line number Diff line number Diff line
@@ -13,8 +13,31 @@ let

  naughtyPassphrase = ''!,./;'[]\-=<>?:"{}|_+@$%^&*()`~ # ceci n'est pas un commentaire'';

  runBssidTest =
    name: expectedBssid: extraConfig:
    runSimulatorTest name extraConfig ''
      with subtest("Daemon can connect to the right access point"):
          machine.wait_for_unit("wpa_supplicant-wlan1.service")
          machine.wait_until_succeeds(
            "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED"
          )
          machine.wait_until_succeeds(
            "wpa_cli -i wlan1 status | grep -q bssid=${expectedBssid}"
          )
    '';

  runConnectionTest =
    name: extraConfig:
    runSimulatorTest name extraConfig ''
      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"
          )
    '';

  runSimulatorTest =
    name: extraConfig: extraTestScript:
    runTest {
      name = "wpa_supplicant-${name}";
      inherit meta;
@@ -50,12 +73,22 @@ let
                bssid = "02:00:00:00:00:01";
              };
              wlan0-2 = {
                ssid = "nixos-test-mixed";
                authentication = {
                  mode = "wpa3-sae-transition";
                  saeAddToMacAllow = true;
                  saePasswordsFile = pkgs.writeText "password" naughtyPassphrase;
                  wpaPasswordFile = pkgs.writeText "password" naughtyPassphrase;
                };
                bssid = "02:00:00:00:00:02";
              };
              wlan0-3 = {
                ssid = "nixos-test-wpa2";
                authentication = {
                  mode = "wpa2-sha256";
                  wpaPassword = naughtyPassphrase;
                };
                bssid = "02:00:00:00:00:02";
                bssid = "02:00:00:00:00:03";
              };
            };
          };
@@ -85,11 +118,7 @@ let
        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"
            )
        ${extraTestScript}
      '';
    };

@@ -129,6 +158,18 @@ in
            psk = "password";
            authProtocols = [ "SAE" ];
          };

          # Test duplicate SSID generation
          duplicate1 = {
            ssid = "duplicate";
            bssid = "00:00:00:00:00:01";
            psk = "password";
          };
          duplicate2 = {
            ssid = "duplicate";
            bssid = "00:00:00:00:00:02";
            psk = "password";
          };
        };
      };
    };
@@ -148,6 +189,12 @@ in
          assert int(machine.succeed(f"grep -c sae-only {config_file}")) == 1
          assert int(machine.succeed(f"grep -c mixed-wpa {config_file}")) == 2

      with subtest("Duplicate SSID network blocks have been generated"):
          # more duplication due to fallbacks
          assert int(machine.succeed(f"grep -c duplicate {config_file}")) == 4
          assert int(machine.succeed(f"grep -c bssid=00:00:00:00:00:01 {config_file}")) == 2
          assert int(machine.succeed(f"grep -c bssid=00:00:00:00:00:02 {config_file}")) == 2

      # save file for manual inspection
      machine.copy_from_vm(config_file)
    '';
@@ -222,4 +269,23 @@ in
      authProtocols = [ "WPA-PSK-SHA256" ];
    };
  };

  # Test connection with the highest prio "matching" network block found.
  # "Matching" meaning with the right SSID and BSSID
  bssidGuard = runBssidTest "bssid-guard" "02:00:00:00:00:02" {
    networks = {
      "1_first" = {
        ssid = "nixos-test-mixed";
        bssid = "02:00:00:00:00:01";
        pskRaw = "ext:psk_nixos_test";
      };
      "2_second" = {
        ssid = "nixos-test-mixed";
        bssid = "02:00:00:00:00:02";
        pskRaw = "ext:psk_nixos_test";
        priority = 1;
      };
    };
  };

}