11 "organization-name": "Company-X",
13 "start-datetime": "2016-04-01T00:00:00Z",
14 "end-datetime": "2016-04-01T23:59:59Z"
16 "contact-info": "sts-reporting@company-x.example",
17 "report-id": "5065427c-23d3-47ca-b6e0-946ea0e8c4be",
21 "policy-string": ["version: STSv1","mode: testing",
22 "mx: *.mail.company-y.example","max_age: 86400"],
23 "policy-domain": "company-y.example",
24 "mx-host": ["*.mail.company-y.example"]
27 "total-successful-session-count": 5326,
28 "total-failure-session-count": 303
31 "result-type": "certificate-expired",
32 "sending-mta-ip": "2001:db8:abcd:0012::1",
33 "receiving-mx-hostname": "mx1.mail.company-y.example",
34 "failed-session-count": 100
36 "result-type": "starttls-not-supported",
37 "sending-mta-ip": "2001:db8:abcd:0013::1",
38 "receiving-mx-hostname": "mx2.mail.company-y.example",
39 "receiving-ip": "203.0.113.56",
40 "failed-session-count": 200,
41 "additional-information": "https://reports.company-x.example/report_info ? id = 5065427 c - 23 d3# StarttlsNotSupported "
43 "result-type": "validation-failure",
44 "sending-mta-ip": "198.51.100.62",
45 "receiving-ip": "203.0.113.58",
46 "receiving-mx-hostname": "mx-backup.mail.company-y.example",
47 "failed-session-count": 3,
48 "failure-reason-code": "X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED"
54var tlsrptMessage = strings.ReplaceAll(`From: tlsrpt@mail.sender.example.com
55Date: Fri, May 09 2017 16:54:30 -0800
56To: mts-sts-tlsrpt@example.net
57Subject: Report Domain: example.net
58Submitter: mail.sender.example.com
59Report-ID: <735ff.e317+bf22029@example.net>
60TLS-Report-Domain: example.net
61TLS-Report-Submitter: mail.sender.example.com
63Content-Type: multipart/report; report-type="tlsrpt";
64 boundary="----=_NextPart_000_024E_01CC9B0A.AFE54C00"
65Content-Language: en-us
67This is a multipart message in MIME format.
69------=_NextPart_000_024E_01CC9B0A.AFE54C00
70Content-Type: text/plain; charset="us-ascii"
71Content-Transfer-Encoding: 7bit
73This is an aggregate TLS report from mail.sender.example.com
75------=_NextPart_000_024E_01CC9B0A.AFE54C00
76Content-Type: application/tlsrpt+json
77Content-Transfer-Encoding: 8bit
78Content-Disposition: attachment;
79 filename="mail.sender.example!example.com!1013662812!1013749130.json.gz"
83------=_NextPart_000_024E_01CC9B0A.AFE54C00--
86// Message without multipart.
87var tlsrptMessage2 = strings.ReplaceAll(`From: tlsrpt@mail.sender.example.com
88To: mts-sts-tlsrpt@example.net
89Subject: Report Domain: example.net
90Report-ID: <735ff.e317+bf22029@example.net>
91TLS-Report-Domain: example.net
92TLS-Report-Submitter: mail.sender.example.com
94Content-Type: application/tlsrpt+json
95Content-Transfer-Encoding: 8bit
96Content-Disposition: attachment;
97 filename="mail.sender.example!example.com!1013662812!1013749130.json.gz"
102func TestReport(t *testing.T) {
106 dec := json.NewDecoder(strings.NewReader(reportJSON))
107 dec.DisallowUnknownFields()
108 if err := dec.Decode(&report); err != nil {
109 t.Fatalf("parsing report: %s", err)
112 if _, err := ParseMessage(xlog, strings.NewReader(tlsrptMessage)); err != nil {
113 t.Fatalf("parsing TLSRPT from message: %s", err)
116 if _, err := ParseMessage(xlog, strings.NewReader(tlsrptMessage2)); err != nil {
117 t.Fatalf("parsing TLSRPT from message: %s", err)
120 if _, err := ParseMessage(xlog, strings.NewReader(strings.ReplaceAll(tlsrptMessage, "multipart/report", "multipart/related"))); err != ErrNoReport {
121 t.Fatalf("got err %v, expected ErrNoReport", err)
124 if _, err := ParseMessage(xlog, strings.NewReader(strings.ReplaceAll(tlsrptMessage, "application/tlsrpt+json", "application/json"))); err != ErrNoReport {
125 t.Fatalf("got err %v, expected ErrNoReport", err)
128 files, err := os.ReadDir("../testdata/tlsreports")
130 t.Fatalf("listing reports: %s", err)
132 for _, file := range files {
133 f, err := os.Open("../testdata/tlsreports/" + file.Name())
135 t.Fatalf("open %q: %s", file, err)
137 if _, err := ParseMessage(xlog, f); err != nil {
138 t.Fatalf("parsing TLSRPT from message %q: %s", file.Name(), err)
144func FuzzParseMessage(f *testing.F) {
146 f.Fuzz(func(t *testing.T, s string) {
147 ParseMessage(xlog, strings.NewReader(s))