mox/dmarc/parse_test.go
Mechiel Lukkien cb229cb6cf
mox!
2023-01-30 14:27:06 +01:00

142 lines
5.1 KiB
Go

package dmarc
import (
"reflect"
"testing"
)
func TestParse(t *testing.T) {
// ../rfc/7489:3224
// bad cases
bad := func(s string) {
t.Helper()
_, _, err := ParseRecord(s)
if err == nil {
t.Fatalf("got parse success, expected error")
}
}
bad("")
bad("v=")
bad("v=DMARC12") // "2" leftover
bad("v=DMARC1") // semicolon required
bad("v=dmarc1; p=none") // dmarc1 is case-sensitive
bad("v=DMARC1 p=none") // missing ;
bad("v=DMARC1;") // missing p, no rua
bad("v=DMARC1; sp=invalid") // invalid sp, no rua
bad("v=DMARC1; sp=reject; p=reject") // p must be directly after v
bad("v=DMARC1; p=none; p=none") // dup
bad("v=DMARC1; p=none; p=reject") // dup
bad("v=DMARC1;;") // missing tag
bad("v=DMARC1; adkim=x") // bad value
bad("v=DMARC1; aspf=123") // bad value
bad("v=DMARC1; ri=") // missing value
bad("v=DMARC1; ri=-1") // invalid, must be >= 0
bad("v=DMARC1; ri=99999999999999999999999999999999999999") // does not fit in int
bad("v=DMARC1; ri=123bad") // leftover data
bad("v=DMARC1; ri=bad") // not a number
bad("v=DMARC1; fo=")
bad("v=DMARC1; fo=01")
bad("v=DMARC1; fo=bad")
bad("v=DMARC1; rf=bad-trailing-dash-")
bad("v=DMARC1; rf=")
bad("v=DMARC1; rf=bad.non-alphadigitdash")
bad("v=DMARC1; p=badvalue")
bad("v=DMARC1; sp=bad")
bad("v=DMARC1; pct=110")
bad("v=DMARC1; pct=bogus")
bad("v=DMARC1; pct=")
bad("v=DMARC1; rua=")
bad("v=DMARC1; rua=bogus")
bad("v=DMARC1; rua=mailto:dmarc-feedback@example.com!")
bad("v=DMARC1; rua=mailto:dmarc-feedback@example.com!99999999999999999999999999999999999999999999999")
bad("v=DMARC1; rua=mailto:dmarc-feedback@example.com!10p")
valid := func(s string, exp Record) {
t.Helper()
r, _, err := ParseRecord(s)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(r, &exp) {
t.Fatalf("got:\n%#v\nexpected:\n%#v", r, &exp)
}
}
// Return a record with default values, and overrides from r. Only for the fields used below.
record := func(r Record) Record {
rr := DefaultRecord
if r.Policy != "" {
rr.Policy = r.Policy
}
if r.AggregateReportAddresses != nil {
rr.AggregateReportAddresses = r.AggregateReportAddresses
}
if r.FailureReportAddresses != nil {
rr.FailureReportAddresses = r.FailureReportAddresses
}
if r.Percentage != 0 {
rr.Percentage = r.Percentage
}
return rr
}
valid("v=DMARC1; rua=mailto:mjl@mox.example", record(Record{
Policy: "none",
AggregateReportAddresses: []URI{
{Address: "mailto:mjl@mox.example"},
},
})) // ../rfc/7489:1407
valid("v=DMARC1; p=reject; sp=invalid; rua=mailto:mjl@mox.example", record(Record{
Policy: "none",
AggregateReportAddresses: []URI{
{Address: "mailto:mjl@mox.example"},
},
})) // ../rfc/7489:1407
valid("v=DMARC1; p=none; rua=mailto:dmarc-feedback@example.com", record(Record{
Policy: "none",
AggregateReportAddresses: []URI{
{Address: "mailto:dmarc-feedback@example.com"},
},
}))
valid("v=DMARC1; p=none; rua=mailto:dmarc-feedback@example.com;ruf=mailto:auth-reports@example.com", record(Record{
Policy: "none",
AggregateReportAddresses: []URI{
{Address: "mailto:dmarc-feedback@example.com"},
},
FailureReportAddresses: []URI{
{Address: "mailto:auth-reports@example.com"},
},
}))
valid("v=DMARC1; p=quarantine; rua=mailto:dmarc-feedback@example.com,mailto:tld-test@thirdparty.example.net!10m; pct=25", record(Record{
Policy: "quarantine",
AggregateReportAddresses: []URI{
{Address: "mailto:dmarc-feedback@example.com"},
{Address: "mailto:tld-test@thirdparty.example.net", MaxSize: 10, Unit: "m"},
},
Percentage: 25,
}))
valid("V = DMARC1 ; P = reject ;\tSP=none; unknown \t=\t ignored-future-value \t ; adkim=s; aspf=s; rua=mailto:dmarc-feedback@example.com ,\t\tmailto:tld-test@thirdparty.example.net!10m; RUF=mailto:auth-reports@example.com ,\t\tmailto:tld-test@thirdparty.example.net!0G; RI = 123; FO = 0:1:d:s ; RF= afrf : other; Pct = 0",
Record{
Version: "DMARC1",
Policy: "reject",
SubdomainPolicy: "none",
ADKIM: "s",
ASPF: "s",
AggregateReportAddresses: []URI{
{Address: "mailto:dmarc-feedback@example.com"},
{Address: "mailto:tld-test@thirdparty.example.net", MaxSize: 10, Unit: "m"},
},
FailureReportAddresses: []URI{
{Address: "mailto:auth-reports@example.com"},
{Address: "mailto:tld-test@thirdparty.example.net", MaxSize: 0, Unit: "g"},
},
AggregateReportingInterval: 123,
FailureReportingOptions: []string{"0", "1", "d", "s"},
ReportingFormat: []string{"afrf", "other"},
Percentage: 0,
},
)
}