# Simple tests, used for debugging the testing infrastructure; and some
# additional tests for situations not covered by the other files.
---
description: Simple successes
tests:
test1:
description: Straightforward sucesss
helo: example.net
mailfrom: "foobar@example.net"
host: 1.2.3.4
result: pass
test2:
description: HELO is set, but expected to be ignored
helo: blargh
mailfrom: "foobar@example.net"
host: 1.2.3.4
result: pass
zonedata:
example.net:
- SPF: v=spf1 +all
---
description: Simple failures
tests:
test1:
description: Straightforward failure
helo: example.net
mailfrom: "foobar@example.net"
host: 1.2.3.4
result: fail
test2:
description: HELO is set, but expected to be ignored
helo: blargh
mailfrom: "foobar@example.net"
host: 1.2.3.4
result: fail
zonedata:
example.net:
- SPF: v=spf1 -all
---
description: Regexp edge cases for "a", "mx" and "ptr"
tests:
ipv6-with-a:
description: |
Send from an ip6 address that has "a:" inside. If we incorrectly parse
the "ip6" as "a", this results in a permerror since the host doesn't
match.
mailfrom: "foobar@a1.net"
host: a::a
result: pass
bad-a-mask:
description: |
If we incorrectly parse the "ip6" as "a", this results in a permerror
due to an invalid mask.
mailfrom: "foobar@a2.net"
host: 2001:db8:ff0:100::2
result: softfail
exp-contains-mx:
description: exp= contains mx:, which should be ignored.
mailfrom: "foobar@expmx.net"
host: 1.2.3.4
result: softfail
exp-contains-ptr:
description: |
exp= contains ptr:, which should be ignored.
Note this test case involves unusual/invalid domains.
mailfrom: "foobar@expptr.net"
host: 1.2.3.4
result: softfail
zonedata:
a1.net:
- SPF: v=spf1 ip6:a::a ~all
a2.net:
- SPF: v=spf1 ip6:1a0a:cccc::/29 ~all
expmx.net:
- SPF: v=spf1 exp=mx:mymx.com ~all
- MX: [10, mymx.com]
mymx.com:
- A: 1.2.3.4
expptr.net:
- SPF: v=spf1 exp=ptr:lalala.com ~all
4.3.2.1.in-addr.arpa:
- PTR: ptr:lalala.com.
ptr:lalala.com:
- A: 1.2.3.4
---
description: Error on PTR forward resolution
tests:
broken-ptr-forward:
description: |
Check that if during 'ptr' forward resolution we get an error, we skip
the domain (and consequently fail the check).
mailfrom: "foo@domain.net"
host: 1.2.3.4
result: softfail
zonedata:
domain.net:
- SPF: v=spf1 ptr:lalala.com ~all
4.3.2.1.in-addr.arpa:
- PTR: lalala.com
lalala.com:
- TIMEOUT: true
---
description: Permanent error on 'exists' resolution
tests:
exists-perm-error:
description: |
Check that if, during an 'exists' forward resolution we get an error, we
return temperror.
mailfrom: "foo@domain.net"
host: 1.2.3.4
result: temperror
zonedata:
domain.net:
- SPF: v=spf1 exists:lalala.com ~all
lalala.com:
- SERVFAIL: true
---
description: Resolve H macros correctly
tests:
resolve-h-macros:
description: |
Check that '%{h}' macros are correctly resolved to the HELO/EHLO and not
the sender domain.
mailfrom: "foo@domain.net"
helo: holahola
host: 1.2.3.4
result: pass
zonedata:
domain.net:
- SPF: v=spf1 exists:%{h}.com ~all
holahola.com:
- A: 127.0.0.2
---
description: Only include the first 10 PTR results
tests:
only-first-10-ptr:
description: |
Check that if during 'ptr' forward resolution we only consider the first
10 names, and ignore the rest.
mailfrom: "foo@domain.net"
host: 1.2.3.4
result: softfail
zonedata:
domain.net:
- A: 127.0.0.1
- SPF: v=spf1 ptr ~all
4.3.2.1.in-addr.arpa:
- PTR: dom01.com
- PTR: dom02.com
- PTR: dom03.com
- PTR: dom04.com
- PTR: dom05.com
- PTR: dom06.com
- PTR: dom07.com
- PTR: dom08.com
- PTR: dom09.com
- PTR: dom10.com
# Entries below here should get dropped. They would make it pass.
- PTR: domain.net
dom01.com:
- A: 127.0.0.1
dom02.com:
- A: 127.0.0.2
dom03.com:
- A: 127.0.0.3
dom04.com:
- A: 127.0.0.4
dom05.com:
- A: 127.0.0.5
dom06.com:
- A: 127.0.0.6
dom07.com:
- A: 127.0.0.7
dom08.com:
- A: 127.0.0.8
dom09.com:
- A: 127.0.0.9
dom10.com:
- A: 127.0.0.10
---
description: Resolution limits
tests:
resolution-with-10-lookups:
description: |
Check that a resolution with precisely 10 lookups (the default limit)
works fine.
mailfrom: "foo@okay.com"
host: 1.2.3.4
result: pass
resolution-with-11-lookups:
description: |
Check that a resolution with precisely 11 lookups (over default limit)
fails as expected.
mailfrom: "foo@bad.com"
host: 1.2.3.4
result: permerror
zonedata:
okay.com:
- SPF: v=spf1 include:d11 include:d12 include:d13
include:d14 include:d15 -all
bad.com:
- SPF: v=spf1 include:d00
include:d11 include:d12 include:d13
include:d14 include:d15 -all
d00:
- SPF: v=spf1 -all
d11:
- SPF: v=spf1 include:d21 ~all
d12:
- SPF: v=spf1 include:d22 ~all
d13:
- SPF: v=spf1 include:d23 ~all
d14:
- SPF: v=spf1 include:d24 ~all
d15:
- SPF: v=spf1 include:d25 ~all
d21:
- SPF: v=spf1 -all
d22:
- SPF: v=spf1 -all
d23:
- SPF: v=spf1 -all
d24:
- SPF: v=spf1 -all
d25:
- SPF: v=spf1 all
---
description: Lookup limit boundary
tests:
lookup-limit-at-10:
description: |
Check that a resolution with exactly 10 terms that cause DNS lookups is
allowed, and that the terms after them are still evaluated.
mailfrom: "foo@at10"
host: 1.2.3.4
result: pass
lookup-limit-at-10-matches:
description: |
Check that the 10th term that causes a DNS lookup is evaluated, and can
produce a match. It is the last term, so nothing after it can alter the
result.
mailfrom: "foo@at10match"
host: 1.2.3.4
result: pass
lookup-limit-over-a:
description: |
Check that the 11th "a" term is not evaluated, even though it would
match. The limit must be checked before doing the lookup: checking it
only when moving on to the next term allows 11 lookups instead of 10,
and lets the 11th one decide the result.
mailfrom: "foo@over-a"
host: 1.2.3.4
result: permerror
lookup-limit-over-mx:
description: |
Same as lookup-limit-over-a, for the "mx" mechanism.
mailfrom: "foo@over-mx"
host: 1.2.3.4
result: permerror
lookup-limit-over-exists:
description: |
Same as lookup-limit-over-a, for the "exists" mechanism.
mailfrom: "foo@over-exists"
host: 1.2.3.4
result: permerror
lookup-limit-over-ptr:
description: |
Same as lookup-limit-over-a, for the "ptr" mechanism.
mailfrom: "foo@over-ptr"
host: 1.2.3.4
result: permerror
lookup-limit-over-no-match:
description: |
Check that the 11th term causes a permerror even when it does not match
and there is no term after it. Otherwise the record is evaluated to the
end, and the excess lookup goes unnoticed.
mailfrom: "foo@over-nomatch"
host: 1.2.3.4
result: permerror
zonedata:
at10:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
ip4:1.2.3.4 -all
at10match:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch
a:amatch
over-a:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:amatch
over-mx:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
mx:mxmatch
over-exists:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
exists:amatch
over-ptr:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
ptr:ptrmatch.com
over-nomatch:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch
nomatch:
- A: 10.0.0.1
amatch:
- A: 1.2.3.4
mxmatch:
- MX: [10, amatch]
ptrmatch.com:
- A: 1.2.3.4
4.3.2.1.in-addr.arpa:
- PTR: ptrmatch.com
---
description: Void lookup limit
tests:
void-limit-at-2:
description: |
Check that 2 void lookups (the default limit) are allowed, and that the
terms after them are still evaluated.
mailfrom: "foo@atvoid2"
host: 1.2.3.4
result: pass
void-limit-over-a:
description: |
Check that exceeding the void lookup limit on an "a" term causes a
permerror, even when it is the last term. The limit must be checked
right after the lookup: checking it only when moving on to the next
term lets the excess go unnoticed if there is no next term.
mailfrom: "foo@overvoid-a"
host: 1.2.3.4
result: permerror
void-limit-over-mx:
description: |
Same as void-limit-over-a, for the "mx" mechanism. The domain exists but
has no MX records, which is a void lookup.
mailfrom: "foo@overvoid-mx"
host: 1.2.3.4
result: permerror
void-limit-over-exists:
description: |
Same as void-limit-over-a, for the "exists" mechanism.
mailfrom: "foo@overvoid-exists"
host: 1.2.3.4
result: permerror
void-limit-over-ptr:
description: |
Same as void-limit-over-a, for the "ptr" mechanism. The address has no
PTR records, which is a void lookup.
mailfrom: "foo@overvoid-ptr"
host: 1.2.3.4
result: permerror
void-limit-over-in-include:
description: |
Check that exceeding the void lookup limit inside an "include" makes the
whole evaluation return permerror, instead of just making the include
not match. Note the include is the last term, so nothing after it can
turn the excess into a permerror on its own.
mailfrom: "foo@overvoid-include"
host: 1.2.3.4
result: permerror
zonedata:
atvoid2:
- SPF: v=spf1 a:void1 a:void2 ip4:1.2.3.4 -all
overvoid-a:
- SPF: v=spf1 a:void1 a:void2 a:void3
overvoid-mx:
- SPF: v=spf1 a:void1 a:void2 mx:onlya
overvoid-exists:
- SPF: v=spf1 a:void1 a:void2 exists:void3
overvoid-ptr:
- SPF: v=spf1 a:void1 a:void2 ptr
overvoid-include:
- SPF: v=spf1 include:overvoid-a
onlya:
- A: 1.2.3.4
---
description: MX resolution limits
tests:
mx-resolution-10-terms:
description: |
Check that a resolution with 10 "mx" terms works, because it's within
the limit. Each term will resolve to multiple records, but those
shouldn't be individually counted (there's a limit of 10 MX records per
MX lookup, but that's tested separately).
mailfrom: "foo@mx10"
host: 1.2.3.4
result: pass
mx-resolution-11-terms:
description: |
Check that a resolution with 11 "mx" terms, causes a permerror due to
exceeding lookup limits.
mailfrom: "foo@mx11"
host: 1.2.3.4
result: permerror
zonedata:
mx10:
- SPF: v=spf1 mx:domain mx:domain mx:domain mx:domain mx:domain
mx:domain mx:domain mx:domain mx:domain mx:domain
all
mx11:
- SPF: v=spf1 mx:domain mx:domain mx:domain mx:domain mx:domain
mx:domain mx:domain mx:domain mx:domain mx:domain
mx:domain all
domain:
- MX: [1, blah1]
- MX: [2, blah2]
- MX: [3, blah3]
---
description: PTR resolution limits
tests:
ptr-resolution-10-terms:
description: |
Check that a resolution with 10 "ptr" terms works, because it's within
the limit, and that the terms after them are still evaluated. The
address is only resolved once and the names reused, but each term still
counts against the limit.
mailfrom: "foo@ptr10"
host: 1.2.3.4
result: pass
ptr-resolution-11-terms:
description: |
Check that a resolution with 11 "ptr" terms causes a permerror due to
exceeding lookup limits, even though only one DNS lookup is performed.
mailfrom: "foo@ptr11"
host: 1.2.3.4
result: permerror
ptr-resolution-mixed-terms:
description: |
Check that "ptr" terms are counted individually when mixed with other
terms that cause DNS lookups: here the second "ptr" is the 11th term,
and takes the resolution over the limit.
mailfrom: "foo@ptrmixed"
host: 1.2.3.4
result: permerror
zonedata:
ptr10:
- SPF: v=spf1 ptr:nomatch.com ptr:nomatch.com ptr:nomatch.com
ptr:nomatch.com ptr:nomatch.com ptr:nomatch.com
ptr:nomatch.com ptr:nomatch.com ptr:nomatch.com
ptr:nomatch.com ip4:1.2.3.4 -all
ptr11:
- SPF: v=spf1 ptr:nomatch.com ptr:nomatch.com ptr:nomatch.com
ptr:nomatch.com ptr:nomatch.com ptr:nomatch.com
ptr:nomatch.com ptr:nomatch.com ptr:nomatch.com
ptr:nomatch.com ptr:nomatch.com -all
ptrmixed:
- SPF: v=spf1 a:nomatch a:nomatch a:nomatch a:nomatch a:nomatch
a:nomatch a:nomatch a:nomatch a:nomatch
ptr:nomatch.com ptr:nomatch.com -all
nomatch:
- A: 10.0.0.1
ptrhost.com:
- A: 1.2.3.4
4.3.2.1.in-addr.arpa:
- PTR: ptrhost.com
---
description: NXDOMAIN tests
tests:
one-mx-not-found:
description: |
Check that if one of the MXs is not found, we continue evaluating the
rest.
mailfrom: "foo@d00"
host: 1.2.3.4
result: pass
all-mx-not-found:
description: |
Check that if none of the MXs is not found, we continue evaluating the
rest of the terms.
mailfrom: "foo@d01"
host: 1.2.3.4
result: pass
domain-not-found:
description: |
Check if the top-level domain is not found (which is different that it
existing but having no TXT record).
mailfrom: "foo@doesnotexist"
host: 1.2.3.4
result: none
include-not-found:
description: |
For include, if the recursive check returns None, it should make the
evaluation return PermError.
mailfrom: "foo@d02"
host: 1.2.3.4
result: permerror
redirect-not-found:
description: |
For redirect, if the recursive check returns None, it should make the
evaluation return PermError.
mailfrom: "foo@d03"
host: 1.2.3.4
result: permerror
zonedata:
d00:
- SPF: v=spf1 mx -all
- MX: [10, "doesnotexist"]
- MX: [20, "sender"]
d01:
- SPF: v=spf1 mx ip4:1.2.3.4 -all
- MX: [10, "doesnotexist"]
- MX: [20, "doesnotexist"]
d02:
- SPF: v=spf1 include:doesnotexist all
d03:
- SPF: v=spf1 redirect=doesnotexist
sender:
- A: 1.2.3.4
---
description: PTR forward confirmation
tests:
ptr-forward-confirmed:
description: |
A PTR name that resolves back to the IP being checked is validated, and
matches.
mailfrom: "foo@good.com"
host: 1.2.3.4
result: pass
ptr-resolves-elsewhere:
description: |
A PTR name that resolves, but to a different address, must NOT be
validated: RFC 7208 section 5.5 requires <ip> to be among the addresses
returned for the name, not just that the name resolves to something.
mailfrom: "foo@bad.com"
host: 1.2.3.4
result: fail
ptr-resolves-elsewhere-v6:
description: |
As above, but the name resolves to an address of a different family.
mailfrom: "foo@badv6.com"
host: 1.2.3.4
result: fail
ptr-one-of-many:
description: |
A name with several addresses is validated if any one of them is the IP
being checked.
mailfrom: "foo@many.com"
host: 1.2.3.4
result: pass
zonedata:
good.com:
- SPF: v=spf1 ptr:good.com -all
- A: 1.2.3.4
bad.com:
- SPF: v=spf1 ptr:bad.com -all
- A: 9.9.9.9
badv6.com:
- SPF: v=spf1 ptr:badv6.com -all
- AAAA: 2001:db8::1
many.com:
- SPF: v=spf1 ptr:many.com -all
- A: 10.0.0.1
- A: 1.2.3.4
- A: 10.0.0.2
4.3.2.1.in-addr.arpa:
- PTR: good.com
- PTR: bad.com
- PTR: badv6.com
- PTR: many.com
---
description: PTR domain matching
tests:
ptr-exact:
description: |
The validated name is the target domain itself, so it matches.
mailfrom: "foo@exact.com"
host: 1.2.3.4
result: pass
ptr-subdomain:
description: |
The validated name is a subdomain of the target domain, so it matches.
mailfrom: "foo@sub.com"
host: 1.2.3.5
result: pass
ptr-not-subdomain:
description: |
The validated name ends with the target domain as a string, but not at
a label boundary, so it must NOT match: RFC 7208 section 5.5 requires
the name to be the target domain, or a subdomain of it.
mailfrom: "foo@notsub.com"
host: 1.2.3.6
result: fail
ptr-target-trailing-dot:
description: |
A target domain written with a trailing dot matches the same names as
one written without it.
mailfrom: "foo@dot.com"
host: 1.2.3.7
result: pass
zonedata:
exact.com:
- SPF: v=spf1 ptr:exactname.com -all
exactname.com:
- A: 1.2.3.4
4.3.2.1.in-addr.arpa:
- PTR: exactname.com
sub.com:
- SPF: v=spf1 ptr:subname.com -all
deep.sub.subname.com:
- A: 1.2.3.5
5.3.2.1.in-addr.arpa:
- PTR: deep.sub.subname.com
notsub.com:
- SPF: v=spf1 ptr:example.com -all
notexample.com:
- A: 1.2.3.6
6.3.2.1.in-addr.arpa:
- PTR: notexample.com
dot.com:
- SPF: v=spf1 ptr:dotname.com. -all
dotname.com:
- A: 1.2.3.7
7.3.2.1.in-addr.arpa:
- PTR: dotname.com