1 # This tests parsedmarc by sending a report to its monitored email
2 # address and reading the results out of Elasticsearch.
6 inherit (import ../../lib/testing-python.nix args) makeTest;
9 dmarcTestReport = builtins.fetchurl {
10 name = "dmarc-test-report";
11 url = "https://github.com/domainaware/parsedmarc/raw/f45ab94e0608088e0433557608d9f4e9517d3afe/samples/aggregate/estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip";
12 sha256 = "0dq64cj49711kbja27pjl2hy0d3azrjxg91kqrh40x46fkn1dwkx";
16 pkgs.writeScriptBin "send-email" ''
17 #!${pkgs.python3.interpreter}
19 from email import encoders
20 from email.mime.base import MIMEBase
21 from email.mime.multipart import MIMEMultipart
22 from email.mime.text import MIMEText
24 sender_email = "dmarc_tester@fake.domain"
25 receiver_email = "${address}"
27 message = MIMEMultipart()
28 message["From"] = sender_email
29 message["To"] = receiver_email
30 message["Subject"] = "DMARC test"
32 message.attach(MIMEText("Testing parsedmarc", "plain"))
34 attachment = MIMEBase("application", "zip")
36 with open("${dmarcTestReport}", "rb") as report:
37 attachment.set_payload(report.read())
39 encoders.encode_base64(attachment)
41 attachment.add_header(
42 "Content-Disposition",
43 "attachment; filename= estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip",
46 message.attach(attachment)
47 text = message.as_string()
49 with smtplib.SMTP('localhost') as server:
50 server.sendmail(sender_email, receiver_email, text)
57 name = "parsedmarc-local-mail";
58 meta = with lib.maintainers; {
59 maintainers = [ talyz ];
65 virtualisation.memorySize = 2048;
68 enableSubmission = true;
69 enableSubmissions = true;
70 submissionsOptions = {
71 smtpd_sasl_auth_enable = "yes";
72 smtpd_client_restrictions = "permit";
76 services.parsedmarc = {
82 hostname = "localhost";
87 environment.systemPackages = [
88 (sendEmail "dmarc@localhost")
93 testScript = { nodes }:
95 esPort = toString nodes.parsedmarc.config.services.elasticsearch.port;
96 valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value";
99 parsedmarc.wait_for_unit("postfix.service")
100 parsedmarc.wait_for_unit("dovecot2.service")
101 parsedmarc.wait_for_unit("parsedmarc.service")
102 parsedmarc.wait_until_succeeds(
103 "curl -sS -f http://localhost:${esPort}"
107 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
108 + " | tee /dev/console"
109 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
111 parsedmarc.succeed("send-email")
112 parsedmarc.wait_until_succeeds(
113 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
114 + " | tee /dev/console"
115 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
122 certs = import ../common/acme/server/snakeoil-certs.nix;
123 mailDomain = certs.domain;
124 parsedmarcDomain = "parsedmarc.fake.domain";
127 name = "parsedmarc-external-mail";
128 meta = with lib.maintainers; {
129 maintainers = [ talyz ];
136 virtualisation.memorySize = 2048;
138 security.pki.certificateFiles = [
142 networking.extraHosts = ''
143 127.0.0.1 ${parsedmarcDomain}
144 ${nodes.mail.config.networking.primaryIPAddress} ${mailDomain}
147 services.parsedmarc = {
149 provision.geoIp = false;
155 password = "${pkgs.writeText "imap-password" "foobar"}";
159 environment.systemPackages = [
167 imports = [ ../common/user-account.nix ];
169 networking.extraHosts = ''
170 127.0.0.1 ${mailDomain}
171 ${nodes.parsedmarc.config.networking.primaryIPAddress} ${parsedmarcDomain}
174 services.dovecot2 = {
176 protocols = [ "imap" ];
177 sslCACert = "${certs.ca.cert}";
178 sslServerCert = "${certs.${mailDomain}.cert}";
179 sslServerKey = "${certs.${mailDomain}.key}";
186 myhostname = mailDomain;
187 mydestination = mailDomain;
189 enableSubmission = true;
190 enableSubmissions = true;
191 submissionsOptions = {
192 smtpd_sasl_auth_enable = "yes";
193 smtpd_client_restrictions = "permit";
196 environment.systemPackages = [ (sendEmail "alice@${mailDomain}") ];
198 networking.firewall.allowedTCPPorts = [ 993 ];
202 testScript = { nodes }:
204 esPort = toString nodes.parsedmarc.config.services.elasticsearch.port;
205 valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value";
208 mail.wait_for_unit("postfix.service")
209 mail.wait_for_unit("dovecot2.service")
212 parsedmarc.wait_for_unit("parsedmarc.service")
213 parsedmarc.wait_until_succeeds(
214 "curl -sS -f http://localhost:${esPort}"
218 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
219 + " | tee /dev/console"
220 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
222 mail.succeed("send-email")
223 parsedmarc.wait_until_succeeds(
224 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
225 + " | tee /dev/console"
226 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"