1import ../make-test-python.nix ({ pkgs, ... }:
2let
3 certs = import ../common/acme/server/snakeoil-certs.nix;
4 domain = certs.domain;
5in {
6 name = "maddy-tls";
7 meta = with pkgs.lib.maintainers; { maintainers = [ onny ]; };
8
9 nodes = {
10 server = { options, ... }: {
11 services.maddy = {
12 enable = true;
13 hostname = domain;
14 primaryDomain = domain;
15 openFirewall = true;
16 ensureAccounts = [ "postmaster@${domain}" ];
17 ensureCredentials = {
18 # Do not use this in production. This will make passwords world-readable
19 # in the Nix store
20 "postmaster@${domain}".passwordFile = "${pkgs.writeText "postmaster" "test"}";
21 };
22 tls = {
23 loader = "file";
24 certificates = [{
25 certPath = "${certs.${domain}.cert}";
26 keyPath = "${certs.${domain}.key}";
27 }];
28 };
29 # Enable TLS listeners. Configuring this via the module is not yet
30 # implemented.
31 config = builtins.replaceStrings [
32 "imap tcp://0.0.0.0:143"
33 "submission tcp://0.0.0.0:587"
34 ] [
35 "imap tls://0.0.0.0:993 tcp://0.0.0.0:143"
36 "submission tls://0.0.0.0:465 tcp://0.0.0.0:587"
37 ] options.services.maddy.config.default;
38 };
39 # Not covered by openFirewall yet
40 networking.firewall.allowedTCPPorts = [ 993 465 ];
41 };
42
43 client = { nodes, ... }: {
44 security.pki.certificateFiles = [
45 certs.ca.cert
46 ];
47 networking.extraHosts = ''
48 ${nodes.server.networking.primaryIPAddress} ${domain}
49 '';
50 environment.systemPackages = [
51 (pkgs.writers.writePython3Bin "send-testmail" { } ''
52 import smtplib
53 import ssl
54 from email.mime.text import MIMEText
55
56 context = ssl.create_default_context()
57 msg = MIMEText("Hello World")
58 msg['Subject'] = 'Test'
59 msg['From'] = "postmaster@${domain}"
60 msg['To'] = "postmaster@${domain}"
61 with smtplib.SMTP_SSL(host='${domain}', port=465, context=context) as smtp:
62 smtp.login('postmaster@${domain}', 'test')
63 smtp.sendmail(
64 'postmaster@${domain}', 'postmaster@${domain}', msg.as_string()
65 )
66 '')
67 (pkgs.writers.writePython3Bin "test-imap" { } ''
68 import imaplib
69
70 with imaplib.IMAP4_SSL('${domain}') as imap:
71 imap.login('postmaster@${domain}', 'test')
72 imap.select()
73 status, refs = imap.search(None, 'ALL')
74 assert status == 'OK'
75 assert len(refs) == 1
76 status, msg = imap.fetch(refs[0], 'BODY[TEXT]')
77 assert status == 'OK'
78 assert msg[0][1].strip() == b"Hello World"
79 '')
80 ];
81 };
82 };
83
84 testScript = ''
85 start_all()
86 server.wait_for_unit("maddy.service")
87 server.wait_for_open_port(143)
88 server.wait_for_open_port(993)
89 server.wait_for_open_port(587)
90 server.wait_for_open_port(465)
91 client.succeed("send-testmail")
92 client.succeed("test-imap")
93 '';
94})