coppertone 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/.travis.yml +7 -0
- data/Gemfile +7 -0
- data/LICENSE +201 -0
- data/README.md +58 -0
- data/Rakefile +140 -0
- data/coppertone.gemspec +27 -0
- data/lib/coppertone/class_builder.rb +20 -0
- data/lib/coppertone/directive.rb +38 -0
- data/lib/coppertone/dns/error.rb +9 -0
- data/lib/coppertone/dns/mock_client.rb +106 -0
- data/lib/coppertone/dns/resolv_client.rb +110 -0
- data/lib/coppertone/dns.rb +3 -0
- data/lib/coppertone/domain_spec.rb +45 -0
- data/lib/coppertone/error.rb +29 -0
- data/lib/coppertone/ip_address_wrapper.rb +75 -0
- data/lib/coppertone/macro_context.rb +67 -0
- data/lib/coppertone/macro_string/macro_expand.rb +84 -0
- data/lib/coppertone/macro_string/macro_literal.rb +24 -0
- data/lib/coppertone/macro_string/macro_parser.rb +62 -0
- data/lib/coppertone/macro_string/macro_static_expand.rb +52 -0
- data/lib/coppertone/macro_string.rb +31 -0
- data/lib/coppertone/mechanism/a.rb +16 -0
- data/lib/coppertone/mechanism/all.rb +24 -0
- data/lib/coppertone/mechanism/cidr_parser.rb +14 -0
- data/lib/coppertone/mechanism/domain_spec_mechanism.rb +18 -0
- data/lib/coppertone/mechanism/domain_spec_optional.rb +46 -0
- data/lib/coppertone/mechanism/domain_spec_required.rb +37 -0
- data/lib/coppertone/mechanism/domain_spec_with_dual_cidr.rb +114 -0
- data/lib/coppertone/mechanism/exists.rb +14 -0
- data/lib/coppertone/mechanism/include.rb +18 -0
- data/lib/coppertone/mechanism/include_matcher.rb +34 -0
- data/lib/coppertone/mechanism/ip4.rb +13 -0
- data/lib/coppertone/mechanism/ip6.rb +13 -0
- data/lib/coppertone/mechanism/ip_mechanism.rb +48 -0
- data/lib/coppertone/mechanism/mx.rb +40 -0
- data/lib/coppertone/mechanism/ptr.rb +17 -0
- data/lib/coppertone/mechanism.rb +32 -0
- data/lib/coppertone/modifier/base.rb +24 -0
- data/lib/coppertone/modifier/exp.rb +34 -0
- data/lib/coppertone/modifier/redirect.rb +17 -0
- data/lib/coppertone/modifier/unknown.rb +16 -0
- data/lib/coppertone/modifier.rb +30 -0
- data/lib/coppertone/qualifier.rb +45 -0
- data/lib/coppertone/record.rb +86 -0
- data/lib/coppertone/record_evaluator.rb +63 -0
- data/lib/coppertone/record_finder.rb +34 -0
- data/lib/coppertone/request.rb +68 -0
- data/lib/coppertone/request_context.rb +67 -0
- data/lib/coppertone/request_count_limiter.rb +36 -0
- data/lib/coppertone/result.rb +50 -0
- data/lib/coppertone/sender_identity.rb +39 -0
- data/lib/coppertone/spf_service.rb +9 -0
- data/lib/coppertone/term.rb +13 -0
- data/lib/coppertone/utils/domain_utils.rb +59 -0
- data/lib/coppertone/utils/host_utils.rb +22 -0
- data/lib/coppertone/utils/ip_in_domain_checker.rb +53 -0
- data/lib/coppertone/utils/validated_domain_finder.rb +40 -0
- data/lib/coppertone/utils.rb +4 -0
- data/lib/coppertone/version.rb +3 -0
- data/lib/coppertone.rb +48 -0
- data/lib/resolv/dns/resource/in/spf.rb +15 -0
- data/spec/directive_spec.rb +41 -0
- data/spec/dns/resolv_client_spec.rb +307 -0
- data/spec/domain_spec_spec.rb +35 -0
- data/spec/ip_address_wrapper_spec.rb +67 -0
- data/spec/macro_context_spec.rb +69 -0
- data/spec/macro_string/macro_expand_spec.rb +79 -0
- data/spec/macro_string/macro_literal_spec.rb +27 -0
- data/spec/macro_string/macro_static_expand_spec.rb +67 -0
- data/spec/macro_string_spec.rb +20 -0
- data/spec/mechanism/a_spec.rb +198 -0
- data/spec/mechanism/all_spec.rb +22 -0
- data/spec/mechanism/exists_spec.rb +91 -0
- data/spec/mechanism/include_spec.rb +43 -0
- data/spec/mechanism/ip4_spec.rb +110 -0
- data/spec/mechanism/ip6_spec.rb +104 -0
- data/spec/mechanism/mx_spec.rb +51 -0
- data/spec/mechanism/ptr_spec.rb +43 -0
- data/spec/mechanism_spec.rb +4 -0
- data/spec/modifier_spec.rb +4 -0
- data/spec/open_spf/ALL_mechanism_syntax_spec.rb +38 -0
- data/spec/open_spf/A_mechanism_syntax_spec.rb +159 -0
- data/spec/open_spf/EXISTS_mechanism_syntax_spec.rb +46 -0
- data/spec/open_spf/IP4_mechanism_syntax_spec.rb +59 -0
- data/spec/open_spf/IP6_mechanism_syntax_spec.rb +60 -0
- data/spec/open_spf/Include_mechanism_semantics_and_syntax_spec.rb +56 -0
- data/spec/open_spf/Initial_processing_spec.rb +77 -0
- data/spec/open_spf/MX_mechanism_syntax_spec.rb +119 -0
- data/spec/open_spf/Macro_expansion_rules_spec.rb +154 -0
- data/spec/open_spf/PTR_mechanism_syntax_spec.rb +42 -0
- data/spec/open_spf/Processing_limits_spec.rb +72 -0
- data/spec/open_spf/Record_evaluation_spec.rb +75 -0
- data/spec/open_spf/Record_lookup_spec.rb +48 -0
- data/spec/open_spf/Selecting_records_spec.rb +61 -0
- data/spec/open_spf/Semantics_of_exp_and_other_modifiers_spec.rb +167 -0
- data/spec/open_spf/Test_cases_from_implementation_bugs_spec.rb +17 -0
- data/spec/qualifier_spec.rb +54 -0
- data/spec/record_evaluator_spec.rb +4 -0
- data/spec/record_finder_spec.rb +4 -0
- data/spec/record_spec.rb +100 -0
- data/spec/request_context_spec.rb +43 -0
- data/spec/request_count_limiter_spec.rb +28 -0
- data/spec/result_spec.rb +4 -0
- data/spec/rfc7208-tests.yml +2548 -0
- data/spec/sender_identity_spec.rb +69 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/term_spec.rb +38 -0
- data/spec/utils/domain_utils_spec.rb +60 -0
- data/spec/utils/host_utils_spec.rb +32 -0
- data/spec/utils/ip_in_domain_checker_spec.rb +4 -0
- data/spec/utils/validated_domain_finder_spec.rb +4 -0
- metadata +306 -0
|
@@ -0,0 +1,2548 @@
|
|
|
1
|
+
# This is the openspf.org test suite (release 2014.04) based on RFC 7208.
|
|
2
|
+
# http://www.openspf.org/Test_Suite
|
|
3
|
+
#
|
|
4
|
+
# $Id: rfc7208-tests.yml,v 1.1.2.8 2014/08/02 18:35:01 customdesigned Exp $
|
|
5
|
+
# vim:sw=2 sts=2 et
|
|
6
|
+
#
|
|
7
|
+
# See rfc7208-tests.CHANGES for a changelog.
|
|
8
|
+
#
|
|
9
|
+
# Contributors:
|
|
10
|
+
# Stuart D Gathman 90% of the tests
|
|
11
|
+
# Julian Mehnle some tests, proofread YAML syntax, formal schema
|
|
12
|
+
# Frank Ellermann
|
|
13
|
+
# Scott Kitterman
|
|
14
|
+
# Wayne Schlitt
|
|
15
|
+
# Craig Whitmore
|
|
16
|
+
# Norman Maurer
|
|
17
|
+
# Mark Shewmaker
|
|
18
|
+
# Philip Gladstone
|
|
19
|
+
#
|
|
20
|
+
# For RFC 4408, the test suite was designed for use with SPF (type 99) and TXT
|
|
21
|
+
# implementations. In RFC 7208, use of type SPF has been removed.
|
|
22
|
+
#
|
|
23
|
+
# The "Selecting records" test section is the only one concerned with weeding
|
|
24
|
+
# out (incorrect) queries for type SPF of any kind or proper response to
|
|
25
|
+
# duplicate or conflicting records. Other sections rely on auto-magic
|
|
26
|
+
# duplication of SPF to TXT records (by test suite drivers) to test all
|
|
27
|
+
# implementation types with one specification.
|
|
28
|
+
#
|
|
29
|
+
# All new tests should use Documentation IPs for both IP4 and IP6. I was
|
|
30
|
+
# stupid to use 1.2.3.4 - that is a real global IP (although it doesn't ping).
|
|
31
|
+
#
|
|
32
|
+
---
|
|
33
|
+
description: Initial processing
|
|
34
|
+
tests:
|
|
35
|
+
toolonglabel:
|
|
36
|
+
description: >-
|
|
37
|
+
DNS labels limited to 63 chars.
|
|
38
|
+
comment: >-
|
|
39
|
+
For initial processing, a long label results in None, not TempError
|
|
40
|
+
spec: 4.3/1
|
|
41
|
+
helo: mail.example.net
|
|
42
|
+
host: 1.2.3.5
|
|
43
|
+
mailfrom: lyme.eater@A123456789012345678901234567890123456789012345678901234567890123.example.com
|
|
44
|
+
result: none
|
|
45
|
+
longlabel:
|
|
46
|
+
description: >-
|
|
47
|
+
DNS labels limited to 63 chars.
|
|
48
|
+
spec: 4.3/1
|
|
49
|
+
helo: mail.example.net
|
|
50
|
+
host: 1.2.3.5
|
|
51
|
+
mailfrom: lyme.eater@A12345678901234567890123456789012345678901234567890123456789012.example.com
|
|
52
|
+
result: fail
|
|
53
|
+
emptylabel:
|
|
54
|
+
spec: 4.3/1
|
|
55
|
+
helo: mail.example.net
|
|
56
|
+
host: 1.2.3.5
|
|
57
|
+
mailfrom: lyme.eater@A...example.com
|
|
58
|
+
result: none
|
|
59
|
+
helo-not-fqdn:
|
|
60
|
+
spec: 4.3/1
|
|
61
|
+
helo: A2345678
|
|
62
|
+
host: 1.2.3.5
|
|
63
|
+
mailfrom: ""
|
|
64
|
+
result: none
|
|
65
|
+
helo-domain-literal:
|
|
66
|
+
spec: 4.3/1
|
|
67
|
+
helo: "[1.2.3.5]"
|
|
68
|
+
host: 1.2.3.5
|
|
69
|
+
mailfrom: ""
|
|
70
|
+
result: none
|
|
71
|
+
nolocalpart:
|
|
72
|
+
spec: 4.3/2
|
|
73
|
+
helo: mail.example.net
|
|
74
|
+
host: 1.2.3.4
|
|
75
|
+
mailfrom: '@example.net'
|
|
76
|
+
result: fail
|
|
77
|
+
explanation: postmaster
|
|
78
|
+
domain-literal:
|
|
79
|
+
spec: 4.3/1
|
|
80
|
+
helo: OEMCOMPUTER
|
|
81
|
+
host: 1.2.3.5
|
|
82
|
+
mailfrom: "foo@[1.2.3.5]"
|
|
83
|
+
result: none
|
|
84
|
+
non-ascii-policy:
|
|
85
|
+
description: >-
|
|
86
|
+
SPF policies are restricted to 7-bit ascii.
|
|
87
|
+
spec: 3.1/1
|
|
88
|
+
helo: hosed
|
|
89
|
+
host: 1.2.3.4
|
|
90
|
+
mailfrom: "foobar@hosed.example.com"
|
|
91
|
+
result: permerror
|
|
92
|
+
non-ascii-mech:
|
|
93
|
+
description: >-
|
|
94
|
+
SPF policies are restricted to 7-bit ascii.
|
|
95
|
+
comment: >-
|
|
96
|
+
Checking a possibly different code path for non-ascii chars.
|
|
97
|
+
spec: 3.1/1
|
|
98
|
+
helo: hosed
|
|
99
|
+
host: 1.2.3.4
|
|
100
|
+
mailfrom: "foobar@hosed2.example.com"
|
|
101
|
+
result: permerror
|
|
102
|
+
non-ascii-result:
|
|
103
|
+
description: >-
|
|
104
|
+
SPF policies are restricted to 7-bit ascii.
|
|
105
|
+
comment: >-
|
|
106
|
+
Checking yet another code path for non-ascii chars.
|
|
107
|
+
spec: 3.1/1
|
|
108
|
+
helo: hosed
|
|
109
|
+
host: 1.2.3.4
|
|
110
|
+
mailfrom: "foobar@hosed3.example.com"
|
|
111
|
+
result: permerror
|
|
112
|
+
non-ascii-non-spf:
|
|
113
|
+
description: >-
|
|
114
|
+
Non-ascii content in non-SPF related records.
|
|
115
|
+
comment: >-
|
|
116
|
+
Non-SPF related TXT records are none of our business.
|
|
117
|
+
spec: 4.5/1
|
|
118
|
+
helo: hosed
|
|
119
|
+
host: 1.2.3.4
|
|
120
|
+
mailfrom: "foobar@nothosed.example.com"
|
|
121
|
+
result: fail
|
|
122
|
+
explanation: DEFAULT
|
|
123
|
+
control-char-policy:
|
|
124
|
+
description: >-
|
|
125
|
+
Mechanisms are separated by spaces only, not any control char.
|
|
126
|
+
spec: 4.6.1/2
|
|
127
|
+
helo: hosed
|
|
128
|
+
host: 192.0.2.3
|
|
129
|
+
mailfrom: "foobar@ctrl.example.com"
|
|
130
|
+
result: permerror
|
|
131
|
+
zonedata:
|
|
132
|
+
example.com:
|
|
133
|
+
- TIMEOUT
|
|
134
|
+
example.net:
|
|
135
|
+
- TXT: v=spf1 -all exp=exp.example.net
|
|
136
|
+
a.example.net:
|
|
137
|
+
- TXT: v=spf1 -all exp=exp.example.net
|
|
138
|
+
exp.example.net:
|
|
139
|
+
- TXT: '%{l}'
|
|
140
|
+
a12345678901234567890123456789012345678901234567890123456789012.example.com:
|
|
141
|
+
- TXT: v=spf1 -all
|
|
142
|
+
hosed.example.com:
|
|
143
|
+
- TXT: "v=spf1 a:\xEF\xBB\xBFgarbage.example.net -all"
|
|
144
|
+
hosed2.example.com:
|
|
145
|
+
- TXT: "v=spf1 \x80a:example.net -all"
|
|
146
|
+
hosed3.example.com:
|
|
147
|
+
- TXT: "v=spf1 a:example.net \x96all"
|
|
148
|
+
nothosed.example.com:
|
|
149
|
+
- TXT: "v=spf1 a:example.net -all"
|
|
150
|
+
- TXT: "\x96"
|
|
151
|
+
ctrl.example.com:
|
|
152
|
+
- TXT: "v=spf1 a:ctrl.example.com\x0dptr -all"
|
|
153
|
+
- A: 192.0.2.3
|
|
154
|
+
---
|
|
155
|
+
description: Record lookup
|
|
156
|
+
tests:
|
|
157
|
+
both:
|
|
158
|
+
spec: 4.4/1
|
|
159
|
+
helo: mail.example.net
|
|
160
|
+
host: 1.2.3.4
|
|
161
|
+
mailfrom: foo@both.example.net
|
|
162
|
+
result: fail
|
|
163
|
+
txtonly:
|
|
164
|
+
description: Result is none if checking SPF records only
|
|
165
|
+
(which you should not be doing).
|
|
166
|
+
spec: 4.4/1
|
|
167
|
+
helo: mail.example.net
|
|
168
|
+
host: 1.2.3.4
|
|
169
|
+
mailfrom: foo@txtonly.example.net
|
|
170
|
+
result: fail
|
|
171
|
+
spfonly:
|
|
172
|
+
description: Result is none if checking TXT records only.
|
|
173
|
+
spec: 4.4/1
|
|
174
|
+
helo: mail.example.net
|
|
175
|
+
host: 1.2.3.4
|
|
176
|
+
mailfrom: foo@spfonly.example.net
|
|
177
|
+
result: none
|
|
178
|
+
spftimeout:
|
|
179
|
+
description: >-
|
|
180
|
+
TXT record present, but SPF lookup times out.
|
|
181
|
+
Result is temperror if checking SPF records only. Fortunately,
|
|
182
|
+
we don't do type SPF anymore.
|
|
183
|
+
comment: >-
|
|
184
|
+
This actually happens for a popular braindead DNS server.
|
|
185
|
+
spec: 4.4/1
|
|
186
|
+
helo: mail.example.net
|
|
187
|
+
host: 1.2.3.4
|
|
188
|
+
mailfrom: foo@spftimeout.example.net
|
|
189
|
+
result: fail
|
|
190
|
+
txttimeout:
|
|
191
|
+
description: >-
|
|
192
|
+
SPF record present, but TXT lookup times out.
|
|
193
|
+
If only TXT records are checked, result is temperror.
|
|
194
|
+
spec: 4.4/1
|
|
195
|
+
helo: mail.example.net
|
|
196
|
+
host: 1.2.3.4
|
|
197
|
+
mailfrom: foo@txttimeout.example.net
|
|
198
|
+
result: temperror
|
|
199
|
+
nospftxttimeout:
|
|
200
|
+
description: >-
|
|
201
|
+
No SPF record present, and TXT lookup times out.
|
|
202
|
+
If only TXT records are checked, result is temperror.
|
|
203
|
+
comment: >-
|
|
204
|
+
Because TXT records is where v=spf1 records will likely be, returning
|
|
205
|
+
temperror will try again later. A timeout due to a braindead server
|
|
206
|
+
is unlikely in the case of TXT, as opposed to the newer SPF RR.
|
|
207
|
+
spec: 4.4/1
|
|
208
|
+
helo: mail.example.net
|
|
209
|
+
host: 1.2.3.4
|
|
210
|
+
mailfrom: foo@nospftxttimeout.example.net
|
|
211
|
+
result: temperror
|
|
212
|
+
alltimeout:
|
|
213
|
+
description: Both TXT and SPF queries time out
|
|
214
|
+
spec: 4.4/2
|
|
215
|
+
helo: mail.example.net
|
|
216
|
+
host: 1.2.3.4
|
|
217
|
+
mailfrom: foo@alltimeout.example.net
|
|
218
|
+
result: temperror
|
|
219
|
+
zonedata:
|
|
220
|
+
both.example.net:
|
|
221
|
+
- TXT: v=spf1 -all
|
|
222
|
+
- SPF: v=spf1 -all
|
|
223
|
+
txtonly.example.net:
|
|
224
|
+
- TXT: v=spf1 -all
|
|
225
|
+
spfonly.example.net:
|
|
226
|
+
- SPF: v=spf1 -all
|
|
227
|
+
- TXT: NONE
|
|
228
|
+
spftimeout.example.net:
|
|
229
|
+
- TXT: v=spf1 -all
|
|
230
|
+
- TIMEOUT
|
|
231
|
+
txttimeout.example.net:
|
|
232
|
+
- SPF: v=spf1 -all
|
|
233
|
+
- TXT: NONE
|
|
234
|
+
- TIMEOUT
|
|
235
|
+
nospftxttimeout.example.net:
|
|
236
|
+
- SPF: "v=spf3 !a:yahoo.com -all"
|
|
237
|
+
- TXT: NONE
|
|
238
|
+
- TIMEOUT
|
|
239
|
+
alltimeout.example.net:
|
|
240
|
+
- TIMEOUT
|
|
241
|
+
---
|
|
242
|
+
description: Selecting records
|
|
243
|
+
tests:
|
|
244
|
+
nospace1:
|
|
245
|
+
description: >-
|
|
246
|
+
Version must be terminated by space or end of record. TXT pieces
|
|
247
|
+
are joined without intervening spaces.
|
|
248
|
+
spec: 4.5/4
|
|
249
|
+
helo: mail.example1.com
|
|
250
|
+
host: 1.2.3.4
|
|
251
|
+
mailfrom: foo@example2.com
|
|
252
|
+
result: none
|
|
253
|
+
empty:
|
|
254
|
+
description: Empty SPF record.
|
|
255
|
+
spec: 4.5/4
|
|
256
|
+
helo: mail1.example1.com
|
|
257
|
+
host: 1.2.3.4
|
|
258
|
+
mailfrom: foo@example1.com
|
|
259
|
+
result: neutral
|
|
260
|
+
nospace2:
|
|
261
|
+
spec: 4.5/4
|
|
262
|
+
helo: mail.example1.com
|
|
263
|
+
host: 1.2.3.4
|
|
264
|
+
mailfrom: foo@example3.com
|
|
265
|
+
result: pass
|
|
266
|
+
spfoverride:
|
|
267
|
+
description: >-
|
|
268
|
+
SPF records no longer used.
|
|
269
|
+
spec: 4.5/5
|
|
270
|
+
helo: mail.example1.com
|
|
271
|
+
host: 1.2.3.4
|
|
272
|
+
mailfrom: foo@example4.com
|
|
273
|
+
result: fail
|
|
274
|
+
multitxt1:
|
|
275
|
+
description: >-
|
|
276
|
+
Implementations should give permerror/unknown because of
|
|
277
|
+
the conflicting TXT records.
|
|
278
|
+
spec: 4.5/5
|
|
279
|
+
helo: mail.example1.com
|
|
280
|
+
host: 1.2.3.4
|
|
281
|
+
mailfrom: foo@example5.com
|
|
282
|
+
result: permerror
|
|
283
|
+
multitxt2:
|
|
284
|
+
description: >-
|
|
285
|
+
Multiple records is a permerror, v=spf1 is case insensitive
|
|
286
|
+
spec: 4.5/6
|
|
287
|
+
helo: mail.example1.com
|
|
288
|
+
host: 1.2.3.4
|
|
289
|
+
mailfrom: foo@example6.com
|
|
290
|
+
result: permerror
|
|
291
|
+
multispf1:
|
|
292
|
+
description: >-
|
|
293
|
+
Multiple records is a permerror, even when they are identical.
|
|
294
|
+
However, this situation cannot be reliably reproduced with live
|
|
295
|
+
DNS since cache and resolvers are allowed to combine identical
|
|
296
|
+
records.
|
|
297
|
+
spec: 4.5/6
|
|
298
|
+
helo: mail.example1.com
|
|
299
|
+
host: 1.2.3.4
|
|
300
|
+
mailfrom: foo@example7.com
|
|
301
|
+
result: [permerror, fail]
|
|
302
|
+
multispf2:
|
|
303
|
+
description: >-
|
|
304
|
+
Ignoring SPF-type records will give pass because there is a (single)
|
|
305
|
+
TXT record.
|
|
306
|
+
spec: 4.5/6
|
|
307
|
+
helo: mail.example1.com
|
|
308
|
+
host: 1.2.3.4
|
|
309
|
+
mailfrom: foo@example8.com
|
|
310
|
+
result: pass
|
|
311
|
+
nospf:
|
|
312
|
+
spec: 4.5/7
|
|
313
|
+
helo: mail.example1.com
|
|
314
|
+
host: 1.2.3.4
|
|
315
|
+
mailfrom: foo@mail.example1.com
|
|
316
|
+
result: none
|
|
317
|
+
case-insensitive:
|
|
318
|
+
description: >-
|
|
319
|
+
v=spf1 is case insensitive
|
|
320
|
+
spec: 4.5/6
|
|
321
|
+
helo: mail.example1.com
|
|
322
|
+
host: 1.2.3.4
|
|
323
|
+
mailfrom: foo@example9.com
|
|
324
|
+
result: softfail
|
|
325
|
+
zonedata:
|
|
326
|
+
example3.com:
|
|
327
|
+
- TXT: v=spf10
|
|
328
|
+
- TXT: v=spf1 mx
|
|
329
|
+
- MX: [0, mail.example1.com]
|
|
330
|
+
example1.com:
|
|
331
|
+
- TXT: v=spf1
|
|
332
|
+
example2.com:
|
|
333
|
+
- TXT: ['v=spf1', 'mx']
|
|
334
|
+
mail.example1.com:
|
|
335
|
+
- A: 1.2.3.4
|
|
336
|
+
example4.com:
|
|
337
|
+
- SPF: v=spf1 +all
|
|
338
|
+
- TXT: v=spf1 -all
|
|
339
|
+
example5.com:
|
|
340
|
+
- SPF: v=spf1 +all
|
|
341
|
+
- TXT: v=spf1 -all
|
|
342
|
+
- TXT: v=spf1 +all
|
|
343
|
+
example6.com:
|
|
344
|
+
- TXT: v=spf1 -all
|
|
345
|
+
- TXT: V=sPf1 +all
|
|
346
|
+
example7.com:
|
|
347
|
+
- TXT: v=spf1 -all
|
|
348
|
+
- TXT: v=spf1 -all
|
|
349
|
+
example8.com:
|
|
350
|
+
- SPF: V=spf1 -all
|
|
351
|
+
- SPF: v=spf1 -all
|
|
352
|
+
- TXT: v=spf1 +all
|
|
353
|
+
example9.com:
|
|
354
|
+
- TXT: v=SpF1 ~all
|
|
355
|
+
---
|
|
356
|
+
description: Record evaluation
|
|
357
|
+
tests:
|
|
358
|
+
detect-errors-anywhere:
|
|
359
|
+
description: Any syntax errors anywhere in the record MUST be detected.
|
|
360
|
+
spec: 4.6
|
|
361
|
+
helo: mail.example.com
|
|
362
|
+
host: 1.2.3.4
|
|
363
|
+
mailfrom: foo@t1.example.com
|
|
364
|
+
result: permerror
|
|
365
|
+
modifier-charset-good:
|
|
366
|
+
description: name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
|
|
367
|
+
spec: 4.6.1/2
|
|
368
|
+
helo: mail.example.com
|
|
369
|
+
host: 1.2.3.4
|
|
370
|
+
mailfrom: foo@t2.example.com
|
|
371
|
+
result: pass
|
|
372
|
+
modifier-charset-bad1:
|
|
373
|
+
description: >-
|
|
374
|
+
'=' character immediately after the name and before any ":" or "/"
|
|
375
|
+
spec: 4.6.1/4
|
|
376
|
+
helo: mail.example.com
|
|
377
|
+
host: 1.2.3.4
|
|
378
|
+
mailfrom: foo@t3.example.com
|
|
379
|
+
result: permerror
|
|
380
|
+
modifier-charset-bad2:
|
|
381
|
+
description: >-
|
|
382
|
+
'=' character immediately after the name and before any ":" or "/"
|
|
383
|
+
spec: 4.6.1/4
|
|
384
|
+
helo: mail.example.com
|
|
385
|
+
host: 1.2.3.4
|
|
386
|
+
mailfrom: foo@t4.example.com
|
|
387
|
+
result: permerror
|
|
388
|
+
redirect-after-mechanisms1:
|
|
389
|
+
description: >-
|
|
390
|
+
The "redirect" modifier has an effect after all the mechanisms.
|
|
391
|
+
comment: >-
|
|
392
|
+
The redirect in this example would violate processing limits, except
|
|
393
|
+
that it is never used because of the all mechanism.
|
|
394
|
+
spec: 4.6.3
|
|
395
|
+
helo: mail.example.com
|
|
396
|
+
host: 1.2.3.4
|
|
397
|
+
mailfrom: foo@t5.example.com
|
|
398
|
+
result: softfail
|
|
399
|
+
redirect-after-mechanisms2:
|
|
400
|
+
description: >-
|
|
401
|
+
The "redirect" modifier has an effect after all the mechanisms.
|
|
402
|
+
spec: 4.6.3
|
|
403
|
+
helo: mail.example.com
|
|
404
|
+
host: 1.2.3.5
|
|
405
|
+
mailfrom: foo@t6.example.com
|
|
406
|
+
result: fail
|
|
407
|
+
default-result:
|
|
408
|
+
description: Default result is neutral.
|
|
409
|
+
spec: 4.7/1
|
|
410
|
+
helo: mail.example.com
|
|
411
|
+
host: 1.2.3.5
|
|
412
|
+
mailfrom: foo@t7.example.com
|
|
413
|
+
result: neutral
|
|
414
|
+
redirect-is-modifier:
|
|
415
|
+
description: |-
|
|
416
|
+
Invalid mechanism. Redirect is a modifier.
|
|
417
|
+
spec: 4.6.1/4
|
|
418
|
+
helo: mail.example.com
|
|
419
|
+
host: 1.2.3.4
|
|
420
|
+
mailfrom: foo@t8.example.com
|
|
421
|
+
result: permerror
|
|
422
|
+
invalid-domain:
|
|
423
|
+
description: >-
|
|
424
|
+
Domain-spec must end in macro-expand or valid toplabel.
|
|
425
|
+
spec: 7.1/2
|
|
426
|
+
helo: mail.example.com
|
|
427
|
+
host: 1.2.3.4
|
|
428
|
+
mailfrom: foo@t9.example.com
|
|
429
|
+
result: permerror
|
|
430
|
+
invalid-domain-empty-label:
|
|
431
|
+
description: >-
|
|
432
|
+
target-name that is a valid domain-spec per RFC 4408 and RFC 7208 but an
|
|
433
|
+
invalid domain name per RFC 1035 (empty label) should be treated as
|
|
434
|
+
non-existent.
|
|
435
|
+
comment: >-
|
|
436
|
+
An empty domain label, i.e. two successive dots, in a mechanism
|
|
437
|
+
target-name is valid domain-spec syntax (perhaps formed from a macro
|
|
438
|
+
expansion), even though a DNS query cannot be composed from it. The spec
|
|
439
|
+
being unclear about it, this could either be considered a syntax error,
|
|
440
|
+
or, by analogy to 4.3/1 and 5/10/3, the mechanism could be treated as a
|
|
441
|
+
no-match. RFC 7208 failed to agree on which result to use, and declares
|
|
442
|
+
the situation undefined. The preferred test result is therefore a matter
|
|
443
|
+
of opinion.
|
|
444
|
+
spec: 4.3/1, 4.8/5, 5/10/3
|
|
445
|
+
helo: mail.example.com
|
|
446
|
+
host: 1.2.3.4
|
|
447
|
+
mailfrom: foo@t10.example.com
|
|
448
|
+
result: [fail, permerror]
|
|
449
|
+
invalid-domain-long:
|
|
450
|
+
description: >-
|
|
451
|
+
target-name that is a valid domain-spec per RFC 4408 and RFC 7208 but an
|
|
452
|
+
invalid domain name per RFC 1035 (long label) must be treated as
|
|
453
|
+
non-existent.
|
|
454
|
+
comment: >-
|
|
455
|
+
A domain label longer than 63 characters in a mechanism target-name is
|
|
456
|
+
valid domain-spec syntax (perhaps formed from a macro expansion), even
|
|
457
|
+
though a DNS query cannot be composed from it. The spec being unclear
|
|
458
|
+
about it, this could either be considered a syntax error, or, by analogy
|
|
459
|
+
to 4.3/1 and 5/10/3, the mechanism could be treated as a no-match. RFC
|
|
460
|
+
7208 failed to agree on which result to use, and declares the situation
|
|
461
|
+
undefined. The preferred test result is therefore a matter of opinion.
|
|
462
|
+
spec: 4.3/1, 4.8/5, 5/10/3
|
|
463
|
+
helo: mail.example.com
|
|
464
|
+
host: 1.2.3.4
|
|
465
|
+
mailfrom: foo@t11.example.com
|
|
466
|
+
result: [fail,permerror]
|
|
467
|
+
invalid-domain-long-via-macro:
|
|
468
|
+
description: >-
|
|
469
|
+
target-name that is a valid domain-spec per RFC 4408 and RFC 7208 but an
|
|
470
|
+
invalid domain name per RFC 1035 (long label) must be treated as
|
|
471
|
+
non-existent.
|
|
472
|
+
comment: >-
|
|
473
|
+
A domain label longer than 63 characters that results from macro
|
|
474
|
+
expansion in a mechanism target-name is valid domain-spec syntax (and is
|
|
475
|
+
not even subject to syntax checking after macro expansion), even though
|
|
476
|
+
a DNS query cannot be composed from it. The spec being unclear about
|
|
477
|
+
it, this could either be considered a syntax error, or, by analogy to
|
|
478
|
+
4.3/1 and 5/10/3, the mechanism could be treated as a no-match. RFC 7208
|
|
479
|
+
failed to agree on which result to use, and declares the situation
|
|
480
|
+
undefined. The preferred test result is therefore a matter of opinion.
|
|
481
|
+
spec: 4.3/1, 4.8/5, 5/10/3
|
|
482
|
+
helo: "%%%%%%%%%%%%%%%%%%%%%%"
|
|
483
|
+
host: 1.2.3.4
|
|
484
|
+
mailfrom: foo@t12.example.com
|
|
485
|
+
result: [fail,permerror]
|
|
486
|
+
zonedata:
|
|
487
|
+
mail.example.com:
|
|
488
|
+
- A: 1.2.3.4
|
|
489
|
+
t1.example.com:
|
|
490
|
+
- TXT: v=spf1 ip4:1.2.3.4 -all moo
|
|
491
|
+
t2.example.com:
|
|
492
|
+
- TXT: v=spf1 moo.cow-far_out=man:dog/cat ip4:1.2.3.4 -all
|
|
493
|
+
t3.example.com:
|
|
494
|
+
- TXT: v=spf1 moo.cow/far_out=man:dog/cat ip4:1.2.3.4 -all
|
|
495
|
+
t4.example.com:
|
|
496
|
+
- TXT: v=spf1 moo.cow:far_out=man:dog/cat ip4:1.2.3.4 -all
|
|
497
|
+
t5.example.com:
|
|
498
|
+
- TXT: v=spf1 redirect=t5.example.com ~all
|
|
499
|
+
t6.example.com:
|
|
500
|
+
- TXT: v=spf1 ip4:1.2.3.4 redirect=t2.example.com
|
|
501
|
+
t7.example.com:
|
|
502
|
+
- TXT: v=spf1 ip4:1.2.3.4
|
|
503
|
+
t8.example.com:
|
|
504
|
+
- TXT: v=spf1 ip4:1.2.3.4 redirect:t2.example.com
|
|
505
|
+
t9.example.com:
|
|
506
|
+
- TXT: v=spf1 a:foo-bar -all
|
|
507
|
+
t10.example.com:
|
|
508
|
+
- TXT: v=spf1 a:mail.example...com -all
|
|
509
|
+
t11.example.com:
|
|
510
|
+
- TXT: v=spf1 a:a123456789012345678901234567890123456789012345678901234567890123.example.com -all
|
|
511
|
+
t12.example.com:
|
|
512
|
+
- TXT: v=spf1 a:%{H}.bar -all
|
|
513
|
+
---
|
|
514
|
+
description: ALL mechanism syntax
|
|
515
|
+
tests:
|
|
516
|
+
all-dot:
|
|
517
|
+
description: |
|
|
518
|
+
all = "all"
|
|
519
|
+
comment: |-
|
|
520
|
+
At least one implementation got this wrong
|
|
521
|
+
spec: 5.1/1
|
|
522
|
+
helo: mail.example.com
|
|
523
|
+
host: 1.2.3.4
|
|
524
|
+
mailfrom: foo@e1.example.com
|
|
525
|
+
result: permerror
|
|
526
|
+
all-arg:
|
|
527
|
+
description: |
|
|
528
|
+
all = "all"
|
|
529
|
+
comment: |-
|
|
530
|
+
At least one implementation got this wrong
|
|
531
|
+
spec: 5.1/1
|
|
532
|
+
helo: mail.example.com
|
|
533
|
+
host: 1.2.3.4
|
|
534
|
+
mailfrom: foo@e2.example.com
|
|
535
|
+
result: permerror
|
|
536
|
+
all-cidr:
|
|
537
|
+
description: |
|
|
538
|
+
all = "all"
|
|
539
|
+
spec: 5.1/1
|
|
540
|
+
helo: mail.example.com
|
|
541
|
+
host: 1.2.3.4
|
|
542
|
+
mailfrom: foo@e3.example.com
|
|
543
|
+
result: permerror
|
|
544
|
+
all-neutral:
|
|
545
|
+
description: |
|
|
546
|
+
all = "all"
|
|
547
|
+
spec: 5.1/1
|
|
548
|
+
helo: mail.example.com
|
|
549
|
+
host: 1.2.3.4
|
|
550
|
+
mailfrom: foo@e4.example.com
|
|
551
|
+
result: neutral
|
|
552
|
+
all-double:
|
|
553
|
+
description: |
|
|
554
|
+
all = "all"
|
|
555
|
+
spec: 5.1/1
|
|
556
|
+
helo: mail.example.com
|
|
557
|
+
host: 1.2.3.4
|
|
558
|
+
mailfrom: foo@e5.example.com
|
|
559
|
+
result: pass
|
|
560
|
+
zonedata:
|
|
561
|
+
mail.example.com:
|
|
562
|
+
- A: 1.2.3.4
|
|
563
|
+
e1.example.com:
|
|
564
|
+
- TXT: v=spf1 -all.
|
|
565
|
+
e2.example.com:
|
|
566
|
+
- TXT: v=spf1 -all:foobar
|
|
567
|
+
e3.example.com:
|
|
568
|
+
- TXT: v=spf1 -all/8
|
|
569
|
+
e4.example.com:
|
|
570
|
+
- TXT: v=spf1 ?all
|
|
571
|
+
e5.example.com:
|
|
572
|
+
- TXT: v=spf1 all -all
|
|
573
|
+
---
|
|
574
|
+
description: PTR mechanism syntax
|
|
575
|
+
tests:
|
|
576
|
+
ptr-cidr:
|
|
577
|
+
description: |-
|
|
578
|
+
PTR = "ptr" [ ":" domain-spec ]
|
|
579
|
+
spec: 5.5/2
|
|
580
|
+
helo: mail.example.com
|
|
581
|
+
host: 1.2.3.4
|
|
582
|
+
mailfrom: foo@e1.example.com
|
|
583
|
+
result: permerror
|
|
584
|
+
ptr-match-target:
|
|
585
|
+
description: >-
|
|
586
|
+
Check all validated domain names to see if they end in the <target-name>
|
|
587
|
+
domain.
|
|
588
|
+
spec: 5.5/5
|
|
589
|
+
helo: mail.example.com
|
|
590
|
+
host: 1.2.3.4
|
|
591
|
+
mailfrom: foo@e2.example.com
|
|
592
|
+
result: pass
|
|
593
|
+
ptr-match-implicit:
|
|
594
|
+
description: >-
|
|
595
|
+
Check all validated domain names to see if they end in the <target-name>
|
|
596
|
+
domain.
|
|
597
|
+
spec: 5.5/5
|
|
598
|
+
helo: mail.example.com
|
|
599
|
+
host: 1.2.3.4
|
|
600
|
+
mailfrom: foo@e3.example.com
|
|
601
|
+
result: pass
|
|
602
|
+
ptr-nomatch-invalid:
|
|
603
|
+
description: >-
|
|
604
|
+
Check all validated domain names to see if they end in the <target-name>
|
|
605
|
+
domain.
|
|
606
|
+
comment: >-
|
|
607
|
+
This PTR record does not validate
|
|
608
|
+
spec: 5.5/5
|
|
609
|
+
helo: mail.example.com
|
|
610
|
+
host: 1.2.3.4
|
|
611
|
+
mailfrom: foo@e4.example.com
|
|
612
|
+
result: fail
|
|
613
|
+
ptr-match-ip6:
|
|
614
|
+
description: >-
|
|
615
|
+
Check all validated domain names to see if they end in the <target-name>
|
|
616
|
+
domain.
|
|
617
|
+
spec: 5.5/5
|
|
618
|
+
helo: mail.example.com
|
|
619
|
+
host: "CAFE:BABE::1"
|
|
620
|
+
mailfrom: foo@e3.example.com
|
|
621
|
+
result: pass
|
|
622
|
+
ptr-empty-domain:
|
|
623
|
+
description: >-
|
|
624
|
+
domain-spec cannot be empty.
|
|
625
|
+
spec: 5.5/2
|
|
626
|
+
helo: mail.example.com
|
|
627
|
+
host: 1.2.3.4
|
|
628
|
+
mailfrom: foo@e5.example.com
|
|
629
|
+
result: permerror
|
|
630
|
+
zonedata:
|
|
631
|
+
mail.example.com:
|
|
632
|
+
- A: 1.2.3.4
|
|
633
|
+
e1.example.com:
|
|
634
|
+
- TXT: v=spf1 ptr/0 -all
|
|
635
|
+
e2.example.com:
|
|
636
|
+
- TXT: v=spf1 ptr:example.com -all
|
|
637
|
+
4.3.2.1.in-addr.arpa:
|
|
638
|
+
- PTR: e3.example.com
|
|
639
|
+
- PTR: e4.example.com
|
|
640
|
+
- PTR: mail.example.com
|
|
641
|
+
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.E.B.A.B.E.F.A.C.ip6.arpa:
|
|
642
|
+
- PTR: e3.example.com
|
|
643
|
+
e3.example.com:
|
|
644
|
+
- TXT: v=spf1 ptr -all
|
|
645
|
+
- A: 1.2.3.4
|
|
646
|
+
- AAAA: "CAFE:BABE::1"
|
|
647
|
+
e4.example.com:
|
|
648
|
+
- TXT: v=spf1 ptr -all
|
|
649
|
+
e5.example.com:
|
|
650
|
+
- TXT: "v=spf1 ptr:"
|
|
651
|
+
---
|
|
652
|
+
description: A mechanism syntax
|
|
653
|
+
tests:
|
|
654
|
+
a-cidr6:
|
|
655
|
+
description: |
|
|
656
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
657
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
658
|
+
spec: 5.3/2
|
|
659
|
+
helo: mail.example.com
|
|
660
|
+
host: 1.2.3.4
|
|
661
|
+
mailfrom: foo@e6.example.com
|
|
662
|
+
result: fail
|
|
663
|
+
a-bad-cidr4:
|
|
664
|
+
description: |
|
|
665
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
666
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
667
|
+
spec: 5.3/2
|
|
668
|
+
helo: mail.example.com
|
|
669
|
+
host: 1.2.3.4
|
|
670
|
+
mailfrom: foo@e6a.example.com
|
|
671
|
+
result: permerror
|
|
672
|
+
a-bad-cidr6:
|
|
673
|
+
description: |
|
|
674
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
675
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
676
|
+
spec: 5.3/2
|
|
677
|
+
helo: mail.example.com
|
|
678
|
+
host: 1.2.3.4
|
|
679
|
+
mailfrom: foo@e7.example.com
|
|
680
|
+
result: permerror
|
|
681
|
+
a-dual-cidr-ip4-match:
|
|
682
|
+
description: |
|
|
683
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
684
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
685
|
+
spec: 5.3/2
|
|
686
|
+
helo: mail.example.com
|
|
687
|
+
host: 1.2.3.4
|
|
688
|
+
mailfrom: foo@e8.example.com
|
|
689
|
+
result: pass
|
|
690
|
+
a-dual-cidr-ip4-err:
|
|
691
|
+
description: |
|
|
692
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
693
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
694
|
+
spec: 5.3/2
|
|
695
|
+
helo: mail.example.com
|
|
696
|
+
host: 1.2.3.4
|
|
697
|
+
mailfrom: foo@e8e.example.com
|
|
698
|
+
result: permerror
|
|
699
|
+
a-dual-cidr-ip6-match:
|
|
700
|
+
description: |
|
|
701
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
702
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
703
|
+
spec: 5.3/2
|
|
704
|
+
helo: mail.example.com
|
|
705
|
+
host: "2001:db8:1234::cafe:babe"
|
|
706
|
+
mailfrom: foo@e8.example.com
|
|
707
|
+
result: pass
|
|
708
|
+
a-dual-cidr-ip4-default:
|
|
709
|
+
description: |
|
|
710
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
711
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
712
|
+
spec: 5.3/2
|
|
713
|
+
helo: mail.example.com
|
|
714
|
+
host: 1.2.3.4
|
|
715
|
+
mailfrom: foo@e8b.example.com
|
|
716
|
+
result: fail
|
|
717
|
+
a-dual-cidr-ip6-default:
|
|
718
|
+
description: |
|
|
719
|
+
A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
720
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
721
|
+
spec: 5.3/2
|
|
722
|
+
helo: mail.example.com
|
|
723
|
+
host: "2001:db8:1234::cafe:babe"
|
|
724
|
+
mailfrom: foo@e8a.example.com
|
|
725
|
+
result: fail
|
|
726
|
+
a-multi-ip1:
|
|
727
|
+
description: >-
|
|
728
|
+
A matches any returned IP.
|
|
729
|
+
spec: 5.3/3
|
|
730
|
+
helo: mail.example.com
|
|
731
|
+
host: 1.2.3.4
|
|
732
|
+
mailfrom: foo@e10.example.com
|
|
733
|
+
result: pass
|
|
734
|
+
a-multi-ip2:
|
|
735
|
+
description: >-
|
|
736
|
+
A matches any returned IP.
|
|
737
|
+
spec: 5.3/3
|
|
738
|
+
helo: mail.example.com
|
|
739
|
+
host: 1.2.3.4
|
|
740
|
+
mailfrom: foo@e10.example.com
|
|
741
|
+
result: pass
|
|
742
|
+
a-bad-domain:
|
|
743
|
+
description: >-
|
|
744
|
+
domain-spec must pass basic syntax checks;
|
|
745
|
+
a ':' may appear in domain-spec, but not in top-label
|
|
746
|
+
spec: 7.1/2
|
|
747
|
+
helo: mail.example.com
|
|
748
|
+
host: 1.2.3.4
|
|
749
|
+
mailfrom: foo@e9.example.com
|
|
750
|
+
result: permerror
|
|
751
|
+
a-nxdomain:
|
|
752
|
+
description: >-
|
|
753
|
+
If no ips are returned, A mechanism does not match, even with /0.
|
|
754
|
+
spec: 5.3/3
|
|
755
|
+
helo: mail.example.com
|
|
756
|
+
host: 1.2.3.4
|
|
757
|
+
mailfrom: foo@e1.example.com
|
|
758
|
+
result: fail
|
|
759
|
+
a-cidr4-0:
|
|
760
|
+
description: >-
|
|
761
|
+
Matches if any A records are present in DNS.
|
|
762
|
+
spec: 5.3/3
|
|
763
|
+
helo: mail.example.com
|
|
764
|
+
host: 1.2.3.4
|
|
765
|
+
mailfrom: foo@e2.example.com
|
|
766
|
+
result: pass
|
|
767
|
+
a-cidr4-0-ip6:
|
|
768
|
+
description: >-
|
|
769
|
+
Matches if any A records are present in DNS.
|
|
770
|
+
spec: 5.3/3
|
|
771
|
+
helo: mail.example.com
|
|
772
|
+
host: "1234::1"
|
|
773
|
+
mailfrom: foo@e2.example.com
|
|
774
|
+
result: fail
|
|
775
|
+
a-cidr6-0-ip4:
|
|
776
|
+
description: >-
|
|
777
|
+
Would match if any AAAA records are present in DNS,
|
|
778
|
+
but not for an IP4 connection.
|
|
779
|
+
spec: 5.3/3
|
|
780
|
+
helo: mail.example.com
|
|
781
|
+
host: 1.2.3.4
|
|
782
|
+
mailfrom: foo@e2a.example.com
|
|
783
|
+
result: fail
|
|
784
|
+
a-cidr6-0-ip4mapped:
|
|
785
|
+
description: >-
|
|
786
|
+
Would match if any AAAA records are present in DNS,
|
|
787
|
+
but not for an IP4 connection.
|
|
788
|
+
spec: 5.3/3
|
|
789
|
+
helo: mail.example.com
|
|
790
|
+
host: "::FFFF:1.2.3.4"
|
|
791
|
+
mailfrom: foo@e2a.example.com
|
|
792
|
+
result: fail
|
|
793
|
+
a-cidr6-0-ip6:
|
|
794
|
+
description: >-
|
|
795
|
+
Matches if any AAAA records are present in DNS.
|
|
796
|
+
spec: 5.3/3
|
|
797
|
+
helo: mail.example.com
|
|
798
|
+
host: "1234::1"
|
|
799
|
+
mailfrom: foo@e2a.example.com
|
|
800
|
+
result: pass
|
|
801
|
+
a-ip6-dualstack:
|
|
802
|
+
description: >-
|
|
803
|
+
Simple IP6 Address match with dual stack.
|
|
804
|
+
spec: 5.3/3
|
|
805
|
+
helo: mail.example.com
|
|
806
|
+
host: "1234::1"
|
|
807
|
+
mailfrom: foo@ipv6.example.com
|
|
808
|
+
result: pass
|
|
809
|
+
a-cidr6-0-nxdomain:
|
|
810
|
+
description: >-
|
|
811
|
+
No match if no AAAA records are present in DNS.
|
|
812
|
+
spec: 5.3/3
|
|
813
|
+
helo: mail.example.com
|
|
814
|
+
host: "1234::1"
|
|
815
|
+
mailfrom: foo@e2b.example.com
|
|
816
|
+
result: fail
|
|
817
|
+
a-null:
|
|
818
|
+
description: >-
|
|
819
|
+
Null octets not allowed in toplabel
|
|
820
|
+
spec: 7.1/2
|
|
821
|
+
helo: mail.example.com
|
|
822
|
+
host: 1.2.3.5
|
|
823
|
+
mailfrom: foo@e3.example.com
|
|
824
|
+
result: permerror
|
|
825
|
+
a-numeric:
|
|
826
|
+
description: >-
|
|
827
|
+
toplabel may not be all numeric
|
|
828
|
+
comment: >-
|
|
829
|
+
A common publishing mistake is using ip4 addresses with A mechanism.
|
|
830
|
+
This should receive special diagnostic attention in the permerror.
|
|
831
|
+
spec: 7.1/2
|
|
832
|
+
helo: mail.example.com
|
|
833
|
+
host: 1.2.3.4
|
|
834
|
+
mailfrom: foo@e4.example.com
|
|
835
|
+
result: permerror
|
|
836
|
+
a-numeric-toplabel:
|
|
837
|
+
description: >-
|
|
838
|
+
toplabel may not be all numeric
|
|
839
|
+
spec: 7.1/2
|
|
840
|
+
helo: mail.example.com
|
|
841
|
+
host: 1.2.3.4
|
|
842
|
+
mailfrom: foo@e5.example.com
|
|
843
|
+
result: permerror
|
|
844
|
+
a-dash-in-toplabel:
|
|
845
|
+
description: >-
|
|
846
|
+
toplabel may contain dashes
|
|
847
|
+
comment: >-
|
|
848
|
+
Going from the "toplabel" grammar definition, an implementation using
|
|
849
|
+
regular expressions in incrementally parsing SPF records might
|
|
850
|
+
erroneously try to match a TLD such as ".xn--zckzah" (cf. IDN TLDs!) to
|
|
851
|
+
'( *alphanum ALPHA *alphanum )' first before trying the alternative
|
|
852
|
+
'( 1*alphanum "-" *( alphanum / "-" ) alphanum )', essentially causing
|
|
853
|
+
a non-greedy, and thus, incomplete match. Make sure a greedy match is
|
|
854
|
+
performed!
|
|
855
|
+
spec: 7.1/2
|
|
856
|
+
helo: mail.example.com
|
|
857
|
+
host: 1.2.3.4
|
|
858
|
+
mailfrom: foo@e14.example.com
|
|
859
|
+
result: pass
|
|
860
|
+
a-bad-toplabel:
|
|
861
|
+
description: >-
|
|
862
|
+
toplabel may not begin with a dash
|
|
863
|
+
spec: 7.1/2
|
|
864
|
+
helo: mail.example.com
|
|
865
|
+
host: 1.2.3.4
|
|
866
|
+
mailfrom: foo@e12.example.com
|
|
867
|
+
result: permerror
|
|
868
|
+
a-only-toplabel:
|
|
869
|
+
description: >-
|
|
870
|
+
domain-spec may not consist of only a toplabel.
|
|
871
|
+
spec: 7.1/2
|
|
872
|
+
helo: mail.example.com
|
|
873
|
+
host: 1.2.3.4
|
|
874
|
+
mailfrom: foo@e5a.example.com
|
|
875
|
+
result: permerror
|
|
876
|
+
a-only-toplabel-trailing-dot:
|
|
877
|
+
description: >-
|
|
878
|
+
domain-spec may not consist of only a toplabel.
|
|
879
|
+
comment: >-
|
|
880
|
+
"A trailing dot doesn't help."
|
|
881
|
+
spec: 7.1/2
|
|
882
|
+
helo: mail.example.com
|
|
883
|
+
host: 1.2.3.4
|
|
884
|
+
mailfrom: foo@e5b.example.com
|
|
885
|
+
result: permerror
|
|
886
|
+
a-colon-domain:
|
|
887
|
+
description: >-
|
|
888
|
+
domain-spec may contain any visible char except %
|
|
889
|
+
spec: 7.1/2
|
|
890
|
+
helo: mail.example.com
|
|
891
|
+
host: 1.2.3.4
|
|
892
|
+
mailfrom: foo@e11.example.com
|
|
893
|
+
result: pass
|
|
894
|
+
a-colon-domain-ip4mapped:
|
|
895
|
+
description: >-
|
|
896
|
+
domain-spec may contain any visible char except %
|
|
897
|
+
spec: 7.1/2
|
|
898
|
+
helo: mail.example.com
|
|
899
|
+
host: "::FFFF:1.2.3.4"
|
|
900
|
+
mailfrom: foo@e11.example.com
|
|
901
|
+
result: pass
|
|
902
|
+
a-empty-domain:
|
|
903
|
+
description: >-
|
|
904
|
+
domain-spec cannot be empty.
|
|
905
|
+
spec: 5.3/2
|
|
906
|
+
helo: mail.example.com
|
|
907
|
+
host: 1.2.3.4
|
|
908
|
+
mailfrom: foo@e13.example.com
|
|
909
|
+
result: permerror
|
|
910
|
+
zonedata:
|
|
911
|
+
mail.example.com:
|
|
912
|
+
- A: 1.2.3.4
|
|
913
|
+
e1.example.com:
|
|
914
|
+
- TXT: v=spf1 a/0 -all
|
|
915
|
+
e2.example.com:
|
|
916
|
+
- A: 1.1.1.1
|
|
917
|
+
- AAAA: "1234::2"
|
|
918
|
+
- TXT: v=spf1 a/0 -all
|
|
919
|
+
e2a.example.com:
|
|
920
|
+
- AAAA: "1234::1"
|
|
921
|
+
- TXT: v=spf1 a//0 -all
|
|
922
|
+
e2b.example.com:
|
|
923
|
+
- A: 1.1.1.1
|
|
924
|
+
- TXT: v=spf1 a//0 -all
|
|
925
|
+
ipv6.example.com:
|
|
926
|
+
- AAAA: "1234::1"
|
|
927
|
+
- A: 1.1.1.1
|
|
928
|
+
- TXT: v=spf1 a -all
|
|
929
|
+
e3.example.com:
|
|
930
|
+
- TXT: "v=spf1 a:foo.example.com\0"
|
|
931
|
+
e4.example.com:
|
|
932
|
+
- TXT: v=spf1 a:111.222.33.44
|
|
933
|
+
e5.example.com:
|
|
934
|
+
- TXT: v=spf1 a:abc.123
|
|
935
|
+
e5a.example.com:
|
|
936
|
+
- TXT: v=spf1 a:museum
|
|
937
|
+
e5b.example.com:
|
|
938
|
+
- TXT: v=spf1 a:museum.
|
|
939
|
+
e6.example.com:
|
|
940
|
+
- TXT: v=spf1 a//33 -all
|
|
941
|
+
e6a.example.com:
|
|
942
|
+
- TXT: v=spf1 a/33 -all
|
|
943
|
+
e7.example.com:
|
|
944
|
+
- TXT: v=spf1 a//129 -all
|
|
945
|
+
e8.example.com:
|
|
946
|
+
- A: 1.2.3.5
|
|
947
|
+
- AAAA: "2001:db8:1234::dead:beef"
|
|
948
|
+
- TXT: v=spf1 a/24//64 -all
|
|
949
|
+
e8e.example.com:
|
|
950
|
+
- A: 1.2.3.5
|
|
951
|
+
- AAAA: "2001:db8:1234::dead:beef"
|
|
952
|
+
- TXT: v=spf1 a/24/64 -all
|
|
953
|
+
e8a.example.com:
|
|
954
|
+
- A: 1.2.3.5
|
|
955
|
+
- AAAA: "2001:db8:1234::dead:beef"
|
|
956
|
+
- TXT: v=spf1 a/24 -all
|
|
957
|
+
e8b.example.com:
|
|
958
|
+
- A: 1.2.3.5
|
|
959
|
+
- AAAA: "2001:db8:1234::dead:beef"
|
|
960
|
+
- TXT: v=spf1 a//64 -all
|
|
961
|
+
e9.example.com:
|
|
962
|
+
- TXT: v=spf1 a:example.com:8080
|
|
963
|
+
e10.example.com:
|
|
964
|
+
- TXT: v=spf1 a:foo.example.com/24
|
|
965
|
+
foo.example.com:
|
|
966
|
+
- A: 1.1.1.1
|
|
967
|
+
- A: 1.2.3.5
|
|
968
|
+
e11.example.com:
|
|
969
|
+
- TXT: v=spf1 a:foo:bar/baz.example.com
|
|
970
|
+
foo:bar/baz.example.com:
|
|
971
|
+
- A: 1.2.3.4
|
|
972
|
+
e12.example.com:
|
|
973
|
+
- TXT: v=spf1 a:example.-com
|
|
974
|
+
e13.example.com:
|
|
975
|
+
- TXT: "v=spf1 a:"
|
|
976
|
+
e14.example.com:
|
|
977
|
+
- TXT: "v=spf1 a:foo.example.xn--zckzah -all"
|
|
978
|
+
foo.example.xn--zckzah:
|
|
979
|
+
- A: 1.2.3.4
|
|
980
|
+
---
|
|
981
|
+
description: Include mechanism semantics and syntax
|
|
982
|
+
tests:
|
|
983
|
+
include-fail:
|
|
984
|
+
description: >-
|
|
985
|
+
recursive check_host() result of fail causes include to not match.
|
|
986
|
+
spec: 5.2/9
|
|
987
|
+
helo: mail.example.com
|
|
988
|
+
host: 1.2.3.4
|
|
989
|
+
mailfrom: foo@e1.example.com
|
|
990
|
+
result: softfail
|
|
991
|
+
include-softfail:
|
|
992
|
+
description: >-
|
|
993
|
+
recursive check_host() result of softfail causes include to not match.
|
|
994
|
+
spec: 5.2/9
|
|
995
|
+
helo: mail.example.com
|
|
996
|
+
host: 1.2.3.4
|
|
997
|
+
mailfrom: foo@e2.example.com
|
|
998
|
+
result: pass
|
|
999
|
+
include-neutral:
|
|
1000
|
+
description: >-
|
|
1001
|
+
recursive check_host() result of neutral causes include to not match.
|
|
1002
|
+
spec: 5.2/9
|
|
1003
|
+
helo: mail.example.com
|
|
1004
|
+
host: 1.2.3.4
|
|
1005
|
+
mailfrom: foo@e3.example.com
|
|
1006
|
+
result: fail
|
|
1007
|
+
include-temperror:
|
|
1008
|
+
description: >-
|
|
1009
|
+
recursive check_host() result of temperror causes include to temperror
|
|
1010
|
+
spec: 5.2/9
|
|
1011
|
+
helo: mail.example.com
|
|
1012
|
+
host: 1.2.3.4
|
|
1013
|
+
mailfrom: foo@e4.example.com
|
|
1014
|
+
result: temperror
|
|
1015
|
+
include-permerror:
|
|
1016
|
+
description: >-
|
|
1017
|
+
recursive check_host() result of permerror causes include to permerror
|
|
1018
|
+
spec: 5.2/9
|
|
1019
|
+
helo: mail.example.com
|
|
1020
|
+
host: 1.2.3.4
|
|
1021
|
+
mailfrom: foo@e5.example.com
|
|
1022
|
+
result: permerror
|
|
1023
|
+
include-syntax-error:
|
|
1024
|
+
description: >-
|
|
1025
|
+
include = "include" ":" domain-spec
|
|
1026
|
+
spec: 5.2/1
|
|
1027
|
+
helo: mail.example.com
|
|
1028
|
+
host: 1.2.3.4
|
|
1029
|
+
mailfrom: foo@e6.example.com
|
|
1030
|
+
result: permerror
|
|
1031
|
+
include-cidr:
|
|
1032
|
+
description: >-
|
|
1033
|
+
include = "include" ":" domain-spec
|
|
1034
|
+
spec: 5.2/1
|
|
1035
|
+
helo: mail.example.com
|
|
1036
|
+
host: 1.2.3.4
|
|
1037
|
+
mailfrom: foo@e9.example.com
|
|
1038
|
+
result: permerror
|
|
1039
|
+
include-none:
|
|
1040
|
+
description: >-
|
|
1041
|
+
recursive check_host() result of none causes include to permerror
|
|
1042
|
+
spec: 5.2/9
|
|
1043
|
+
helo: mail.example.com
|
|
1044
|
+
host: 1.2.3.4
|
|
1045
|
+
mailfrom: foo@e7.example.com
|
|
1046
|
+
result: permerror
|
|
1047
|
+
include-empty-domain:
|
|
1048
|
+
description: >-
|
|
1049
|
+
domain-spec cannot be empty.
|
|
1050
|
+
spec: 5.2/1
|
|
1051
|
+
helo: mail.example.com
|
|
1052
|
+
host: 1.2.3.4
|
|
1053
|
+
mailfrom: foo@e8.example.com
|
|
1054
|
+
result: permerror
|
|
1055
|
+
zonedata:
|
|
1056
|
+
mail.example.com:
|
|
1057
|
+
- A: 1.2.3.4
|
|
1058
|
+
ip5.example.com:
|
|
1059
|
+
- TXT: v=spf1 ip4:1.2.3.5 -all
|
|
1060
|
+
ip6.example.com:
|
|
1061
|
+
- TXT: v=spf1 ip4:1.2.3.6 ~all
|
|
1062
|
+
ip7.example.com:
|
|
1063
|
+
- TXT: v=spf1 ip4:1.2.3.7 ?all
|
|
1064
|
+
ip8.example.com:
|
|
1065
|
+
- TIMEOUT
|
|
1066
|
+
erehwon.example.com:
|
|
1067
|
+
- TXT: v=spfl am not an SPF record
|
|
1068
|
+
e1.example.com:
|
|
1069
|
+
- TXT: v=spf1 include:ip5.example.com ~all
|
|
1070
|
+
e2.example.com:
|
|
1071
|
+
- TXT: v=spf1 include:ip6.example.com all
|
|
1072
|
+
e3.example.com:
|
|
1073
|
+
- TXT: v=spf1 include:ip7.example.com -all
|
|
1074
|
+
e4.example.com:
|
|
1075
|
+
- TXT: v=spf1 include:ip8.example.com -all
|
|
1076
|
+
e5.example.com:
|
|
1077
|
+
- TXT: v=spf1 include:e6.example.com -all
|
|
1078
|
+
e6.example.com:
|
|
1079
|
+
- TXT: v=spf1 include +all
|
|
1080
|
+
e7.example.com:
|
|
1081
|
+
- TXT: v=spf1 include:erehwon.example.com -all
|
|
1082
|
+
e8.example.com:
|
|
1083
|
+
- TXT: "v=spf1 include: -all"
|
|
1084
|
+
e9.example.com:
|
|
1085
|
+
- TXT: "v=spf1 include:ip5.example.com/24 -all"
|
|
1086
|
+
---
|
|
1087
|
+
description: MX mechanism syntax
|
|
1088
|
+
tests:
|
|
1089
|
+
mx-cidr6:
|
|
1090
|
+
description: |
|
|
1091
|
+
MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
1092
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
1093
|
+
spec: 5.4/2
|
|
1094
|
+
helo: mail.example.com
|
|
1095
|
+
host: 1.2.3.4
|
|
1096
|
+
mailfrom: foo@e6.example.com
|
|
1097
|
+
result: fail
|
|
1098
|
+
mx-bad-cidr4:
|
|
1099
|
+
description: |
|
|
1100
|
+
MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
1101
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
1102
|
+
spec: 5.4/2
|
|
1103
|
+
helo: mail.example.com
|
|
1104
|
+
host: 1.2.3.4
|
|
1105
|
+
mailfrom: foo@e6a.example.com
|
|
1106
|
+
result: permerror
|
|
1107
|
+
mx-bad-cidr6:
|
|
1108
|
+
description: |
|
|
1109
|
+
MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ]
|
|
1110
|
+
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
|
|
1111
|
+
spec: 5.4/2
|
|
1112
|
+
helo: mail.example.com
|
|
1113
|
+
host: 1.2.3.4
|
|
1114
|
+
mailfrom: foo@e7.example.com
|
|
1115
|
+
result: permerror
|
|
1116
|
+
mx-multi-ip1:
|
|
1117
|
+
description: >-
|
|
1118
|
+
MX matches any returned IP.
|
|
1119
|
+
spec: 5.4/3
|
|
1120
|
+
helo: mail.example.com
|
|
1121
|
+
host: 1.2.3.4
|
|
1122
|
+
mailfrom: foo@e10.example.com
|
|
1123
|
+
result: pass
|
|
1124
|
+
mx-multi-ip2:
|
|
1125
|
+
description: >-
|
|
1126
|
+
MX matches any returned IP.
|
|
1127
|
+
spec: 5.4/3
|
|
1128
|
+
helo: mail.example.com
|
|
1129
|
+
host: 1.2.3.4
|
|
1130
|
+
mailfrom: foo@e10.example.com
|
|
1131
|
+
result: pass
|
|
1132
|
+
mx-bad-domain:
|
|
1133
|
+
description: >-
|
|
1134
|
+
domain-spec must pass basic syntax checks
|
|
1135
|
+
comment: >-
|
|
1136
|
+
A ':' may appear in domain-spec, but not in top-label.
|
|
1137
|
+
spec: 7.1/2
|
|
1138
|
+
helo: mail.example.com
|
|
1139
|
+
host: 1.2.3.4
|
|
1140
|
+
mailfrom: foo@e9.example.com
|
|
1141
|
+
result: permerror
|
|
1142
|
+
mx-nxdomain:
|
|
1143
|
+
description: >-
|
|
1144
|
+
If no ips are returned, MX mechanism does not match, even with /0.
|
|
1145
|
+
spec: 5.4/3
|
|
1146
|
+
helo: mail.example.com
|
|
1147
|
+
host: 1.2.3.4
|
|
1148
|
+
mailfrom: foo@e1.example.com
|
|
1149
|
+
result: fail
|
|
1150
|
+
mx-cidr4-0:
|
|
1151
|
+
description: >-
|
|
1152
|
+
Matches if any A records for any MX records are present in DNS.
|
|
1153
|
+
spec: 5.4/3
|
|
1154
|
+
helo: mail.example.com
|
|
1155
|
+
host: 1.2.3.4
|
|
1156
|
+
mailfrom: foo@e2.example.com
|
|
1157
|
+
result: pass
|
|
1158
|
+
mx-cidr4-0-ip6:
|
|
1159
|
+
description: >-
|
|
1160
|
+
cidr4 doesn't apply to IP6 connections.
|
|
1161
|
+
comment: >-
|
|
1162
|
+
The IP6 CIDR starts with a double slash.
|
|
1163
|
+
spec: 5.4/3
|
|
1164
|
+
helo: mail.example.com
|
|
1165
|
+
host: "1234::1"
|
|
1166
|
+
mailfrom: foo@e2.example.com
|
|
1167
|
+
result: fail
|
|
1168
|
+
mx-cidr6-0-ip4:
|
|
1169
|
+
description: >-
|
|
1170
|
+
Would match if any AAAA records for MX records are present in DNS,
|
|
1171
|
+
but not for an IP4 connection.
|
|
1172
|
+
spec: 5.4/3
|
|
1173
|
+
helo: mail.example.com
|
|
1174
|
+
host: 1.2.3.4
|
|
1175
|
+
mailfrom: foo@e2a.example.com
|
|
1176
|
+
result: fail
|
|
1177
|
+
mx-cidr6-0-ip4mapped:
|
|
1178
|
+
description: >-
|
|
1179
|
+
Would match if any AAAA records for MX records are present in DNS,
|
|
1180
|
+
but not for an IP4 connection.
|
|
1181
|
+
spec: 5.4/3
|
|
1182
|
+
helo: mail.example.com
|
|
1183
|
+
host: "::FFFF:1.2.3.4"
|
|
1184
|
+
mailfrom: foo@e2a.example.com
|
|
1185
|
+
result: fail
|
|
1186
|
+
mx-cidr6-0-ip6:
|
|
1187
|
+
description: >-
|
|
1188
|
+
Matches if any AAAA records for any MX records are present in DNS.
|
|
1189
|
+
spec: 5.3/3
|
|
1190
|
+
helo: mail.example.com
|
|
1191
|
+
host: "1234::1"
|
|
1192
|
+
mailfrom: foo@e2a.example.com
|
|
1193
|
+
result: pass
|
|
1194
|
+
mx-cidr6-0-nxdomain:
|
|
1195
|
+
description: >-
|
|
1196
|
+
No match if no AAAA records for any MX records are present in DNS.
|
|
1197
|
+
spec: 5.4/3
|
|
1198
|
+
helo: mail.example.com
|
|
1199
|
+
host: "1234::1"
|
|
1200
|
+
mailfrom: foo@e2b.example.com
|
|
1201
|
+
result: fail
|
|
1202
|
+
mx-null:
|
|
1203
|
+
description: >-
|
|
1204
|
+
Null not allowed in top-label.
|
|
1205
|
+
spec: 7.1/2
|
|
1206
|
+
helo: mail.example.com
|
|
1207
|
+
host: 1.2.3.5
|
|
1208
|
+
mailfrom: foo@e3.example.com
|
|
1209
|
+
result: permerror
|
|
1210
|
+
mx-numeric-top-label:
|
|
1211
|
+
description: >-
|
|
1212
|
+
Top-label may not be all numeric
|
|
1213
|
+
spec: 7.1/2
|
|
1214
|
+
helo: mail.example.com
|
|
1215
|
+
host: 1.2.3.4
|
|
1216
|
+
mailfrom: foo@e5.example.com
|
|
1217
|
+
result: permerror
|
|
1218
|
+
mx-colon-domain:
|
|
1219
|
+
description: >-
|
|
1220
|
+
Domain-spec may contain any visible char except %
|
|
1221
|
+
spec: 7.1/2
|
|
1222
|
+
helo: mail.example.com
|
|
1223
|
+
host: 1.2.3.4
|
|
1224
|
+
mailfrom: foo@e11.example.com
|
|
1225
|
+
result: pass
|
|
1226
|
+
mx-colon-domain-ip4mapped:
|
|
1227
|
+
description: >-
|
|
1228
|
+
Domain-spec may contain any visible char except %
|
|
1229
|
+
spec: 7.1/2
|
|
1230
|
+
helo: mail.example.com
|
|
1231
|
+
host: "::FFFF:1.2.3.4"
|
|
1232
|
+
mailfrom: foo@e11.example.com
|
|
1233
|
+
result: pass
|
|
1234
|
+
mx-bad-toplab:
|
|
1235
|
+
description: >-
|
|
1236
|
+
Toplabel may not begin with -
|
|
1237
|
+
spec: 7.1/2
|
|
1238
|
+
helo: mail.example.com
|
|
1239
|
+
host: 1.2.3.4
|
|
1240
|
+
mailfrom: foo@e12.example.com
|
|
1241
|
+
result: permerror
|
|
1242
|
+
mx-empty:
|
|
1243
|
+
description: >-
|
|
1244
|
+
test null MX
|
|
1245
|
+
comment: >-
|
|
1246
|
+
Some implementations have had trouble with null MX
|
|
1247
|
+
spec: 5.4/3
|
|
1248
|
+
helo: mail.example.com
|
|
1249
|
+
host: 1.2.3.4
|
|
1250
|
+
mailfrom: ""
|
|
1251
|
+
result: neutral
|
|
1252
|
+
mx-implicit:
|
|
1253
|
+
description: >-
|
|
1254
|
+
If the target name has no MX records, check_host() MUST NOT pretend the
|
|
1255
|
+
target is its single MX, and MUST NOT default to an A lookup on the
|
|
1256
|
+
target-name directly.
|
|
1257
|
+
spec: 5.4/4
|
|
1258
|
+
helo: mail.example.com
|
|
1259
|
+
host: 1.2.3.4
|
|
1260
|
+
mailfrom: foo@e4.example.com
|
|
1261
|
+
result: neutral
|
|
1262
|
+
mx-empty-domain:
|
|
1263
|
+
description: >-
|
|
1264
|
+
domain-spec cannot be empty.
|
|
1265
|
+
spec: 5.2/1
|
|
1266
|
+
helo: mail.example.com
|
|
1267
|
+
host: 1.2.3.4
|
|
1268
|
+
mailfrom: foo@e13.example.com
|
|
1269
|
+
result: permerror
|
|
1270
|
+
zonedata:
|
|
1271
|
+
mail.example.com:
|
|
1272
|
+
- A: 1.2.3.4
|
|
1273
|
+
- MX: [0, ""]
|
|
1274
|
+
- TXT: v=spf1 mx
|
|
1275
|
+
e1.example.com:
|
|
1276
|
+
- TXT: v=spf1 mx/0 -all
|
|
1277
|
+
- MX: [0, e1.example.com]
|
|
1278
|
+
e2.example.com:
|
|
1279
|
+
- A: 1.1.1.1
|
|
1280
|
+
- AAAA: "1234::2"
|
|
1281
|
+
- MX: [0, e2.example.com]
|
|
1282
|
+
- TXT: v=spf1 mx/0 -all
|
|
1283
|
+
e2a.example.com:
|
|
1284
|
+
- AAAA: "1234::1"
|
|
1285
|
+
- MX: [0, e2a.example.com]
|
|
1286
|
+
- TXT: v=spf1 mx//0 -all
|
|
1287
|
+
e2b.example.com:
|
|
1288
|
+
- A: 1.1.1.1
|
|
1289
|
+
- MX: [0, e2b.example.com]
|
|
1290
|
+
- TXT: v=spf1 mx//0 -all
|
|
1291
|
+
e3.example.com:
|
|
1292
|
+
- TXT: "v=spf1 mx:foo.example.com\0"
|
|
1293
|
+
e4.example.com:
|
|
1294
|
+
- TXT: v=spf1 mx
|
|
1295
|
+
- A: 1.2.3.4
|
|
1296
|
+
e5.example.com:
|
|
1297
|
+
- TXT: v=spf1 mx:abc.123
|
|
1298
|
+
e6.example.com:
|
|
1299
|
+
- TXT: v=spf1 mx//33 -all
|
|
1300
|
+
e6a.example.com:
|
|
1301
|
+
- TXT: v=spf1 mx/33 -all
|
|
1302
|
+
e7.example.com:
|
|
1303
|
+
- TXT: v=spf1 mx//129 -all
|
|
1304
|
+
e9.example.com:
|
|
1305
|
+
- TXT: v=spf1 mx:example.com:8080
|
|
1306
|
+
e10.example.com:
|
|
1307
|
+
- TXT: v=spf1 mx:foo.example.com/24
|
|
1308
|
+
foo.example.com:
|
|
1309
|
+
- MX: [0, foo1.example.com]
|
|
1310
|
+
foo1.example.com:
|
|
1311
|
+
- A: 1.1.1.1
|
|
1312
|
+
- A: 1.2.3.5
|
|
1313
|
+
e11.example.com:
|
|
1314
|
+
- TXT: v=spf1 mx:foo:bar/baz.example.com
|
|
1315
|
+
foo:bar/baz.example.com:
|
|
1316
|
+
- MX: [0, "foo:bar/baz.example.com"]
|
|
1317
|
+
- A: 1.2.3.4
|
|
1318
|
+
e12.example.com:
|
|
1319
|
+
- TXT: v=spf1 mx:example.-com
|
|
1320
|
+
e13.example.com:
|
|
1321
|
+
- TXT: "v=spf1 mx: -all"
|
|
1322
|
+
---
|
|
1323
|
+
description: EXISTS mechanism syntax
|
|
1324
|
+
tests:
|
|
1325
|
+
exists-empty-domain:
|
|
1326
|
+
description: >-
|
|
1327
|
+
domain-spec cannot be empty.
|
|
1328
|
+
spec: 5.7/2
|
|
1329
|
+
helo: mail.example.com
|
|
1330
|
+
host: 1.2.3.4
|
|
1331
|
+
mailfrom: foo@e1.example.com
|
|
1332
|
+
result: permerror
|
|
1333
|
+
exists-implicit:
|
|
1334
|
+
description: >-
|
|
1335
|
+
exists = "exists" ":" domain-spec
|
|
1336
|
+
spec: 5.7/2
|
|
1337
|
+
helo: mail.example.com
|
|
1338
|
+
host: 1.2.3.4
|
|
1339
|
+
mailfrom: foo@e2.example.com
|
|
1340
|
+
result: permerror
|
|
1341
|
+
exists-cidr:
|
|
1342
|
+
description: >-
|
|
1343
|
+
exists = "exists" ":" domain-spec
|
|
1344
|
+
spec: 5.7/2
|
|
1345
|
+
helo: mail.example.com
|
|
1346
|
+
host: 1.2.3.4
|
|
1347
|
+
mailfrom: foo@e3.example.com
|
|
1348
|
+
result: permerror
|
|
1349
|
+
exists-ip4:
|
|
1350
|
+
description: >-
|
|
1351
|
+
mechanism matches if any DNS A RR exists
|
|
1352
|
+
spec: 5.7/3
|
|
1353
|
+
helo: mail.example.com
|
|
1354
|
+
host: 1.2.3.4
|
|
1355
|
+
mailfrom: foo@e4.example.com
|
|
1356
|
+
result: pass
|
|
1357
|
+
exists-ip6:
|
|
1358
|
+
description: >-
|
|
1359
|
+
The lookup type is A even when the connection is ip6
|
|
1360
|
+
spec: 5.7/3
|
|
1361
|
+
helo: mail.example.com
|
|
1362
|
+
host: "CAFE:BABE::3"
|
|
1363
|
+
mailfrom: foo@e4.example.com
|
|
1364
|
+
result: pass
|
|
1365
|
+
exists-ip6only:
|
|
1366
|
+
description: >-
|
|
1367
|
+
The lookup type is A even when the connection is ip6
|
|
1368
|
+
spec: 5.7/3
|
|
1369
|
+
helo: mail.example.com
|
|
1370
|
+
host: "CAFE:BABE::3"
|
|
1371
|
+
mailfrom: foo@e5.example.com
|
|
1372
|
+
result: fail
|
|
1373
|
+
exists-dnserr:
|
|
1374
|
+
description: >-
|
|
1375
|
+
Result for DNS error clarified in RFC7208: MTAs or other processors
|
|
1376
|
+
SHOULD impose a limit on the maximum amount of elapsed time to evaluate
|
|
1377
|
+
check_host(). Such a limit SHOULD allow at least 20 seconds. If such
|
|
1378
|
+
a limit is exceeded, the result of authorization SHOULD be "temperror".
|
|
1379
|
+
spec: 5/8
|
|
1380
|
+
helo: mail.example.com
|
|
1381
|
+
host: "CAFE:BABE::3"
|
|
1382
|
+
mailfrom: foo@e6.example.com
|
|
1383
|
+
result: temperror
|
|
1384
|
+
zonedata:
|
|
1385
|
+
mail.example.com:
|
|
1386
|
+
- A: 1.2.3.4
|
|
1387
|
+
mail6.example.com:
|
|
1388
|
+
- AAAA: "CAFE:BABE::4"
|
|
1389
|
+
err.example.com:
|
|
1390
|
+
- TIMEOUT
|
|
1391
|
+
e1.example.com:
|
|
1392
|
+
- TXT: "v=spf1 exists:"
|
|
1393
|
+
e2.example.com:
|
|
1394
|
+
- TXT: "v=spf1 exists"
|
|
1395
|
+
e3.example.com:
|
|
1396
|
+
- TXT: "v=spf1 exists:mail.example.com/24"
|
|
1397
|
+
e4.example.com:
|
|
1398
|
+
- TXT: "v=spf1 exists:mail.example.com"
|
|
1399
|
+
e5.example.com:
|
|
1400
|
+
- TXT: "v=spf1 exists:mail6.example.com -all"
|
|
1401
|
+
e6.example.com:
|
|
1402
|
+
- TXT: "v=spf1 exists:err.example.com -all"
|
|
1403
|
+
---
|
|
1404
|
+
description: IP4 mechanism syntax
|
|
1405
|
+
tests:
|
|
1406
|
+
cidr4-0:
|
|
1407
|
+
description: >-
|
|
1408
|
+
ip4-cidr-length = "/" 1*DIGIT
|
|
1409
|
+
spec: 5.6/2
|
|
1410
|
+
helo: mail.example.com
|
|
1411
|
+
host: 1.2.3.4
|
|
1412
|
+
mailfrom: foo@e1.example.com
|
|
1413
|
+
result: pass
|
|
1414
|
+
cidr4-32:
|
|
1415
|
+
description: >-
|
|
1416
|
+
ip4-cidr-length = "/" 1*DIGIT
|
|
1417
|
+
spec: 5.6/2
|
|
1418
|
+
helo: mail.example.com
|
|
1419
|
+
host: 1.2.3.4
|
|
1420
|
+
mailfrom: foo@e2.example.com
|
|
1421
|
+
result: pass
|
|
1422
|
+
cidr4-33:
|
|
1423
|
+
description: >-
|
|
1424
|
+
Invalid CIDR should get permerror.
|
|
1425
|
+
comment: >-
|
|
1426
|
+
The RFC4408 was silent on ip4 CIDR > 32 or ip6 CIDR > 128, but RFC7208
|
|
1427
|
+
is explicit. Invalid CIDR is prohibited.
|
|
1428
|
+
spec: 5.6/2
|
|
1429
|
+
helo: mail.example.com
|
|
1430
|
+
host: 1.2.3.4
|
|
1431
|
+
mailfrom: foo@e3.example.com
|
|
1432
|
+
result: permerror
|
|
1433
|
+
cidr4-032:
|
|
1434
|
+
description: >-
|
|
1435
|
+
Invalid CIDR should get permerror.
|
|
1436
|
+
comment: >-
|
|
1437
|
+
Leading zeros are not explicitly prohibited by the RFC. However,
|
|
1438
|
+
since the RFC explicity prohibits leading zeros in ip4-network,
|
|
1439
|
+
our interpretation is that CIDR should be also.
|
|
1440
|
+
spec: 5.6/2
|
|
1441
|
+
helo: mail.example.com
|
|
1442
|
+
host: 1.2.3.4
|
|
1443
|
+
mailfrom: foo@e4.example.com
|
|
1444
|
+
result: permerror
|
|
1445
|
+
bare-ip4:
|
|
1446
|
+
description: >-
|
|
1447
|
+
IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ]
|
|
1448
|
+
spec: 5.6/2
|
|
1449
|
+
helo: mail.example.com
|
|
1450
|
+
host: 1.2.3.4
|
|
1451
|
+
mailfrom: foo@e5.example.com
|
|
1452
|
+
result: permerror
|
|
1453
|
+
bad-ip4-port:
|
|
1454
|
+
description: >-
|
|
1455
|
+
IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ]
|
|
1456
|
+
comment: >-
|
|
1457
|
+
This has actually been published in SPF records.
|
|
1458
|
+
spec: 5.6/2
|
|
1459
|
+
helo: mail.example.com
|
|
1460
|
+
host: 1.2.3.4
|
|
1461
|
+
mailfrom: foo@e8.example.com
|
|
1462
|
+
result: permerror
|
|
1463
|
+
bad-ip4-short:
|
|
1464
|
+
description: >-
|
|
1465
|
+
It is not permitted to omit parts of the IP address instead of
|
|
1466
|
+
using CIDR notations.
|
|
1467
|
+
spec: 5.6/4
|
|
1468
|
+
helo: mail.example.com
|
|
1469
|
+
host: 1.2.3.4
|
|
1470
|
+
mailfrom: foo@e9.example.com
|
|
1471
|
+
result: permerror
|
|
1472
|
+
ip4-dual-cidr:
|
|
1473
|
+
description: >-
|
|
1474
|
+
dual-cidr-length not permitted on ip4
|
|
1475
|
+
spec: 5.6/2
|
|
1476
|
+
helo: mail.example.com
|
|
1477
|
+
host: 1.2.3.4
|
|
1478
|
+
mailfrom: foo@e6.example.com
|
|
1479
|
+
result: permerror
|
|
1480
|
+
ip4-mapped-ip6:
|
|
1481
|
+
description: >-
|
|
1482
|
+
IP4 mapped IP6 connections MUST be treated as IP4
|
|
1483
|
+
spec: 5/9/2
|
|
1484
|
+
helo: mail.example.com
|
|
1485
|
+
host: "::FFFF:1.2.3.4"
|
|
1486
|
+
mailfrom: foo@e7.example.com
|
|
1487
|
+
result: fail
|
|
1488
|
+
zonedata:
|
|
1489
|
+
mail.example.com:
|
|
1490
|
+
- A: 1.2.3.4
|
|
1491
|
+
e1.example.com:
|
|
1492
|
+
- TXT: v=spf1 ip4:1.1.1.1/0 -all
|
|
1493
|
+
e2.example.com:
|
|
1494
|
+
- TXT: v=spf1 ip4:1.2.3.4/32 -all
|
|
1495
|
+
e3.example.com:
|
|
1496
|
+
- TXT: v=spf1 ip4:1.2.3.4/33 -all
|
|
1497
|
+
e4.example.com:
|
|
1498
|
+
- TXT: v=spf1 ip4:1.2.3.4/032 -all
|
|
1499
|
+
e5.example.com:
|
|
1500
|
+
- TXT: v=spf1 ip4
|
|
1501
|
+
e6.example.com:
|
|
1502
|
+
- TXT: v=spf1 ip4:1.2.3.4//32
|
|
1503
|
+
e7.example.com:
|
|
1504
|
+
- TXT: "v=spf1 -ip4:1.2.3.4 ip6:::FFFF:1.2.3.4"
|
|
1505
|
+
e8.example.com:
|
|
1506
|
+
- TXT: v=spf1 ip4:1.2.3.4:8080
|
|
1507
|
+
e9.example.com:
|
|
1508
|
+
- TXT: v=spf1 ip4:1.2.3
|
|
1509
|
+
---
|
|
1510
|
+
description: IP6 mechanism syntax
|
|
1511
|
+
comment: >-
|
|
1512
|
+
IP4 only implementations may skip tests where host is not IP4
|
|
1513
|
+
tests:
|
|
1514
|
+
bare-ip6:
|
|
1515
|
+
description: >-
|
|
1516
|
+
IP6 = "ip6" ":" ip6-network [ ip6-cidr-length ]
|
|
1517
|
+
spec: 5.6/2
|
|
1518
|
+
helo: mail.example.com
|
|
1519
|
+
host: 1.2.3.4
|
|
1520
|
+
mailfrom: foo@e1.example.com
|
|
1521
|
+
result: permerror
|
|
1522
|
+
cidr6-0-ip4:
|
|
1523
|
+
description: >-
|
|
1524
|
+
IP4 connections do not match ip6.
|
|
1525
|
+
comment: >-
|
|
1526
|
+
There was controversy over IPv4 mapped connections. RFC7208 clearly
|
|
1527
|
+
states IPv4 mapped addresses only match ip4: mechanisms.
|
|
1528
|
+
spec: 5/9/2
|
|
1529
|
+
helo: mail.example.com
|
|
1530
|
+
host: 1.2.3.4
|
|
1531
|
+
mailfrom: foo@e2.example.com
|
|
1532
|
+
result: neutral
|
|
1533
|
+
cidr6-ip4:
|
|
1534
|
+
description: >-
|
|
1535
|
+
Even if the SMTP connection is via IPv6, an IPv4-mapped IPv6 IP address
|
|
1536
|
+
(see RFC 3513, Section 2.5.5) MUST still be considered an IPv4 address.
|
|
1537
|
+
comment: >-
|
|
1538
|
+
There was controversy over ip4 mapped connections. RFC7208 clearly
|
|
1539
|
+
requires such connections to be considered as ip4 only.
|
|
1540
|
+
spec: 5/9/2
|
|
1541
|
+
helo: mail.example.com
|
|
1542
|
+
host: "::FFFF:1.2.3.4"
|
|
1543
|
+
mailfrom: foo@e2.example.com
|
|
1544
|
+
result: neutral
|
|
1545
|
+
cidr6-0:
|
|
1546
|
+
description: >-
|
|
1547
|
+
Match any IP6
|
|
1548
|
+
spec: 5/8
|
|
1549
|
+
helo: mail.example.com
|
|
1550
|
+
host: "DEAF:BABE::CAB:FEE"
|
|
1551
|
+
mailfrom: foo@e2.example.com
|
|
1552
|
+
result: pass
|
|
1553
|
+
cidr6-129:
|
|
1554
|
+
description: >-
|
|
1555
|
+
Invalid CIDR
|
|
1556
|
+
comment: >-
|
|
1557
|
+
IP4 only implementations MUST fully syntax check all mechanisms,
|
|
1558
|
+
even if they otherwise ignore them.
|
|
1559
|
+
spec: 5.6/2
|
|
1560
|
+
helo: mail.example.com
|
|
1561
|
+
host: 1.2.3.4
|
|
1562
|
+
mailfrom: foo@e3.example.com
|
|
1563
|
+
result: permerror
|
|
1564
|
+
cidr6-bad:
|
|
1565
|
+
description: >-
|
|
1566
|
+
dual-cidr syntax not used for ip6
|
|
1567
|
+
comment: >-
|
|
1568
|
+
IP4 only implementations MUST fully syntax check all mechanisms,
|
|
1569
|
+
even if they otherwise ignore them.
|
|
1570
|
+
spec: 5.6/2
|
|
1571
|
+
helo: mail.example.com
|
|
1572
|
+
host: 1.2.3.4
|
|
1573
|
+
mailfrom: foo@e4.example.com
|
|
1574
|
+
result: permerror
|
|
1575
|
+
cidr6-33:
|
|
1576
|
+
description: >-
|
|
1577
|
+
make sure ip4 cidr restriction are not used for ip6
|
|
1578
|
+
spec: 5.6/2
|
|
1579
|
+
helo: mail.example.com
|
|
1580
|
+
host: "CAFE:BABE:8000::"
|
|
1581
|
+
mailfrom: foo@e5.example.com
|
|
1582
|
+
result: pass
|
|
1583
|
+
cidr6-33-ip4:
|
|
1584
|
+
description: >-
|
|
1585
|
+
make sure ip4 cidr restriction are not used for ip6
|
|
1586
|
+
spec: 5.6/2
|
|
1587
|
+
helo: mail.example.com
|
|
1588
|
+
host: 1.2.3.4
|
|
1589
|
+
mailfrom: foo@e5.example.com
|
|
1590
|
+
result: neutral
|
|
1591
|
+
ip6-bad1:
|
|
1592
|
+
description: >-
|
|
1593
|
+
spec: 5.6/2
|
|
1594
|
+
helo: mail.example.com
|
|
1595
|
+
host: 1.2.3.4
|
|
1596
|
+
mailfrom: foo@e6.example.com
|
|
1597
|
+
result: permerror
|
|
1598
|
+
zonedata:
|
|
1599
|
+
mail.example.com:
|
|
1600
|
+
- A: 1.2.3.4
|
|
1601
|
+
e1.example.com:
|
|
1602
|
+
- TXT: v=spf1 -all ip6
|
|
1603
|
+
e2.example.com:
|
|
1604
|
+
- TXT: "v=spf1 ip6:::1.1.1.1/0"
|
|
1605
|
+
e3.example.com:
|
|
1606
|
+
- TXT: "v=spf1 ip6:::1.1.1.1/129"
|
|
1607
|
+
e4.example.com:
|
|
1608
|
+
- TXT: "v=spf1 ip6:::1.1.1.1//33"
|
|
1609
|
+
e5.example.com:
|
|
1610
|
+
- TXT: "v=spf1 ip6:CAFE:BABE:8000::/33"
|
|
1611
|
+
e6.example.com:
|
|
1612
|
+
- TXT: "v=spf1 ip6::CAFE::BABE"
|
|
1613
|
+
---
|
|
1614
|
+
description: Semantics of exp and other modifiers
|
|
1615
|
+
comment: >-
|
|
1616
|
+
Implementing exp= is optional. If not implemented, the test driver should
|
|
1617
|
+
not check the explanation field.
|
|
1618
|
+
tests:
|
|
1619
|
+
redirect-none:
|
|
1620
|
+
description: >-
|
|
1621
|
+
If no SPF record is found, or if the target-name is malformed, the result
|
|
1622
|
+
is a "PermError" rather than "None".
|
|
1623
|
+
spec: 6.1/4
|
|
1624
|
+
helo: mail.example.com
|
|
1625
|
+
host: 1.2.3.4
|
|
1626
|
+
mailfrom: foo@e10.example.com
|
|
1627
|
+
result: permerror
|
|
1628
|
+
redirect-cancels-exp:
|
|
1629
|
+
description: >-
|
|
1630
|
+
when executing "redirect", exp= from the original domain MUST NOT be used.
|
|
1631
|
+
spec: 6.2/13
|
|
1632
|
+
helo: mail.example.com
|
|
1633
|
+
host: 1.2.3.4
|
|
1634
|
+
mailfrom: foo@e1.example.com
|
|
1635
|
+
result: fail
|
|
1636
|
+
explanation: DEFAULT
|
|
1637
|
+
redirect-syntax-error:
|
|
1638
|
+
description: |
|
|
1639
|
+
redirect = "redirect" "=" domain-spec
|
|
1640
|
+
comment: >-
|
|
1641
|
+
A literal application of the grammar causes modifier syntax
|
|
1642
|
+
errors (except for macro syntax) to become unknown-modifier.
|
|
1643
|
+
|
|
1644
|
+
modifier = explanation | redirect | unknown-modifier
|
|
1645
|
+
|
|
1646
|
+
However, it is generally agreed, with precedent in other RFCs,
|
|
1647
|
+
that unknown-modifier should not be "greedy", and should not
|
|
1648
|
+
match known modifier names. There should have been explicit
|
|
1649
|
+
prose to this effect, and some has been proposed as an erratum.
|
|
1650
|
+
spec: 6.1/2
|
|
1651
|
+
helo: mail.example.com
|
|
1652
|
+
host: 1.2.3.4
|
|
1653
|
+
mailfrom: foo@e17.example.com
|
|
1654
|
+
result: permerror
|
|
1655
|
+
include-ignores-exp:
|
|
1656
|
+
description: >-
|
|
1657
|
+
when executing "include", exp= from the target domain MUST NOT be used.
|
|
1658
|
+
spec: 6.2/13
|
|
1659
|
+
helo: mail.example.com
|
|
1660
|
+
host: 1.2.3.4
|
|
1661
|
+
mailfrom: foo@e7.example.com
|
|
1662
|
+
result: fail
|
|
1663
|
+
explanation: Correct!
|
|
1664
|
+
redirect-cancels-prior-exp:
|
|
1665
|
+
description: >-
|
|
1666
|
+
when executing "redirect", exp= from the original domain MUST NOT be used.
|
|
1667
|
+
spec: 6.2/13
|
|
1668
|
+
helo: mail.example.com
|
|
1669
|
+
host: 1.2.3.4
|
|
1670
|
+
mailfrom: foo@e3.example.com
|
|
1671
|
+
result: fail
|
|
1672
|
+
explanation: See me.
|
|
1673
|
+
invalid-modifier:
|
|
1674
|
+
description: |
|
|
1675
|
+
unknown-modifier = name "=" macro-string
|
|
1676
|
+
name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
|
|
1677
|
+
comment: >-
|
|
1678
|
+
Unknown modifier name must begin with alpha.
|
|
1679
|
+
spec: A/3
|
|
1680
|
+
helo: mail.example.com
|
|
1681
|
+
host: 1.2.3.4
|
|
1682
|
+
mailfrom: foo@e5.example.com
|
|
1683
|
+
result: permerror
|
|
1684
|
+
empty-modifier-name:
|
|
1685
|
+
description: |
|
|
1686
|
+
name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
|
|
1687
|
+
comment: >-
|
|
1688
|
+
Unknown modifier name must not be empty.
|
|
1689
|
+
spec: A/3
|
|
1690
|
+
helo: mail.example.com
|
|
1691
|
+
host: 1.2.3.4
|
|
1692
|
+
mailfrom: foo@e6.example.com
|
|
1693
|
+
result: permerror
|
|
1694
|
+
dorky-sentinel:
|
|
1695
|
+
description: >-
|
|
1696
|
+
An implementation that uses a legal expansion as a sentinel. We
|
|
1697
|
+
cannot check them all, but we can check this one.
|
|
1698
|
+
comment: >-
|
|
1699
|
+
Spaces are allowed in local-part.
|
|
1700
|
+
spec: 7.1/6
|
|
1701
|
+
helo: mail.example.com
|
|
1702
|
+
host: 1.2.3.4
|
|
1703
|
+
mailfrom: "Macro Error@e8.example.com"
|
|
1704
|
+
result: fail
|
|
1705
|
+
explanation: Macro Error in implementation
|
|
1706
|
+
exp-multiple-txt:
|
|
1707
|
+
description: |
|
|
1708
|
+
Ignore exp if multiple TXT records.
|
|
1709
|
+
comment: >-
|
|
1710
|
+
If domain-spec is empty, or there are any DNS processing errors (any
|
|
1711
|
+
RCODE other than 0), or if no records are returned, or if more than one
|
|
1712
|
+
record is returned, or if there are syntax errors in the explanation
|
|
1713
|
+
string, then proceed as if no exp modifier was given.
|
|
1714
|
+
spec: 6.2/4
|
|
1715
|
+
helo: mail.example.com
|
|
1716
|
+
host: 1.2.3.4
|
|
1717
|
+
mailfrom: foo@e11.example.com
|
|
1718
|
+
result: fail
|
|
1719
|
+
explanation: DEFAULT
|
|
1720
|
+
exp-no-txt:
|
|
1721
|
+
description: |
|
|
1722
|
+
Ignore exp if no TXT records.
|
|
1723
|
+
comment: >-
|
|
1724
|
+
If domain-spec is empty, or there are any DNS processing errors (any
|
|
1725
|
+
RCODE other than 0), or if no records are returned, or if more than one
|
|
1726
|
+
record is returned, or if there are syntax errors in the explanation
|
|
1727
|
+
string, then proceed as if no exp modifier was given.
|
|
1728
|
+
spec: 6.2/4
|
|
1729
|
+
helo: mail.example.com
|
|
1730
|
+
host: 1.2.3.4
|
|
1731
|
+
mailfrom: foo@e22.example.com
|
|
1732
|
+
result: fail
|
|
1733
|
+
explanation: DEFAULT
|
|
1734
|
+
exp-dns-error:
|
|
1735
|
+
description: |
|
|
1736
|
+
Ignore exp if DNS error.
|
|
1737
|
+
comment: >-
|
|
1738
|
+
If domain-spec is empty, or there are any DNS processing errors (any
|
|
1739
|
+
RCODE other than 0), or if no records are returned, or if more than one
|
|
1740
|
+
record is returned, or if there are syntax errors in the explanation
|
|
1741
|
+
string, then proceed as if no exp modifier was given.
|
|
1742
|
+
spec: 6.2/4
|
|
1743
|
+
helo: mail.example.com
|
|
1744
|
+
host: 1.2.3.4
|
|
1745
|
+
mailfrom: foo@e21.example.com
|
|
1746
|
+
result: fail
|
|
1747
|
+
explanation: DEFAULT
|
|
1748
|
+
exp-empty-domain:
|
|
1749
|
+
description: |
|
|
1750
|
+
PermError if exp= domain-spec is empty.
|
|
1751
|
+
comment: >-
|
|
1752
|
+
Section 6.2/4 says, "If domain-spec is empty, or there are any DNS
|
|
1753
|
+
processing errors (any RCODE other than 0), or if no records are
|
|
1754
|
+
returned, or if more than one record is returned, or if there are syntax
|
|
1755
|
+
errors in the explanation string, then proceed as if no exp modifier was
|
|
1756
|
+
given." However, "if domain-spec is empty" conflicts with the grammar
|
|
1757
|
+
given for the exp modifier. This was reported as an erratum, and the
|
|
1758
|
+
solution chosen was to report explicit "exp=" as PermError, but ignore
|
|
1759
|
+
problems due to macro expansion, DNS, or invalid explanation string.
|
|
1760
|
+
spec: 6.2/4
|
|
1761
|
+
helo: mail.example.com
|
|
1762
|
+
host: 1.2.3.4
|
|
1763
|
+
mailfrom: foo@e12.example.com
|
|
1764
|
+
result: permerror
|
|
1765
|
+
explanation-syntax-error:
|
|
1766
|
+
description: |
|
|
1767
|
+
Ignore exp if the explanation string has a syntax error.
|
|
1768
|
+
comment: >-
|
|
1769
|
+
If domain-spec is empty, or there are any DNS processing errors (any
|
|
1770
|
+
RCODE other than 0), or if no records are returned, or if more than one
|
|
1771
|
+
record is returned, or if there are syntax errors in the explanation
|
|
1772
|
+
string, then proceed as if no exp modifier was given.
|
|
1773
|
+
spec: 6.2/4
|
|
1774
|
+
helo: mail.example.com
|
|
1775
|
+
host: 1.2.3.4
|
|
1776
|
+
mailfrom: foo@e13.example.com
|
|
1777
|
+
result: fail
|
|
1778
|
+
explanation: DEFAULT
|
|
1779
|
+
exp-syntax-error:
|
|
1780
|
+
description: |
|
|
1781
|
+
explanation = "exp" "=" domain-spec
|
|
1782
|
+
comment: >-
|
|
1783
|
+
A literal application of the grammar causes modifier syntax
|
|
1784
|
+
errors (except for macro syntax) to become unknown-modifier.
|
|
1785
|
+
|
|
1786
|
+
modifier = explanation | redirect | unknown-modifier
|
|
1787
|
+
|
|
1788
|
+
However, it is generally agreed, with precedent in other RFCs,
|
|
1789
|
+
that unknown-modifier should not be "greedy", and should not
|
|
1790
|
+
match known modifier names. There should have been explicit
|
|
1791
|
+
prose to this effect, and some has been proposed as an erratum.
|
|
1792
|
+
spec: 6.2/1
|
|
1793
|
+
helo: mail.example.com
|
|
1794
|
+
host: 1.2.3.4
|
|
1795
|
+
mailfrom: foo@e16.example.com
|
|
1796
|
+
result: permerror
|
|
1797
|
+
exp-twice:
|
|
1798
|
+
description: |
|
|
1799
|
+
exp= appears twice.
|
|
1800
|
+
comment: >-
|
|
1801
|
+
These two modifiers (exp,redirect) MUST NOT appear in a record more than
|
|
1802
|
+
once each. If they do, then check_host() exits with a result of
|
|
1803
|
+
"PermError".
|
|
1804
|
+
spec: 6/2
|
|
1805
|
+
helo: mail.example.com
|
|
1806
|
+
host: 1.2.3.4
|
|
1807
|
+
mailfrom: foo@e14.example.com
|
|
1808
|
+
result: permerror
|
|
1809
|
+
redirect-empty-domain:
|
|
1810
|
+
description: |
|
|
1811
|
+
redirect = "redirect" "=" domain-spec
|
|
1812
|
+
comment: >-
|
|
1813
|
+
Unlike for exp, there is no instruction to override the permerror
|
|
1814
|
+
for an empty domain-spec (which is invalid syntax).
|
|
1815
|
+
spec: 6.2/4
|
|
1816
|
+
helo: mail.example.com
|
|
1817
|
+
host: 1.2.3.4
|
|
1818
|
+
mailfrom: foo@e18.example.com
|
|
1819
|
+
result: permerror
|
|
1820
|
+
redirect-twice:
|
|
1821
|
+
description: |
|
|
1822
|
+
redirect= appears twice.
|
|
1823
|
+
comment: >-
|
|
1824
|
+
These two modifiers (exp,redirect) MUST NOT appear in a record more than
|
|
1825
|
+
once each. If they do, then check_host() exits with a result of
|
|
1826
|
+
"PermError".
|
|
1827
|
+
spec: 6/2
|
|
1828
|
+
helo: mail.example.com
|
|
1829
|
+
host: 1.2.3.4
|
|
1830
|
+
mailfrom: foo@e15.example.com
|
|
1831
|
+
result: permerror
|
|
1832
|
+
unknown-modifier-syntax:
|
|
1833
|
+
description: |
|
|
1834
|
+
unknown-modifier = name "=" macro-string
|
|
1835
|
+
comment: >-
|
|
1836
|
+
Unknown modifiers must have valid macro syntax.
|
|
1837
|
+
spec: A/3
|
|
1838
|
+
helo: mail.example.com
|
|
1839
|
+
host: 1.2.3.4
|
|
1840
|
+
mailfrom: foo@e9.example.com
|
|
1841
|
+
result: permerror
|
|
1842
|
+
default-modifier-obsolete:
|
|
1843
|
+
description: |
|
|
1844
|
+
Unknown modifiers do not modify the RFC SPF result.
|
|
1845
|
+
comment: >-
|
|
1846
|
+
Some implementations may have a leftover default= modifier from
|
|
1847
|
+
earlier drafts.
|
|
1848
|
+
spec: 6/3
|
|
1849
|
+
helo: mail.example.com
|
|
1850
|
+
host: 1.2.3.4
|
|
1851
|
+
mailfrom: foo@e19.example.com
|
|
1852
|
+
result: neutral
|
|
1853
|
+
default-modifier-obsolete2:
|
|
1854
|
+
description: |
|
|
1855
|
+
Unknown modifiers do not modify the RFC SPF result.
|
|
1856
|
+
comment: >-
|
|
1857
|
+
Some implementations may have a leftover default= modifier from
|
|
1858
|
+
earlier drafts.
|
|
1859
|
+
spec: 6/3
|
|
1860
|
+
helo: mail.example.com
|
|
1861
|
+
host: 1.2.3.4
|
|
1862
|
+
mailfrom: foo@e20.example.com
|
|
1863
|
+
result: neutral
|
|
1864
|
+
non-ascii-exp:
|
|
1865
|
+
description: >-
|
|
1866
|
+
SPF explanation text is restricted to 7-bit ascii.
|
|
1867
|
+
comment: >-
|
|
1868
|
+
Checking a possibly different code path for non-ascii chars.
|
|
1869
|
+
spec: 6.2/5
|
|
1870
|
+
helo: hosed
|
|
1871
|
+
host: 1.2.3.4
|
|
1872
|
+
mailfrom: "foobar@nonascii.example.com"
|
|
1873
|
+
result: fail
|
|
1874
|
+
explanation: DEFAULT
|
|
1875
|
+
two-exp-records:
|
|
1876
|
+
description: >-
|
|
1877
|
+
Must ignore exp= if DNS returns more than one TXT record.
|
|
1878
|
+
spec: 6.2/4
|
|
1879
|
+
helo: hosed
|
|
1880
|
+
host: 1.2.3.4
|
|
1881
|
+
mailfrom: "foobar@tworecs.example.com"
|
|
1882
|
+
result: fail
|
|
1883
|
+
explanation: DEFAULT
|
|
1884
|
+
exp-void:
|
|
1885
|
+
description: |
|
|
1886
|
+
exp=nxdomain.tld
|
|
1887
|
+
comment: >-
|
|
1888
|
+
Non-existent exp= domains MUST NOT count against the void lookup limit.
|
|
1889
|
+
Implementations should lookup any exp record at most once after
|
|
1890
|
+
computing the result.
|
|
1891
|
+
spec: 4.6.4/1, 6/2
|
|
1892
|
+
helo: mail.example.com
|
|
1893
|
+
host: 1.2.3.4
|
|
1894
|
+
mailfrom: foo@e23.example.com
|
|
1895
|
+
result: fail
|
|
1896
|
+
redirect-implicit:
|
|
1897
|
+
description: |
|
|
1898
|
+
redirect changes implicit domain
|
|
1899
|
+
spec: 6.1/4
|
|
1900
|
+
helo: e24.example.com
|
|
1901
|
+
host: 192.0.2.2
|
|
1902
|
+
mailfrom: bar@e24.example.com
|
|
1903
|
+
result: pass
|
|
1904
|
+
zonedata:
|
|
1905
|
+
mail.example.com:
|
|
1906
|
+
- A: 1.2.3.4
|
|
1907
|
+
e1.example.com:
|
|
1908
|
+
- TXT: v=spf1 exp=exp1.example.com redirect=e2.example.com
|
|
1909
|
+
e2.example.com:
|
|
1910
|
+
- TXT: v=spf1 -all
|
|
1911
|
+
e3.example.com:
|
|
1912
|
+
- TXT: v=spf1 exp=exp1.example.com redirect=e4.example.com
|
|
1913
|
+
e4.example.com:
|
|
1914
|
+
- TXT: v=spf1 -all exp=exp2.example.com
|
|
1915
|
+
exp1.example.com:
|
|
1916
|
+
- TXT: No-see-um
|
|
1917
|
+
exp2.example.com:
|
|
1918
|
+
- TXT: See me.
|
|
1919
|
+
exp3.example.com:
|
|
1920
|
+
- TXT: Correct!
|
|
1921
|
+
exp4.example.com:
|
|
1922
|
+
- TXT: "%{l} in implementation"
|
|
1923
|
+
e5.example.com:
|
|
1924
|
+
- TXT: v=spf1 1up=foo
|
|
1925
|
+
e6.example.com:
|
|
1926
|
+
- TXT: v=spf1 =all
|
|
1927
|
+
e7.example.com:
|
|
1928
|
+
- TXT: v=spf1 include:e3.example.com -all exp=exp3.example.com
|
|
1929
|
+
e8.example.com:
|
|
1930
|
+
- TXT: v=spf1 -all exp=exp4.example.com
|
|
1931
|
+
e9.example.com:
|
|
1932
|
+
- TXT: v=spf1 -all foo=%abc
|
|
1933
|
+
e10.example.com:
|
|
1934
|
+
- TXT: v=spf1 redirect=erehwon.example.com
|
|
1935
|
+
e11.example.com:
|
|
1936
|
+
- TXT: v=spf1 -all exp=e11msg.example.com
|
|
1937
|
+
e11msg.example.com:
|
|
1938
|
+
- TXT: Answer a fool according to his folly.
|
|
1939
|
+
- TXT: Do not answer a fool according to his folly.
|
|
1940
|
+
e12.example.com:
|
|
1941
|
+
- TXT: v=spf1 exp= -all
|
|
1942
|
+
e13.example.com:
|
|
1943
|
+
- TXT: v=spf1 exp=e13msg.example.com -all
|
|
1944
|
+
e13msg.example.com:
|
|
1945
|
+
- TXT: The %{x}-files.
|
|
1946
|
+
e14.example.com:
|
|
1947
|
+
- TXT: v=spf1 exp=e13msg.example.com -all exp=e11msg.example.com
|
|
1948
|
+
e15.example.com:
|
|
1949
|
+
- TXT: v=spf1 redirect=e12.example.com -all redirect=e12.example.com
|
|
1950
|
+
e16.example.com:
|
|
1951
|
+
- TXT: v=spf1 exp=-all
|
|
1952
|
+
e17.example.com:
|
|
1953
|
+
- TXT: v=spf1 redirect=-all ?all
|
|
1954
|
+
e18.example.com:
|
|
1955
|
+
- TXT: v=spf1 ?all redirect=
|
|
1956
|
+
e19.example.com:
|
|
1957
|
+
- TXT: v=spf1 default=pass
|
|
1958
|
+
e20.example.com:
|
|
1959
|
+
- TXT: "v=spf1 default=+"
|
|
1960
|
+
e21.example.com:
|
|
1961
|
+
- TXT: v=spf1 exp=e21msg.example.com -all
|
|
1962
|
+
e21msg.example.com:
|
|
1963
|
+
- TIMEOUT
|
|
1964
|
+
e22.example.com:
|
|
1965
|
+
- TXT: v=spf1 exp=mail.example.com -all
|
|
1966
|
+
nonascii.example.com:
|
|
1967
|
+
- TXT: v=spf1 exp=badexp.example.com -all
|
|
1968
|
+
badexp.example.com:
|
|
1969
|
+
- TXT: "\xEF\xBB\xBFExplanation"
|
|
1970
|
+
tworecs.example.com:
|
|
1971
|
+
- TXT: v=spf1 exp=twoexp.example.com -all
|
|
1972
|
+
twoexp.example.com:
|
|
1973
|
+
- TXT: "one"
|
|
1974
|
+
- TXT: "two"
|
|
1975
|
+
e23.example.com:
|
|
1976
|
+
- TXT: v=spf1 a:erehwon.example.com a:foobar.com exp=nxdomain.com -all
|
|
1977
|
+
e24.example.com:
|
|
1978
|
+
- TXT: v=spf1 redirect=testimplicit.example.com
|
|
1979
|
+
- A: 192.0.2.1
|
|
1980
|
+
testimplicit.example.com:
|
|
1981
|
+
- TXT: v=spf1 a -all
|
|
1982
|
+
- A: 192.0.2.2
|
|
1983
|
+
---
|
|
1984
|
+
description: Macro expansion rules
|
|
1985
|
+
tests:
|
|
1986
|
+
trailing-dot-domain:
|
|
1987
|
+
spec: 7.1/16
|
|
1988
|
+
description: >-
|
|
1989
|
+
trailing dot is ignored for domains
|
|
1990
|
+
helo: msgbas2x.cos.example.com
|
|
1991
|
+
host: 192.168.218.40
|
|
1992
|
+
mailfrom: test@example.com
|
|
1993
|
+
result: pass
|
|
1994
|
+
trailing-dot-exp:
|
|
1995
|
+
spec: 7.1
|
|
1996
|
+
description: >-
|
|
1997
|
+
trailing dot is not removed from explanation
|
|
1998
|
+
comment: >-
|
|
1999
|
+
A simple way for an implementation to ignore trailing dots on
|
|
2000
|
+
domains is to remove it when present. But be careful not to
|
|
2001
|
+
remove it for explanation text.
|
|
2002
|
+
helo: msgbas2x.cos.example.com
|
|
2003
|
+
host: 192.168.218.40
|
|
2004
|
+
mailfrom: test@exp.example.com
|
|
2005
|
+
result: fail
|
|
2006
|
+
explanation: This is a test.
|
|
2007
|
+
exp-only-macro-char:
|
|
2008
|
+
spec: 7.1/8
|
|
2009
|
+
description: >-
|
|
2010
|
+
The following macro letters are allowed only in "exp" text: c, r, t
|
|
2011
|
+
helo: msgbas2x.cos.example.com
|
|
2012
|
+
host: 192.168.218.40
|
|
2013
|
+
mailfrom: test@e2.example.com
|
|
2014
|
+
result: permerror
|
|
2015
|
+
invalid-macro-char:
|
|
2016
|
+
spec: 7.1/9
|
|
2017
|
+
description: >-
|
|
2018
|
+
A '%' character not followed by a '{', '%', '-', or '_' character
|
|
2019
|
+
is a syntax error.
|
|
2020
|
+
helo: msgbas2x.cos.example.com
|
|
2021
|
+
host: 192.168.218.40
|
|
2022
|
+
mailfrom: test@e1.example.com
|
|
2023
|
+
result: permerror
|
|
2024
|
+
invalid-embedded-macro-char:
|
|
2025
|
+
spec: 7.1/9
|
|
2026
|
+
description: >-
|
|
2027
|
+
A '%' character not followed by a '{', '%', '-', or '_' character
|
|
2028
|
+
is a syntax error.
|
|
2029
|
+
helo: msgbas2x.cos.example.com
|
|
2030
|
+
host: 192.168.218.40
|
|
2031
|
+
mailfrom: test@e1e.example.com
|
|
2032
|
+
result: permerror
|
|
2033
|
+
invalid-trailing-macro-char:
|
|
2034
|
+
spec: 7.1/9
|
|
2035
|
+
description: >-
|
|
2036
|
+
A '%' character not followed by a '{', '%', '-', or '_' character
|
|
2037
|
+
is a syntax error.
|
|
2038
|
+
helo: msgbas2x.cos.example.com
|
|
2039
|
+
host: 192.168.218.40
|
|
2040
|
+
mailfrom: test@e1t.example.com
|
|
2041
|
+
result: permerror
|
|
2042
|
+
macro-mania-in-domain:
|
|
2043
|
+
description: >-
|
|
2044
|
+
macro-encoded percents (%%), spaces (%_), and URL-percent-encoded
|
|
2045
|
+
spaces (%-)
|
|
2046
|
+
spec: 7.1/3, 7.1/4
|
|
2047
|
+
helo: mail.example.com
|
|
2048
|
+
host: 1.2.3.4
|
|
2049
|
+
mailfrom: test@e1a.example.com
|
|
2050
|
+
result: pass
|
|
2051
|
+
exp-txt-macro-char:
|
|
2052
|
+
spec: 7.1/20
|
|
2053
|
+
description: >-
|
|
2054
|
+
For IPv4 addresses, both the "i" and "c" macros expand
|
|
2055
|
+
to the standard dotted-quad format.
|
|
2056
|
+
helo: msgbas2x.cos.example.com
|
|
2057
|
+
host: 192.168.218.40
|
|
2058
|
+
mailfrom: test@e3.example.com
|
|
2059
|
+
result: fail
|
|
2060
|
+
explanation: Connections from 192.168.218.40 not authorized.
|
|
2061
|
+
domain-name-truncation:
|
|
2062
|
+
spec: 7.1/25
|
|
2063
|
+
description: >-
|
|
2064
|
+
When the result of macro expansion is used in a domain name query, if the
|
|
2065
|
+
expanded domain name exceeds 253 characters, the left side is truncated
|
|
2066
|
+
to fit, by removing successive domain labels until the total length does
|
|
2067
|
+
not exceed 253 characters.
|
|
2068
|
+
helo: msgbas2x.cos.example.com
|
|
2069
|
+
host: 192.168.218.40
|
|
2070
|
+
mailfrom: test@somewhat.long.exp.example.com
|
|
2071
|
+
result: fail
|
|
2072
|
+
explanation: Congratulations! That was tricky.
|
|
2073
|
+
v-macro-ip4:
|
|
2074
|
+
spec: 7.1/6
|
|
2075
|
+
description: |-
|
|
2076
|
+
v = the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6
|
|
2077
|
+
helo: msgbas2x.cos.example.com
|
|
2078
|
+
host: 192.168.218.40
|
|
2079
|
+
mailfrom: test@e4.example.com
|
|
2080
|
+
result: fail
|
|
2081
|
+
explanation: 192.168.218.40 is queried as 40.218.168.192.in-addr.arpa
|
|
2082
|
+
v-macro-ip6:
|
|
2083
|
+
spec: 7.1/6
|
|
2084
|
+
description: |-
|
|
2085
|
+
v = the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6
|
|
2086
|
+
helo: msgbas2x.cos.example.com
|
|
2087
|
+
host: "CAFE:BABE::1"
|
|
2088
|
+
mailfrom: test@e4.example.com
|
|
2089
|
+
result: fail
|
|
2090
|
+
explanation: "cafe:babe::1 is queried as 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.E.B.A.B.E.F.A.C.ip6.arpa"
|
|
2091
|
+
undef-macro:
|
|
2092
|
+
spec: 7.1/6
|
|
2093
|
+
description: >-
|
|
2094
|
+
Allowed macros chars are 'slodipvh' plus 'crt' in explanation.
|
|
2095
|
+
helo: msgbas2x.cos.example.com
|
|
2096
|
+
host: "CAFE:BABE::192.168.218.40"
|
|
2097
|
+
mailfrom: test@e5.example.com
|
|
2098
|
+
result: permerror
|
|
2099
|
+
p-macro-ip4-novalid:
|
|
2100
|
+
spec: 7.1/22
|
|
2101
|
+
description: |-
|
|
2102
|
+
p = the validated domain name of <ip>
|
|
2103
|
+
comment: >-
|
|
2104
|
+
The PTR in this example does not validate.
|
|
2105
|
+
helo: msgbas2x.cos.example.com
|
|
2106
|
+
host: 192.168.218.40
|
|
2107
|
+
mailfrom: test@e6.example.com
|
|
2108
|
+
result: fail
|
|
2109
|
+
explanation: connect from unknown
|
|
2110
|
+
p-macro-ip4-valid:
|
|
2111
|
+
spec: 7.1/22
|
|
2112
|
+
description: |-
|
|
2113
|
+
p = the validated domain name of <ip>
|
|
2114
|
+
comment: >-
|
|
2115
|
+
If a subdomain of the <domain> is present, it SHOULD be used.
|
|
2116
|
+
helo: msgbas2x.cos.example.com
|
|
2117
|
+
host: 192.168.218.41
|
|
2118
|
+
mailfrom: test@e6.example.com
|
|
2119
|
+
result: fail
|
|
2120
|
+
explanation: connect from mx.example.com
|
|
2121
|
+
p-macro-ip6-novalid:
|
|
2122
|
+
spec: 7.1/22
|
|
2123
|
+
description: |-
|
|
2124
|
+
p = the validated domain name of <ip>
|
|
2125
|
+
comment: >-
|
|
2126
|
+
The PTR in this example does not validate.
|
|
2127
|
+
helo: msgbas2x.cos.example.com
|
|
2128
|
+
host: "CAFE:BABE::1"
|
|
2129
|
+
mailfrom: test@e6.example.com
|
|
2130
|
+
result: fail
|
|
2131
|
+
explanation: connect from unknown
|
|
2132
|
+
p-macro-ip6-valid:
|
|
2133
|
+
spec: 7.1/22
|
|
2134
|
+
description: |-
|
|
2135
|
+
p = the validated domain name of <ip>
|
|
2136
|
+
comment: >-
|
|
2137
|
+
If a subdomain of the <domain> is present, it SHOULD be used.
|
|
2138
|
+
helo: msgbas2x.cos.example.com
|
|
2139
|
+
host: "CAFE:BABE::3"
|
|
2140
|
+
mailfrom: test@e6.example.com
|
|
2141
|
+
result: fail
|
|
2142
|
+
explanation: connect from mx.example.com
|
|
2143
|
+
p-macro-multiple:
|
|
2144
|
+
spec: 7.1/22
|
|
2145
|
+
description: |-
|
|
2146
|
+
p = the validated domain name of <ip>
|
|
2147
|
+
comment: >-
|
|
2148
|
+
If a subdomain of the <domain> is present, it SHOULD be used.
|
|
2149
|
+
helo: msgbas2x.cos.example.com
|
|
2150
|
+
host: 192.168.218.42
|
|
2151
|
+
mailfrom: test@e7.example.com
|
|
2152
|
+
result: [pass, softfail]
|
|
2153
|
+
upper-macro:
|
|
2154
|
+
spec: 7.1/26
|
|
2155
|
+
description: >-
|
|
2156
|
+
Uppercased macros expand exactly as their lowercased equivalents,
|
|
2157
|
+
and are then URL escaped. All chars not in the unreserved set
|
|
2158
|
+
MUST be escaped.
|
|
2159
|
+
comment: |
|
|
2160
|
+
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
2161
|
+
helo: msgbas2x.cos.example.com
|
|
2162
|
+
host: 192.168.218.42
|
|
2163
|
+
mailfrom: ~jack&jill=up-a_b3.c@e8.example.com
|
|
2164
|
+
result: fail
|
|
2165
|
+
explanation: http://example.com/why.html?l=~jack%26jill%3Dup-a_b3.c
|
|
2166
|
+
hello-macro:
|
|
2167
|
+
spec: 7.1/6
|
|
2168
|
+
description: |-
|
|
2169
|
+
h = HELO/EHLO domain
|
|
2170
|
+
helo: msgbas2x.cos.example.com
|
|
2171
|
+
host: 192.168.218.40
|
|
2172
|
+
mailfrom: test@e9.example.com
|
|
2173
|
+
result: pass
|
|
2174
|
+
invalid-hello-macro:
|
|
2175
|
+
spec: 7.1/2
|
|
2176
|
+
description: |-
|
|
2177
|
+
h = HELO/EHLO domain, but HELO is invalid
|
|
2178
|
+
comment: >-
|
|
2179
|
+
Domain-spec must end in either a macro, or a valid toplabel.
|
|
2180
|
+
It is not correct to check syntax after macro expansion.
|
|
2181
|
+
helo: "JUMPIN' JUPITER"
|
|
2182
|
+
host: 192.168.218.40
|
|
2183
|
+
mailfrom: test@e9.example.com
|
|
2184
|
+
result: fail
|
|
2185
|
+
hello-domain-literal:
|
|
2186
|
+
spec: 7.1/2
|
|
2187
|
+
description: |-
|
|
2188
|
+
h = HELO/EHLO domain, but HELO is a domain literal
|
|
2189
|
+
comment: >-
|
|
2190
|
+
Domain-spec must end in either a macro, or a valid toplabel.
|
|
2191
|
+
It is not correct to check syntax after macro expansion.
|
|
2192
|
+
helo: "[192.168.218.40]"
|
|
2193
|
+
host: 192.168.218.40
|
|
2194
|
+
mailfrom: test@e9.example.com
|
|
2195
|
+
result: fail
|
|
2196
|
+
require-valid-helo:
|
|
2197
|
+
spec: 7.1/6
|
|
2198
|
+
description: >-
|
|
2199
|
+
Example of requiring valid helo in sender policy. This is a complex
|
|
2200
|
+
policy testing several points at once.
|
|
2201
|
+
helo: OEMCOMPUTER
|
|
2202
|
+
host: 1.2.3.4
|
|
2203
|
+
mailfrom: test@e10.example.com
|
|
2204
|
+
result: fail
|
|
2205
|
+
macro-reverse-split-on-dash:
|
|
2206
|
+
spec: 7.1/15, 7.1/16, 7.1/17, 7.1/18
|
|
2207
|
+
description: >-
|
|
2208
|
+
Macro value transformation (splitting on arbitrary characters, reversal,
|
|
2209
|
+
number of right-hand parts to use)
|
|
2210
|
+
helo: mail.example.com
|
|
2211
|
+
host: 1.2.3.4
|
|
2212
|
+
mailfrom: philip-gladstone-test@e11.example.com
|
|
2213
|
+
result: pass
|
|
2214
|
+
macro-multiple-delimiters:
|
|
2215
|
+
spec: 7.1/15, 7.1/16
|
|
2216
|
+
description: |-
|
|
2217
|
+
Multiple delimiters may be specified in a macro expression.
|
|
2218
|
+
macro-expand = ( "%{" macro-letter transformers *delimiter "}" )
|
|
2219
|
+
/ "%%" / "%_" / "%-"
|
|
2220
|
+
helo: mail.example.com
|
|
2221
|
+
host: 1.2.3.4
|
|
2222
|
+
mailfrom: foo-bar+zip+quux@e12.example.com
|
|
2223
|
+
result: pass
|
|
2224
|
+
zonedata:
|
|
2225
|
+
example.com.d.spf.example.com:
|
|
2226
|
+
- TXT: v=spf1 redirect=a.spf.example.com
|
|
2227
|
+
a.spf.example.com:
|
|
2228
|
+
- TXT: v=spf1 include:o.spf.example.com. ~all
|
|
2229
|
+
o.spf.example.com:
|
|
2230
|
+
- TXT: v=spf1 ip4:192.168.218.40
|
|
2231
|
+
msgbas2x.cos.example.com:
|
|
2232
|
+
- A: 192.168.218.40
|
|
2233
|
+
example.com:
|
|
2234
|
+
- A: 192.168.90.76
|
|
2235
|
+
- TXT: v=spf1 redirect=%{d}.d.spf.example.com.
|
|
2236
|
+
exp.example.com:
|
|
2237
|
+
- TXT: v=spf1 exp=msg.example.com. -all
|
|
2238
|
+
msg.example.com:
|
|
2239
|
+
- TXT: This is a test.
|
|
2240
|
+
e1.example.com:
|
|
2241
|
+
- TXT: v=spf1 -exists:%(ir).sbl.example.com ?all
|
|
2242
|
+
e1e.example.com:
|
|
2243
|
+
- TXT: v=spf1 exists:foo%(ir).sbl.example.com ?all
|
|
2244
|
+
e1t.example.com:
|
|
2245
|
+
- TXT: v=spf1 exists:foo%.sbl.example.com ?all
|
|
2246
|
+
e1a.example.com:
|
|
2247
|
+
- TXT: "v=spf1 a:macro%%percent%_%_space%-url-space.example.com -all"
|
|
2248
|
+
"macro%percent space%20url-space.example.com":
|
|
2249
|
+
- A: 1.2.3.4
|
|
2250
|
+
e2.example.com:
|
|
2251
|
+
- TXT: v=spf1 -all exp=%{r}.example.com
|
|
2252
|
+
e3.example.com:
|
|
2253
|
+
- TXT: v=spf1 -all exp=%{ir}.example.com
|
|
2254
|
+
40.218.168.192.example.com:
|
|
2255
|
+
- TXT: Connections from %{c} not authorized.
|
|
2256
|
+
somewhat.long.exp.example.com:
|
|
2257
|
+
- TXT: v=spf1 -all exp=foobar.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.example.com
|
|
2258
|
+
somewhat.long.exp.example.com.somewhat.long.exp.example.com.somewhat.long.exp.example.com.somewhat.long.exp.example.com.somewhat.long.exp.example.com.somewhat.long.exp.example.com.somewhat.long.exp.example.com.somewhat.long.exp.example.com.example.com:
|
|
2259
|
+
- TXT: Congratulations! That was tricky.
|
|
2260
|
+
e4.example.com:
|
|
2261
|
+
- TXT: v=spf1 -all exp=e4msg.example.com
|
|
2262
|
+
e4msg.example.com:
|
|
2263
|
+
- TXT: "%{c} is queried as %{ir}.%{v}.arpa"
|
|
2264
|
+
e5.example.com:
|
|
2265
|
+
- TXT: v=spf1 a:%{a}.example.com -all
|
|
2266
|
+
e6.example.com:
|
|
2267
|
+
- TXT: v=spf1 -all exp=e6msg.example.com
|
|
2268
|
+
e6msg.example.com:
|
|
2269
|
+
- TXT: "connect from %{p}"
|
|
2270
|
+
mx.example.com:
|
|
2271
|
+
- A: 192.168.218.41
|
|
2272
|
+
- A: 192.168.218.42
|
|
2273
|
+
- AAAA: "CAFE:BABE::2"
|
|
2274
|
+
- AAAA: "CAFE:BABE::3"
|
|
2275
|
+
40.218.168.192.in-addr.arpa:
|
|
2276
|
+
- PTR: mx.example.com
|
|
2277
|
+
41.218.168.192.in-addr.arpa:
|
|
2278
|
+
- PTR: mx.example.com
|
|
2279
|
+
42.218.168.192.in-addr.arpa:
|
|
2280
|
+
- PTR: mx.example.com
|
|
2281
|
+
- PTR: mx.e7.example.com
|
|
2282
|
+
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.E.B.A.B.E.F.A.C.ip6.arpa:
|
|
2283
|
+
- PTR: mx.example.com
|
|
2284
|
+
3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.E.B.A.B.E.F.A.C.ip6.arpa:
|
|
2285
|
+
- PTR: mx.example.com
|
|
2286
|
+
mx.e7.example.com:
|
|
2287
|
+
- A: 192.168.218.42
|
|
2288
|
+
mx.e7.example.com.should.example.com:
|
|
2289
|
+
- A: 127.0.0.2
|
|
2290
|
+
mx.example.com.ok.example.com:
|
|
2291
|
+
- A: 127.0.0.2
|
|
2292
|
+
e7.example.com:
|
|
2293
|
+
- TXT: v=spf1 exists:%{p}.should.example.com ~exists:%{p}.ok.example.com
|
|
2294
|
+
e8.example.com:
|
|
2295
|
+
- TXT: v=spf1 -all exp=msg8.%{D2}
|
|
2296
|
+
msg8.example.com:
|
|
2297
|
+
- TXT: "http://example.com/why.html?l=%{L}"
|
|
2298
|
+
e9.example.com:
|
|
2299
|
+
- TXT: v=spf1 a:%{H} -all
|
|
2300
|
+
e10.example.com:
|
|
2301
|
+
- TXT: v=spf1 -include:_spfh.%{d2} ip4:1.2.3.0/24 -all
|
|
2302
|
+
_spfh.example.com:
|
|
2303
|
+
- TXT: v=spf1 -a:%{h} +all
|
|
2304
|
+
e11.example.com:
|
|
2305
|
+
- TXT: v=spf1 exists:%{i}.%{l2r-}.user.%{d2}
|
|
2306
|
+
1.2.3.4.gladstone.philip.user.example.com:
|
|
2307
|
+
- A: 127.0.0.2
|
|
2308
|
+
e12.example.com:
|
|
2309
|
+
- TXT: v=spf1 exists:%{l2r+-}.user.%{d2}
|
|
2310
|
+
bar.foo.user.example.com:
|
|
2311
|
+
- A: 127.0.0.2
|
|
2312
|
+
---
|
|
2313
|
+
description: Processing limits
|
|
2314
|
+
tests:
|
|
2315
|
+
redirect-loop:
|
|
2316
|
+
description: >-
|
|
2317
|
+
SPF implementations MUST limit the number of mechanisms and modifiers
|
|
2318
|
+
that do DNS lookups to at most 10 per SPF check.
|
|
2319
|
+
spec: 4.6.4/1
|
|
2320
|
+
helo: mail.example.com
|
|
2321
|
+
host: 1.2.3.4
|
|
2322
|
+
mailfrom: foo@e1.example.com
|
|
2323
|
+
result: permerror
|
|
2324
|
+
include-loop:
|
|
2325
|
+
description: >-
|
|
2326
|
+
SPF implementations MUST limit the number of mechanisms and modifiers
|
|
2327
|
+
that do DNS lookups to at most 10 per SPF check.
|
|
2328
|
+
spec: 4.6.4/1
|
|
2329
|
+
helo: mail.example.com
|
|
2330
|
+
host: 1.2.3.4
|
|
2331
|
+
mailfrom: foo@e2.example.com
|
|
2332
|
+
result: permerror
|
|
2333
|
+
mx-limit:
|
|
2334
|
+
description: >-
|
|
2335
|
+
there MUST be a limit of no more than 10 MX looked up and checked.
|
|
2336
|
+
comment: >-
|
|
2337
|
+
The required result for this test was the subject of much controversy
|
|
2338
|
+
with RFC4408. For RFC7208 the ambiguity was resolved in favor of
|
|
2339
|
+
producing a permerror result.
|
|
2340
|
+
spec: 4.6.4/2
|
|
2341
|
+
helo: mail.example.com
|
|
2342
|
+
host: 1.2.3.5
|
|
2343
|
+
mailfrom: foo@e4.example.com
|
|
2344
|
+
result: permerror
|
|
2345
|
+
ptr-limit:
|
|
2346
|
+
description: >-
|
|
2347
|
+
there MUST be a limit of no more than 10 PTR looked up and checked.
|
|
2348
|
+
comment: >-
|
|
2349
|
+
The result of this test cannot be permerror not only because the
|
|
2350
|
+
RFC does not specify it, but because the sender has no control over
|
|
2351
|
+
the PTR records of spammers.
|
|
2352
|
+
The preferred result reflects evaluating the 10 allowed PTR records in
|
|
2353
|
+
the order returned by the test data.
|
|
2354
|
+
If testing with live DNS, the PTR order may be random, and a pass
|
|
2355
|
+
result would still be compliant. The SPF result is effectively
|
|
2356
|
+
randomized.
|
|
2357
|
+
spec: 4.6.4/3
|
|
2358
|
+
helo: mail.example.com
|
|
2359
|
+
host: 1.2.3.5
|
|
2360
|
+
mailfrom: foo@e5.example.com
|
|
2361
|
+
result: [neutral, pass]
|
|
2362
|
+
false-a-limit:
|
|
2363
|
+
description: >-
|
|
2364
|
+
unlike MX, PTR, there is no RR limit for A
|
|
2365
|
+
comment: >-
|
|
2366
|
+
There seems to be a tendency for developers to want to limit
|
|
2367
|
+
A RRs in addition to MX and PTR. These are IPs, not usable for
|
|
2368
|
+
3rd party DoS attacks, and hence need no low limit.
|
|
2369
|
+
spec: 4.6.4
|
|
2370
|
+
helo: mail.example.com
|
|
2371
|
+
host: 1.2.3.12
|
|
2372
|
+
mailfrom: foo@e10.example.com
|
|
2373
|
+
result: pass
|
|
2374
|
+
mech-at-limit:
|
|
2375
|
+
description: >-
|
|
2376
|
+
SPF implementations MUST limit the number of mechanisms and modifiers
|
|
2377
|
+
that do DNS lookups to at most 10 per SPF check.
|
|
2378
|
+
spec: 4.6.4/1
|
|
2379
|
+
helo: mail.example.com
|
|
2380
|
+
host: 1.2.3.4
|
|
2381
|
+
mailfrom: foo@e6.example.com
|
|
2382
|
+
result: pass
|
|
2383
|
+
mech-over-limit:
|
|
2384
|
+
description: >-
|
|
2385
|
+
SPF implementations MUST limit the number of mechanisms and modifiers
|
|
2386
|
+
that do DNS lookups to at most 10 per SPF check.
|
|
2387
|
+
comment: >-
|
|
2388
|
+
We do not check whether an implementation counts mechanisms before
|
|
2389
|
+
or after evaluation. The RFC is not clear on this.
|
|
2390
|
+
spec: 4.6.4/1
|
|
2391
|
+
helo: mail.example.com
|
|
2392
|
+
host: 1.2.3.4
|
|
2393
|
+
mailfrom: foo@e7.example.com
|
|
2394
|
+
result: permerror
|
|
2395
|
+
include-at-limit:
|
|
2396
|
+
description: >-
|
|
2397
|
+
SPF implementations MUST limit the number of mechanisms and modifiers
|
|
2398
|
+
that do DNS lookups to at most 10 per SPF check.
|
|
2399
|
+
comment: >-
|
|
2400
|
+
The part of the RFC that talks about MAY parse the entire record first
|
|
2401
|
+
(4.6) is specific to syntax errors. In RFC7208, processing limits are
|
|
2402
|
+
part of syntax checking (4.6).
|
|
2403
|
+
spec: 4.6.4/1
|
|
2404
|
+
helo: mail.example.com
|
|
2405
|
+
host: 1.2.3.4
|
|
2406
|
+
mailfrom: foo@e8.example.com
|
|
2407
|
+
result: pass
|
|
2408
|
+
include-over-limit:
|
|
2409
|
+
description: >-
|
|
2410
|
+
SPF implementations MUST limit the number of mechanisms and modifiers
|
|
2411
|
+
that do DNS lookups to at most 10 per SPF check.
|
|
2412
|
+
spec: 4.6.4/1
|
|
2413
|
+
helo: mail.example.com
|
|
2414
|
+
host: 1.2.3.4
|
|
2415
|
+
mailfrom: foo@e9.example.com
|
|
2416
|
+
result: permerror
|
|
2417
|
+
void-at-limit:
|
|
2418
|
+
description: >-
|
|
2419
|
+
SPF implementations SHOULD limit "void lookups" to two. An
|
|
2420
|
+
implementation MAY choose to make such a limit configurable.
|
|
2421
|
+
In this case, a default of two is RECOMMENDED.
|
|
2422
|
+
comment: >-
|
|
2423
|
+
This is a new check in RFC7208, but it's been implemented in Mail::SPF
|
|
2424
|
+
for years with no issues.
|
|
2425
|
+
spec: 4.6.4/7
|
|
2426
|
+
helo: mail.example.com
|
|
2427
|
+
host: 1.2.3.4
|
|
2428
|
+
mailfrom: foo@e12.example.com
|
|
2429
|
+
result: neutral
|
|
2430
|
+
void-over-limit:
|
|
2431
|
+
description: >-
|
|
2432
|
+
SPF implementations SHOULD limit "void lookups" to two. An
|
|
2433
|
+
implementation MAY choose to make such a limit configurable.
|
|
2434
|
+
In this case, a default of two is RECOMMENDED.
|
|
2435
|
+
spec: 4.6.4/7
|
|
2436
|
+
helo: mail.example.com
|
|
2437
|
+
host: 1.2.3.4
|
|
2438
|
+
mailfrom: foo@e11.example.com
|
|
2439
|
+
result: permerror
|
|
2440
|
+
zonedata:
|
|
2441
|
+
mail.example.com:
|
|
2442
|
+
- A: 1.2.3.4
|
|
2443
|
+
e1.example.com:
|
|
2444
|
+
- TXT: v=spf1 ip4:1.1.1.1 redirect=e1.example.com
|
|
2445
|
+
- A: 1.2.3.6
|
|
2446
|
+
e2.example.com:
|
|
2447
|
+
- TXT: v=spf1 include:e3.example.com
|
|
2448
|
+
- A: 1.2.3.7
|
|
2449
|
+
e3.example.com:
|
|
2450
|
+
- TXT: v=spf1 include:e2.example.com
|
|
2451
|
+
- A: 1.2.3.8
|
|
2452
|
+
e4.example.com:
|
|
2453
|
+
- TXT: v=spf1 mx
|
|
2454
|
+
- MX: [0, mail.example.com]
|
|
2455
|
+
- MX: [1, mail.example.com]
|
|
2456
|
+
- MX: [2, mail.example.com]
|
|
2457
|
+
- MX: [3, mail.example.com]
|
|
2458
|
+
- MX: [4, mail.example.com]
|
|
2459
|
+
- MX: [5, mail.example.com]
|
|
2460
|
+
- MX: [6, mail.example.com]
|
|
2461
|
+
- MX: [7, mail.example.com]
|
|
2462
|
+
- MX: [8, mail.example.com]
|
|
2463
|
+
- MX: [9, mail.example.com]
|
|
2464
|
+
- MX: [10, e4.example.com]
|
|
2465
|
+
- A: 1.2.3.5
|
|
2466
|
+
e5.example.com:
|
|
2467
|
+
- TXT: v=spf1 ptr
|
|
2468
|
+
- A: 1.2.3.5
|
|
2469
|
+
5.3.2.1.in-addr.arpa:
|
|
2470
|
+
- PTR: e1.example.com.
|
|
2471
|
+
- PTR: e2.example.com.
|
|
2472
|
+
- PTR: e3.example.com.
|
|
2473
|
+
- PTR: e4.example.com.
|
|
2474
|
+
- PTR: example.com.
|
|
2475
|
+
- PTR: e6.example.com.
|
|
2476
|
+
- PTR: e7.example.com.
|
|
2477
|
+
- PTR: e8.example.com.
|
|
2478
|
+
- PTR: e9.example.com.
|
|
2479
|
+
- PTR: e10.example.com.
|
|
2480
|
+
- PTR: e5.example.com.
|
|
2481
|
+
e6.example.com:
|
|
2482
|
+
- TXT: v=spf1 a mx a mx a mx a mx a ptr ip4:1.2.3.4 -all
|
|
2483
|
+
- A: 1.2.3.8
|
|
2484
|
+
- MX: [10, e6.example.com]
|
|
2485
|
+
e7.example.com:
|
|
2486
|
+
- TXT: v=spf1 a mx a mx a mx a mx a ptr a ip4:1.2.3.4 -all
|
|
2487
|
+
- A: 1.2.3.20
|
|
2488
|
+
e8.example.com:
|
|
2489
|
+
- TXT: v=spf1 a include:inc.example.com ip4:1.2.3.4 mx -all
|
|
2490
|
+
- A: 1.2.3.4
|
|
2491
|
+
inc.example.com:
|
|
2492
|
+
- TXT: v=spf1 a a a a a a a a
|
|
2493
|
+
- A: 1.2.3.10
|
|
2494
|
+
e9.example.com:
|
|
2495
|
+
- TXT: v=spf1 a include:inc.example.com a ip4:1.2.3.4 -all
|
|
2496
|
+
- A: 1.2.3.21
|
|
2497
|
+
e10.example.com:
|
|
2498
|
+
- TXT: v=spf1 a -all
|
|
2499
|
+
- A: 1.2.3.1
|
|
2500
|
+
- A: 1.2.3.2
|
|
2501
|
+
- A: 1.2.3.3
|
|
2502
|
+
- A: 1.2.3.4
|
|
2503
|
+
- A: 1.2.3.5
|
|
2504
|
+
- A: 1.2.3.6
|
|
2505
|
+
- A: 1.2.3.7
|
|
2506
|
+
- A: 1.2.3.8
|
|
2507
|
+
- A: 1.2.3.9
|
|
2508
|
+
- A: 1.2.3.10
|
|
2509
|
+
- A: 1.2.3.11
|
|
2510
|
+
- A: 1.2.3.12
|
|
2511
|
+
e11.example.com:
|
|
2512
|
+
- TXT: v=spf1 a:err.example.com a:err1.example.com a:err2.example.com ?all
|
|
2513
|
+
e12.example.com:
|
|
2514
|
+
- TXT: v=spf1 a:err.example.com a:err1.example.com ?all
|
|
2515
|
+
---
|
|
2516
|
+
description: Test cases from implementation bugs
|
|
2517
|
+
tests:
|
|
2518
|
+
bytes-bug:
|
|
2519
|
+
description: >-
|
|
2520
|
+
Bytes vs str bug from pyspf.
|
|
2521
|
+
comment: >-
|
|
2522
|
+
Pyspf failed with strict=2 only. Other implementations may ignore
|
|
2523
|
+
the strict parameter.
|
|
2524
|
+
spec: 5.4/4
|
|
2525
|
+
helo: example.org
|
|
2526
|
+
host: "2001:db8:ff0:100::2"
|
|
2527
|
+
mailfrom: test@example.org
|
|
2528
|
+
result: pass
|
|
2529
|
+
strict: 2
|
|
2530
|
+
zonedata:
|
|
2531
|
+
example.org:
|
|
2532
|
+
- TXT: "v=spf1 mx redirect=_spf.example.com"
|
|
2533
|
+
- MX: [10,smtp.example.org]
|
|
2534
|
+
- MX: [10,smtp1.example.com]
|
|
2535
|
+
smtp.example.org:
|
|
2536
|
+
- A: 198.51.100.2
|
|
2537
|
+
- AAAA: "2001:db8:ff0:100::3"
|
|
2538
|
+
smtp1.example.com:
|
|
2539
|
+
- A: 192.0.2.26
|
|
2540
|
+
- AAAA: "2001:db8:ff0:200::2"
|
|
2541
|
+
2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.F.F.0.8.B.D.0.1.0.0.2.ip6.arpa:
|
|
2542
|
+
- PTR: smtp6-v.fe.example.org
|
|
2543
|
+
smtp6-v.fe.example.org:
|
|
2544
|
+
- AAAA: "2001:db8:ff0:100::2"
|
|
2545
|
+
_spf.example.com:
|
|
2546
|
+
- TXT: "v=spf1 ptr:fe.example.org ptr:sgp.example.com exp=_expspf.example.org -all"
|
|
2547
|
+
_expspf.example.org:
|
|
2548
|
+
- TXT: "Sender domain not allowed from this host. Please see http://www.openspf.org/Why?s=mfrom&id=%{S}&ip=%{C}&r=%{R}"
|