{pkgs, ...}: with (import ./common/lib.nix {inherit pkgs;}); let accounts = { "normal" = { address = "user1@example.com"; password = "secret-password1"; }; "normal2" = { address = "user2@example.com"; password = "secret-password2"; }; "system" = { address = "system@example.com"; password = "secret-password3"; isSystemUser = true; }; }; in pkgs.nixosTest { name = "basic"; nodes = { server = {pkgs, ...}: { imports = [./common/server.nix]; environment.systemPackages = with pkgs; [netcat]; mailsystem = { fqdn = "mail.example.com"; domains = ["example.com"]; accounts = mkAccounts accounts; }; }; client = {...}: { imports = [./common/client.nix]; }; }; testScript = {nodes, ...}: let serverAddr = nodes.server.networking.primaryIPAddress; clientAddr = nodes.client.networking.primaryIPAddress; smtpSettings = { address = serverAddr; port = 465; }; sendMail = mkSendMail smtpSettings accounts; recvMail = mkRecvMail serverAddr accounts; cfg = nodes.server.mailsystem; in '' start_all() server.wait_for_unit("multi-user.target") client.wait_for_unit("multi-user.target") server.wait_until_succeeds("${waitForRspamd nodes.server}") with subtest("imap works and retrieves no new mails"): # fetchmail returns EXIT_CODE 1 when no new mail is available client.succeed("${recvMail "normal"} || [ $? -eq 1 ] >&2") with subtest("send succeeds for normal user"): client.succeed("${sendMail "normal" "" accounts."normal2".address '' Message-ID: <123456asdf@host.local.network> Subject: Testmail1 Hello User2, this is some text! ''}") # give the mail server some time to process the mail server.wait_until_fails('${pendingPostqueue}') with subtest("mail can be retrieved via imap"): client.succeed("${recvMail "normal2"} >&2") with subtest("mail header contains no sensitive information"): client.fail("grep '${clientAddr}' $HOME/mail/*") client.succeed("grep '^Message-ID:.*@${cfg.fqdn}>$' $HOME/mail/*") with subtest("mail header contains correct fqdn in received from"): client.succeed("grep 'Received: from ${cfg.fqdn}' $HOME/mail/*") with subtest("user cannot forge from-address"): client.fail("${sendMail "normal" "someotheraddress@example.com" accounts."normal2".address '' Subject: I actually do not own this from-address Hello User2, I'm pretending to be someotheraddress@example.com and the mailserver should reject this attempt. ''}") with subtest("send succeeds for system user"): client.succeed("${sendMail "system" "" accounts."normal".address '' Subject: Testmail2 Hello User1, this is some text! ''}") # give the mail server some time to process the mail server.wait_until_fails('${pendingPostqueue}') with subtest("mail can be retrieved via imap"): client.succeed("${recvMail "normal"} >&2") with subtest("mail sent to system-account is rejected"): client.fail("${sendMail "normal" "someotheraddress@example.com" accounts."system".address '' Subject: Mail to system-account Hello System user, this mail should never reach you as it should be rejected by postfix. ''}") with subtest("server issues no warnings nor errors"): ${checkLogs "server"} ''; }