at 25.11-pre 5.0 kB view raw
1let 2 certs = import ./common/acme/server/snakeoil-certs.nix; 3 domain = certs.domain; 4in 5import ./make-test-python.nix { 6 name = "schleuder"; 7 nodes.machine = 8 { pkgs, ... }: 9 { 10 imports = [ ./common/user-account.nix ]; 11 services.postfix = { 12 enable = true; 13 enableSubmission = true; 14 tlsTrustedAuthorities = "${certs.ca.cert}"; 15 sslCert = "${certs.${domain}.cert}"; 16 sslKey = "${certs.${domain}.key}"; 17 inherit domain; 18 destination = [ domain ]; 19 localRecipients = [ 20 "root" 21 "alice" 22 "bob" 23 ]; 24 }; 25 services.schleuder = { 26 enable = true; 27 # Don't do it like this in production! The point of this setting 28 # is to allow loading secrets from _outside_ the world-readable 29 # Nix store. 30 extraSettingsFile = pkgs.writeText "schleuder-api-keys.yml" '' 31 api: 32 valid_api_keys: 33 - fnord 34 ''; 35 lists = [ "security@${domain}" ]; 36 settings.api = { 37 tls_cert_file = "${certs.${domain}.cert}"; 38 tls_key_file = "${certs.${domain}.key}"; 39 }; 40 }; 41 42 environment.systemPackages = [ 43 pkgs.gnupg 44 pkgs.msmtp 45 (pkgs.writeScriptBin "do-test" '' 46 #!${pkgs.runtimeShell} 47 set -exuo pipefail 48 49 # Generate a GPG key with no passphrase and export it 50 sudo -u alice gpg --passphrase-fd 0 --batch --yes --quick-generate-key 'alice@${domain}' rsa4096 sign,encr < <(echo) 51 sudo -u alice gpg --armor --export alice@${domain} > alice.asc 52 # Create a new mailing list with alice as the owner, and alice's key 53 schleuder-cli list new security@${domain} alice@${domain} alice.asc 54 55 # Send an email from a non-member of the list. Use --auto-from so we don't have to specify who it's from twice. 56 msmtp --auto-from security@${domain} --host=${domain} --port=25 --tls --tls-starttls <<EOF 57 Subject: really big security issue!! 58 From: root@${domain} 59 60 I found a big security problem! 61 EOF 62 63 # Wait for delivery 64 (set +o pipefail; journalctl -f -n 1000 -u postfix | grep -m 1 'delivered to maildir') 65 66 # There should be exactly one email 67 mail=(/var/spool/mail/alice/new/*) 68 [[ "''${#mail[@]}" = 1 ]] 69 70 # Find the fingerprint of the mailing list key 71 read list_key_fp address < <(schleuder-cli keys list security@${domain} | grep security@) 72 schleuder-cli keys export security@${domain} $list_key_fp > list.asc 73 74 # Import the key into alice's keyring, so we can verify it as well as decrypting 75 sudo -u alice gpg --import <list.asc 76 # And perform the decryption. 77 sudo -u alice gpg -d $mail >decrypted 78 # And check that the text matches. 79 grep "big security problem" decrypted 80 '') 81 82 # For debugging: 83 # pkgs.vim pkgs.openssl pkgs.sqliteinteractive 84 ]; 85 86 security.pki.certificateFiles = [ certs.ca.cert ]; 87 88 # Since we don't have internet here, use dnsmasq to provide MX records from /etc/hosts 89 services.dnsmasq = { 90 enable = true; 91 settings.selfmx = true; 92 }; 93 94 networking.extraHosts = '' 95 127.0.0.1 ${domain} 96 ''; 97 98 # schleuder-cli's config is not quite optimal in several ways: 99 # - A fingerprint _must_ be pinned, it doesn't even have an option 100 # to trust the PKI 101 # - It compares certificate fingerprints rather than key 102 # fingerprints, so renewals break the pin (though that's not 103 # relevant for this test) 104 # - It compares them as strings, which means we need to match the 105 # expected format exactly. This means removing the :s and 106 # lowercasing it. 107 # Refs: 108 # https://0xacab.org/schleuder/schleuder-cli/-/issues/16 109 # https://0xacab.org/schleuder/schleuder-cli/-/blob/f8895b9f47083d8c7b99a2797c93f170f3c6a3c0/lib/schleuder-cli/helper.rb#L230-238 110 systemd.tmpfiles.rules = 111 let 112 cliconfig = 113 pkgs.runCommand "schleuder-cli.yml" 114 { 115 nativeBuildInputs = [ 116 pkgs.jq 117 pkgs.openssl 118 ]; 119 } 120 '' 121 fp=$(openssl x509 -in ${certs.${domain}.cert} -noout -fingerprint -sha256 | cut -d = -f 2 | tr -d : | tr 'A-Z' 'a-z') 122 cat > $out <<EOF 123 host: localhost 124 port: 4443 125 tls_fingerprint: "$fp" 126 api_key: fnord 127 EOF 128 ''; 129 in 130 [ 131 "L+ /root/.schleuder-cli/schleuder-cli.yml - - - - ${cliconfig}" 132 ]; 133 }; 134 135 testScript = '' 136 machine.wait_for_unit("multi-user.target") 137 machine.wait_until_succeeds("nc -z localhost 4443") 138 machine.succeed("do-test") 139 ''; 140}