aboutsummaryrefslogtreecommitdiff
path: root/tests/nixos/fetchurl.nix
blob: 97365d053a59c12b6bca807623b7be7ac168b093 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# Test whether builtin:fetchurl properly performs TLS certificate
# checks on HTTPS servers.

{ lib, config, pkgs, ... }:

let

  makeTlsCert = name: pkgs.runCommand name {
    nativeBuildInputs = with pkgs; [ openssl ];
  } ''
    mkdir -p $out
    openssl req -x509 \
      -subj '/CN=${name}/' -days 49710 \
      -addext 'subjectAltName = DNS:${name}' \
      -keyout "$out/key.pem" -newkey ed25519 \
      -out "$out/cert.pem" -noenc
  '';

  goodCert = makeTlsCert "good";
  badCert = makeTlsCert "bad";

in

{
  name = "fetchurl";

  nodes = {
    machine = { lib, pkgs, ... }: {
      services.nginx = {
        enable = true;

        virtualHosts."good" = {
          addSSL = true;
          sslCertificate = "${goodCert}/cert.pem";
          sslCertificateKey = "${goodCert}/key.pem";
          root = pkgs.runCommand "nginx-root" {} ''
            mkdir "$out"
            echo 'hello world' > "$out/index.html"
          '';
        };

        virtualHosts."bad" = {
          addSSL = true;
          sslCertificate = "${badCert}/cert.pem";
          sslCertificateKey = "${badCert}/key.pem";
          root = pkgs.runCommand "nginx-root" {} ''
            mkdir "$out"
            echo 'foobar' > "$out/index.html"
          '';
        };
      };

      security.pki.certificateFiles = [ "${goodCert}/cert.pem" ];

      networking.hosts."127.0.0.1" = [ "good" "bad" ];

      virtualisation.writableStore = true;

      nix.settings.experimental-features = "nix-command";
    };
  };

  testScript = { nodes, ... }: ''
    machine.wait_for_unit("nginx")
    machine.wait_for_open_port(443)

    out = machine.succeed("curl https://good/index.html")
    assert out == "hello world\n"

    out = machine.succeed("cat ${badCert}/cert.pem > /tmp/cafile.pem; curl --cacert /tmp/cafile.pem https://bad/index.html")
    assert out == "foobar\n"

    # Fetching from a server with a trusted cert should work.
    machine.succeed("nix build --no-substitute --expr 'import <nix/fetchurl.nix> { url = \"https://good/index.html\"; hash = \"sha256-qUiQTy8PR5uPgZdpSzAYSw0u0cHNKh7A+4XSmaGSpEc=\"; }'")

    # Fetching from a server with an untrusted cert should fail.
    err = machine.fail("nix build --no-substitute --expr 'import <nix/fetchurl.nix> { url = \"https://bad/index.html\"; hash = \"sha256-rsBwZF/lPuOzdjBZN2E08FjMM3JHyXit0Xi2zN+wAZ8=\"; }' 2>&1")
    print(err)
    assert "SSL certificate problem: self-signed certificate" in err or "SSL peer certificate or SSH remote key was not OK" in err

    # Fetching from a server with a trusted cert should work via environment variable override.
    machine.succeed("NIX_SSL_CERT_FILE=/tmp/cafile.pem nix build --no-substitute --expr 'import <nix/fetchurl.nix> { url = \"https://bad/index.html\"; hash = \"sha256-rsBwZF/lPuOzdjBZN2E08FjMM3JHyXit0Xi2zN+wAZ8=\"; }'")
  '';
}