mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 08:23:48 +03:00
143 lines
5.1 KiB
Go
143 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,
|
||
|
},
|
||
|
)
|
||
|
}
|