Merge pull request #170746 from rnhmjoj/pr-custom-ca

nixos/tests/custom-ca: split

Changed files
+93 -79
nixos
+93 -79
nixos/tests/custom-ca.nix
···
# Checks that `security.pki` options are working in curl and the main browser
-
# engines: Gecko (via Firefox), Chromium, QtWebEngine (Falkon) and WebKitGTK
-
# (via Midori). The test checks that certificates issued by a custom trusted
-
# CA are accepted but those from an unknown CA are rejected.
+
# engines: Gecko (via Firefox), Chromium, QtWebEngine (via qutebrowser) and
+
# WebKitGTK (via Midori). The test checks that certificates issued by a custom
+
# trusted CA are accepted but those from an unknown CA are rejected.
+
+
{ system ? builtins.currentSystem,
+
config ? {},
+
pkgs ? import ../.. { inherit system config; }
+
}:
-
import ./make-test-python.nix ({ pkgs, lib, ... }:
+
with import ../lib/testing-python.nix { inherit system pkgs; };
let
makeCert = { caName, domain }: pkgs.runCommand "example-cert"
···
domain = "bad.example.com";
};
-
in
-
-
{
-
name = "custom-ca";
-
meta.maintainers = with lib.maintainers; [ rnhmjoj ];
-
-
enableOCR = true;
-
-
nodes.machine = { pkgs, ... }:
-
{ imports = [ ./common/user-account.nix ./common/x11.nix ];
-
-
# chromium-based browsers refuse to run as root
-
test-support.displayManager.auto.user = "alice";
-
-
# browsers may hang with the default memory
-
virtualisation.memorySize = 600;
-
-
networking.hosts."127.0.0.1" = [ "good.example.com" "bad.example.com" ];
+
webserverConfig =
+
{ networking.hosts."127.0.0.1" = [ "good.example.com" "bad.example.com" ];
security.pki.certificateFiles = [ "${example-good-cert}/ca.crt" ];
services.nginx.enable = true;
···
return 200 'It does not work!';
'';
};
-
-
environment.systemPackages = with pkgs; [
-
xdotool
-
firefox
-
chromium
-
qutebrowser
-
midori
-
];
};
-
testScript = ''
-
from typing import Tuple
-
def execute_as(user: str, cmd: str) -> Tuple[int, str]:
-
"""
-
Run a shell command as a specific user.
-
"""
-
return machine.execute(f"sudo -u {user} {cmd}")
+
curlTest = makeTest {
+
name = "custom-ca-curl";
+
meta.maintainers = with lib.maintainers; [ rnhmjoj ];
+
nodes.machine = { ... }: webserverConfig;
+
testScript = ''
+
with subtest("Good certificate is trusted in curl"):
+
machine.wait_for_unit("nginx")
+
machine.wait_for_open_port(443)
+
machine.succeed("curl -fv https://good.example.com")
+
with subtest("Unknown CA is untrusted in curl"):
+
machine.fail("curl -fv https://bad.example.com")
+
'';
+
};
-
def wait_for_window_as(user: str, cls: str) -> None:
-
"""
-
Wait until a X11 window of a given user appears.
-
"""
+
mkBrowserTest = browser: testParams: makeTest {
+
name = "custom-ca-${browser}";
+
meta.maintainers = with lib.maintainers; [ rnhmjoj ];
-
def window_is_visible(last_try: bool) -> bool:
-
ret, stdout = execute_as(user, f"xdotool search --onlyvisible --class {cls}")
-
if last_try:
-
machine.log(f"Last chance to match {cls} on the window list")
-
return ret == 0
+
enableOCR = true;
-
with machine.nested("Waiting for a window to appear"):
-
retry(window_is_visible)
+
nodes.machine = { pkgs, ... }:
+
{ imports =
+
[ ./common/user-account.nix
+
./common/x11.nix
+
webserverConfig
+
];
+
# chromium-based browsers refuse to run as root
+
test-support.displayManager.auto.user = "alice";
-
machine.start()
+
# browsers may hang with the default memory
+
virtualisation.memorySize = 600;
-
with subtest("Good certificate is trusted in curl"):
-
machine.wait_for_unit("nginx")
-
machine.wait_for_open_port(443)
-
machine.succeed("curl -fv https://good.example.com")
+
environment.systemPackages = [ pkgs.xdotool pkgs.${browser} ];
+
};
-
with subtest("Unknown CA is untrusted in curl"):
-
machine.fail("curl -fv https://bad.example.com")
+
testScript = ''
+
from typing import Tuple
+
def execute_as(user: str, cmd: str) -> Tuple[int, str]:
+
"""
+
Run a shell command as a specific user.
+
"""
+
return machine.execute(f"sudo -u {user} {cmd}")
-
browsers = {
-
"firefox": "Security Risk",
-
"chromium": "not private",
-
"qutebrowser -T": "Certificate error",
-
"midori": "Security"
-
}
-
machine.wait_for_x()
-
for command, error in browsers.items():
-
browser = command.split()[0]
-
with subtest("Good certificate is trusted in " + browser):
-
execute_as(
-
"alice", f"{command} https://good.example.com >&2 &"
-
)
-
wait_for_window_as("alice", browser)
-
machine.wait_for_text("It works!")
-
machine.screenshot("good" + browser)
-
execute_as("alice", "xdotool key ctrl+w") # close tab
+
def wait_for_window_as(user: str, cls: str) -> None:
+
"""
+
Wait until a X11 window of a given user appears.
+
"""
-
with subtest("Unknown CA is untrusted in " + browser):
-
execute_as("alice", f"{command} https://bad.example.com >&2 &")
-
machine.wait_for_text(error)
-
machine.screenshot("bad" + browser)
-
machine.succeed("pkill -f " + browser)
-
'';
-
})
+
def window_is_visible(last_try: bool) -> bool:
+
ret, stdout = execute_as(user, f"xdotool search --onlyvisible --class {cls}")
+
if last_try:
+
machine.log(f"Last chance to match {cls} on the window list")
+
return ret == 0
+
+
with machine.nested("Waiting for a window to appear"):
+
retry(window_is_visible)
+
+
+
machine.start()
+
machine.wait_for_x()
+
+
command = "${browser} ${testParams.args or ""}"
+
with subtest("Good certificate is trusted in ${browser}"):
+
execute_as(
+
"alice", f"{command} https://good.example.com >&2 &"
+
)
+
wait_for_window_as("alice", "${browser}")
+
machine.sleep(4)
+
execute_as("alice", "xdotool key ctrl+r") # reload to be safe
+
machine.wait_for_text("It works!")
+
machine.screenshot("good${browser}")
+
execute_as("alice", "xdotool key ctrl+w") # close tab
+
+
with subtest("Unknown CA is untrusted in ${browser}"):
+
execute_as("alice", f"{command} https://bad.example.com >&2 &")
+
machine.wait_for_text("${testParams.error}")
+
machine.screenshot("bad${browser}")
+
'';
+
};
+
+
in
+
+
{
+
curl = curlTest;
+
} // pkgs.lib.mapAttrs mkBrowserTest {
+
firefox = { error = "Security Risk"; };
+
chromium = { error = "not private"; };
+
qutebrowser = { args = "-T"; error = "Certificate error"; };
+
midori = { error = "Security"; };
+
}