You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2006/10/07 11:35:32 UTC

svn commit: r453880 - /james/jspf/trunk/src/test/resources/org/apache/james/jspf/rfc4408-tests.yml

Author: norman
Date: Sat Oct  7 02:35:31 2006
New Revision: 453880

URL: http://svn.apache.org/viewvc?view=rev&rev=453880
Log:
New version of testsuite

Modified:
    james/jspf/trunk/src/test/resources/org/apache/james/jspf/rfc4408-tests.yml

Modified: james/jspf/trunk/src/test/resources/org/apache/james/jspf/rfc4408-tests.yml
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/test/resources/org/apache/james/jspf/rfc4408-tests.yml?view=diff&rev=453880&r1=453879&r2=453880
==============================================================================
--- james/jspf/trunk/src/test/resources/org/apache/james/jspf/rfc4408-tests.yml (original)
+++ james/jspf/trunk/src/test/resources/org/apache/james/jspf/rfc4408-tests.yml Sat Oct  7 02:35:31 2006
@@ -1,1278 +1,1302 @@
-# This is the openspf.org test suite based on RFC 4408.
-# $Id$
-# vim:sw=2 sts=2
-#
-# Contributors:
-#   Stuart D Gathman	everything so far
-# Informal contributors (suggestions but no code):
-#   Craig Whitmore
-#   Frank Ellermann
-#   Wayne Schlitt
-#   Scott Kitterman
-#   Norman Maurer
-#
----
-description: Initial processing
-tests:
-  toolonglabel:
-    description: >-
-      DNS labels limited to 63 chars.
-    spec: 4.3/1
-    helo: mail.example.net
-    host: 1.2.3.5
-    mailfrom: lyme.eater@A123456789012345678901234567890123456789012345678901234567890123.example.com
-    result: none
-  longlabel:
-    description: >-
-      DNS labels limited to 63 chars.
-    spec: 4.3/1
-    helo: mail.example.net
-    host: 1.2.3.5
-    mailfrom: lyme.eater@A12345678901234567890123456789012345678901234567890123456789012.example.com
-    result: fail
-  emptylabel:
-    spec: 4.3/1
-    helo: mail.example.net
-    host: 1.2.3.5
-    mailfrom: lyme.eater@A..example.com
-    result: none
-  nolocalpart:
-    spec: 4.3/2
-    helo: mail.example.net
-    host: 1.2.3.4
-    mailfrom: '@example.net'
-    result: fail
-    explanation: postmaster
-zonedata:
-  example.com:
-    - TIMEOUT
-  example.net:
-    - SPF:  v=spf1 -all exp=exp.example.net
-  A.example.net:
-    - SPF:  v=spf1 -all exp=exp.example.net
-  exp.example.net:
-    - TXT:  '%{l}'
-  A12345678901234567890123456789012345678901234567890123456789012.example.com:
-    - SPF:  v=spf1 -all
----
-description: Record lookup
-tests:
-  both:
-    spec: 4.4/1
-    helo: mail.example.net
-    host: 1.2.3.4
-    mailfrom: foo@both.example.net
-    result: fail
-  txtonly:
-    description: Result is none if checking SPF records only.
-    spec: 4.4/1
-    helo: mail.example.net
-    host: 1.2.3.4
-    mailfrom: foo@txtonly.example.net
-    result: [fail, none]
-  spfonly:
-    description: Result is none if checking TXT records only.
-    spec: 4.4/1
-    helo: mail.example.net
-    host: 1.2.3.4
-    mailfrom: foo@spfonly.example.net
-    result: [fail, none]
-  spftimeout:
-    description: >-
-      TXT record present, but SPF lookup times out.
-      Result is temperror if checking SPF records only.
-    comment: >-
-      This actually happens for a popular braindead DNS server.
-    spec: 4.4/1
-    helo: mail.example.net
-    host: 1.2.3.4
-    mailfrom: foo@spftimeout.example.net
-    result: [fail, temperror]
-  txttimeout:
-    description: >-
-      SPF record present, but TXT lookup times out.
-      If only TXT records are checked, result is temperror.
-    spec: 4.4/1
-    helo: mail.example.net
-    host: 1.2.3.4
-    mailfrom: foo@txttimeout.example.net
-    result: [fail, temperror]
-  alltimeout:
-    description: Both TXT and SPF queries time out
-    spec: 4.4/2
-    helo: mail.example.net
-    host: 1.2.3.4
-    mailfrom: foo@alltimeout.example.net
-    result: temperror
-zonedata:
-  both.example.net:
-    - TXT:  v=spf1 -all
-    - SPF:  v=spf1 -all
-  txtonly.example.net:
-    - TXT:  v=spf1 -all
-  spfonly.example.net:
-    - SPF:  v=spf1 -all
-    - TXT:  NONE
-  spftimeout.example.net:
-    - TXT:  v=spf1 -all
-    - TIMEOUT
-  txttimeout.example.net:
-    - SPF:  v=spf1 -all
-    - TXT:  NONE
-    - TIMEOUT
-  alltimeout.example.net:
-    - TIMEOUT
-
----
-description: Selecting records
-tests:
-  nospace1:
-    description: Version must be terminated by space or end of record.
-    spec: 4.5/4
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example2.com
-    result: none
-  empty:
-    description: Empty SPF record.
-    spec: 4.5/4
-    helo: mail1.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example1.com
-    result: neutral
-  nospace2:
-    spec: 4.5/4
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example3.com
-    result: pass
-  spfoverride:
-    description: >-
-      SPF records override TXT records.  Older implementation may
-      check TXT records only.
-    spec: 4.5/5
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example4.com
-    result: [pass, fail]
-  multitxt1:
-    description: >-
-      Older implementations will give permerror/unknown because of
-      the conflicting TXT records.  However, RFC 4408 says the SPF
-      records overrides them.
-    spec: 4.5/5
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example5.com
-    result: [pass, permerror]
-  multitxt2:
-    spec: 4.5/6
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example6.com
-    result: permerror
-  multispf1:
-    description: >-
-      Multiple records is a permerror, even when they are identical.
-    spec: 4.5/6
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example7.com
-    result: permerror
-  multispf2:
-    description: >-
-      Older implementations will give pass because there is a single
-      TXT record.  But RFC 4408 requires permerror because the SPF
-      records override and there are more than one.
-    spec: 4.5/6
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@example8.com
-    result: [permerror, pass]
-  nospf:
-    spec: 4.5/7
-    helo: mail.example1.com
-    host: 1.2.3.4
-    mailfrom: foo@mail.example1.com
-    result: none
-zonedata:
-  example3.com:
-    - SPF:  v=spf10
-    - SPF:  v=spf1 mx
-    - MX:   [0, mail.example1.com]
-  example1.com:
-    - SPF:  v=spf1
-  example2.com:
-    - SPF:  v=spf1mx
-  mail.example1.com:
-    - A:    1.2.3.4
-  example4.com:
-    - SPF:  v=spf1 +all
-    - TXT:  v=spf1 -all
-  example5.com:
-    - SPF:  v=spf1 +all
-    - TXT:  v=spf1 -all
-    - TXT:  v=spf1 +all
-  example6.com:
-    - TXT:  v=spf1 -all
-    - TXT:  v=spf1 +all
-  example7.com:
-    - SPF:  v=spf1 -all
-    - SPF:  v=spf1 -all
-  example8.com:
-    - SPF:  v=spf1 -all
-    - SPF:  v=spf1 -all
-    - TXT:  v=spf1 +all
----
-description: Record evaluation
-tests:
-  detect-errors-anywhere:
-    description: Any syntax errors anywhere in the record MUST be detected.
-    spec: 4.6
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@t1.example.com
-    result: permerror
-  modifier-charset-good:
-    description: name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
-    spec: 4.6.1/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@t2.example.com
-    result: pass
-  modifier-charset-bad1:
-    description: >-
-      '=' character immediately after the name and before any ":" or "/"
-    spec: 4.6.1/4
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@t3.example.com
-    result: permerror
-  modifier-charset-bad2:
-    description: >-
-      '=' character immediately after the name and before any ":" or "/"
-    spec: 4.6.1/4
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@t4.example.com
-    result: permerror
-  redirect-after-mechanisms1:
-    description: >-
-      The "redirect" modifier has an effect after all the mechanisms.
-    comment: >-
-      The redirect in this example would violate processing limits, except
-      that it is never used because of the all mechanism.
-    spec: 4.6.3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@t5.example.com
-    result: softfail
-  redirect-after-mechanisms2:
-    description: >-
-      The "redirect" modifier has an effect after all the mechanisms.
-    spec: 4.6.3
-    helo: mail.example.com
-    host: 1.2.3.5
-    mailfrom: foo@t6.example.com
-    result: fail
-  default-result:
-    description: Default result is neutral.
-    spec: 4.7/1
-    helo: mail.example.com
-    host: 1.2.3.5
-    mailfrom: foo@t7.example.com
-    result: neutral
-  redirect-is-modifier:
-    description: |-
-      Invalid mechanism.  Redirect is a modifier.
-    spec: 4.6.1/4
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@t8.example.com
-    result: permerror
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  t1.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4 -all moo
-  t2.example.com:
-    - SPF: v=spf1 moo.cow-far_out=man:dog/cat ip4:1.2.3.4 -all
-  t3.example.com:
-    - SPF: v=spf1 moo.cow/far_out=man:dog/cat ip4:1.2.3.4 -all
-  t4.example.com:
-    - SPF: v=spf1 moo.cow:far_out=man:dog/cat ip4:1.2.3.4 -all
-  t5.example.com:
-    - SPF: v=spf1 redirect=t5.example.com ~all
-  t6.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4 redirect=t2.example.com
-  t7.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4
-  t8.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4 redirect:t2.example.com
-
----
-description: >-
-  ALL mechanism syntax
-tests:
-  all-dot:
-    description: |
-      all              = "all"
-    comment: |-
-      At least one implementation got this wrong
-    spec: 5.1/1
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e1.example.com
-    result: permerror
-  all-arg:
-    description: |
-      all              = "all"
-    comment: |-
-      At least one implementation got this wrong
-    spec: 5.1/1
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e2.example.com
-    result: permerror
-  all-cidr:
-    description: |
-      all              = "all"
-    spec: 5.1/1
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e3.example.com
-    result: permerror
-  all-neutral:
-    description: |
-      all              = "all"
-    spec: 5.1/1
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e4.example.com
-    result: neutral
-  all-double:
-    description: |
-      all              = "all"
-    spec: 5.1/1
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e5.example.com
-    result: pass
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  e1.example.com:
-    - SPF: v=spf1 -all.
-  e2.example.com:
-    - SPF: v=spf1 -all:foobar
-  e3.example.com:
-    - SPF: v=spf1 -all/8
-  e4.example.com:
-    - SPF: v=spf1 ?all
-  e5.example.com:
-    - SPF: v=spf1 all -all
-
----
-description: >-
-  PTR mechanism syntax
-tests:
-  ptr-cidr:
-    description: |-
-      PTR              = "ptr"    [ ":" domain-spec ]
-    spec: 5.5/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e1.example.com
-    result: permerror
-  ptr-match-target:
-    description: >-
-      Check all validated domain names to see if they end in the <target-name>
-      domain.
-    spec: 5.5/5
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e2.example.com
-    result: pass
-  ptr-match-implicit:
-    description: >-
-      Check all validated domain names to see if they end in the <target-name>
-      domain.
-    spec: 5.5/5
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e3.example.com
-    result: pass
-  ptr-nomatch-invalid:
-    description: >-
-      Check all validated domain names to see if they end in the <target-name>
-      domain.
-    comment: >-
-      This PTR record does not validate
-    spec: 5.5/5
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e4.example.com
-    result: fail
-  ptr-match-ip6:
-    description: >-
-      Check all validated domain names to see if they end in the <target-name>
-      domain.
-    spec: 5.5/5
-    helo: mail.example.com
-    host: CAFE:BABE::1
-    mailfrom: foo@e3.example.com
-    result: pass
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  e1.example.com:
-    - SPF: v=spf1 ptr/0 -all
-  e2.example.com:
-    - SPF: v=spf1 ptr:example.com -all
-  4.3.2.1.in-addr.arpa:
-    - PTR: e3.example.com
-    - PTR: e4.example.com
-    - PTR: mail.example.com
-  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:
-    - PTR: e3.example.com
-  e3.example.com:
-    - SPF: v=spf1 ptr -all
-    - A: 1.2.3.4
-    - AAAA: CAFE:BABE::1
-  e4.example.com:
-    - SPF: v=spf1 ptr -all
-  
----
-description: >-
-  A mechanism syntax
-tests:
-  a-cidr6:
-    description: |
-      A                = "a"      [ ":" domain-spec ] [ dual-cidr-length ]
-      dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
-    spec: 5.3/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e6.example.com
-    result: fail
-  a-bad-cidr4:
-    description: |
-      A                = "a"      [ ":" domain-spec ] [ dual-cidr-length ]
-      dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
-    spec: 5.3/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e6a.example.com
-    result: permerror
-  a-bad-cidr6:
-    description: |
-      A                = "a"      [ ":" domain-spec ] [ dual-cidr-length ]
-      dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
-    spec: 5.3/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e7.example.com
-    result: permerror
-  a-multi-ip1:
-    description: >-
-      A matches any returned IP.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e10.example.com
-    result: pass
-  a-multi-ip2:
-    description: >-
-      A matches any returned IP.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e10.example.com
-    result: pass
-  a-bad-domain:
-    description: >-
-      domain-spec must pass basic syntax checks, 
-    comment: >-
-      A ':' may appear in domain-spec, but not in top-label.
-    spec: 8.1/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e9.example.com
-    result: permerror
-  a-nxdomain:
-    description: >-
-      If no ips are returned, A mechanism doesn't match, even with /0.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e1.example.com
-    result: fail
-  a-cidr4-0:
-    description: >-
-      Matches if any A records are present in DNS.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e2.example.com
-    result: pass
-  a-cidr4-0-ip6:
-    description: >-
-      Matches if any A records are present in DNS.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1234::1
-    mailfrom: foo@e2.example.com
-    result: fail
-  a-cidr6-0-ip4:
-    description: >-
-      Would match if any AAAA records are present in DNS,
-      but not for an IP4 connection.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e2a.example.com
-    result: fail
-  a-cidr6-0-ip4mapped:
-    description: >-
-      Would match if any AAAA records are present in DNS,
-      but not for an IP4 connection.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: ::FFFF:1.2.3.4
-    mailfrom: foo@e2a.example.com
-    result: fail
-  a-cidr6-0-ip6:
-    description: >-
-      Matches if any AAAA records are present in DNS.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1234::1
-    mailfrom: foo@e2a.example.com
-    result: pass
-  a-cidr6-0-nxdomain:
-    description: >-
-      No match if no AAAA records are present in DNS.
-    spec: 5.3/3
-    helo: mail.example.com
-    host: 1234::1
-    mailfrom: foo@e2b.example.com
-    result: fail
-  a-null:
-    description: >-
-      Null not allowed in top-label.
-    spec: 8.1/2
-    helo: mail.example.com
-    host: 1.2.3.5
-    mailfrom: foo@e3.example.com
-    result: permerror
-  a-numeric:
-    description: >-
-      Top-label may not be all numeric
-    comment: >-
-      A common publishing mistake is using ip4 addresses with A mechanism.
-      This should receive special diagnostic attention in the permerror.
-    spec: 8.1/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e4.example.com
-    result: permerror
-  a-numeric-top-label:
-    description: >-
-      Top-label may not be all numeric
-    spec: 8.1/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e5.example.com
-    result: permerror
-  a-colon-domain:
-    description: >-
-      Domain-spec may contain any visible char except %
-    spec: 8.1/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e11.example.com
-    result: pass
-  a-colon-domain-ip4mapped:
-    description: >-
-      Domain-spec may contain any visible char except %
-    spec: 8.1/2
-    helo: mail.example.com
-    host: ::FFFF:1.2.3.4
-    mailfrom: foo@e11.example.com
-    result: pass
-  a-bad-toplab:
-    description: >-
-      Toplabel may not begin with -
-    spec: 8.1/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e12.example.com
-    result: permerror
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  e1.example.com:
-    - SPF: v=spf1 a/0 -all
-  e2.example.com:
-    - A: 1.1.1.1
-    - AAAA: 1234::2
-    - SPF: v=spf1 a/0 -all
-  e2a.example.com:
-    - AAAA: 1234::1
-    - SPF: v=spf1 a//0 -all
-  e2b.example.com:
-    - A: 1.1.1.1
-    - SPF: v=spf1 a//0 -all
-  e3.example.com:
-    - SPF: "v=spf1 a:foo.example.com\0"
-  e4.example.com:
-    - SPF: v=spf1 a:111.222.33.44
-  e5.example.com:
-    - SPF: v=spf1 a:abc.123
-  e6.example.com:
-    - SPF: v=spf1 a//33 -all
-  e6a.example.com:
-    - SPF: v=spf1 a/33 -all
-  e7.example.com:
-    - SPF: v=spf1 a//129 -all
-  e9.example.com:
-    - SPF: v=spf1 a:example.com:8080
-  e10.example.com:
-    - SPF: v=spf1 a:foo.example.com/24
-  foo.example.com:
-    - A: 1.1.1.1
-    - A: 1.2.3.5
-  e11.example.com:
-    - SPF: v=spf1 a:foo:bar/baz.example.com
-  foo:bar/baz.example.com:
-    - A: 1.2.3.4
-  e12.example.com:
-    - SPF: v=spf1 a:example.-com
-
----
-description: >-
-  IP4 mechanism syntax
-tests:
-  cidr4-0:
-    description: >-
-      ip4-cidr-length  = "/" 1*DIGIT
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e1.example.com
-    result: pass
-  cidr4-32:
-    description: >-
-      ip4-cidr-length  = "/" 1*DIGIT
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e2.example.com
-    result: pass
-  cidr4-33:
-    description: >-
-      Invalid CIDR should get permerror.
-    comment: >-
-      The RFC is silent on ip4 CIDR > 32 or ip6 CIDR > 128.  However,
-      since there is no reasonable interpretation (except a noop), we have
-      read between the lines to see a prohibition on invalid CIDR.
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e3.example.com
-    result: permerror
-  cidr4-032:
-    description: >-
-      Invalid CIDR should get permerror.
-    comment: >-
-      Leading zeros are not explicitly prohibited by the RFC. However,
-      since the RFC explicity prohibits leading zeros in ip4-network,
-      our interpretation is that CIDR should be also.
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e4.example.com
-    result: permerror
-  bare-ip4:
-    description: >-
-      IP4              = "ip4"      ":" ip4-network   [ ip4-cidr-length ]
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e5.example.com
-    result: permerror
-  bad-ip4-port:
-    description: >-
-      IP4              = "ip4"      ":" ip4-network   [ ip4-cidr-length ]
-    comment: >-
-      This has actually been published in SPF records.
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e8.example.com
-    result: permerror
-  bad-ip4-short:
-    description: >-
-      It is not permitted to omit parts of the IP address instead of
-      using CIDR notations.
-    spec: 5.6/4
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e9.example.com
-    result: permerror
-  ip4-dual-cidr:
-    description: >-
-      dual-cidr-length not permitted on ip4
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e6.example.com
-    result: permerror
-  ip4-mapped-ip6:
-    description: >-
-      IP4 mapped IP6 connections MUST be treated as IP4
-    spec: 5/9/2
-    helo: mail.example.com
-    host: ::FFFF:1.2.3.4
-    mailfrom: foo@e7.example.com
-    result: fail
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  e1.example.com:
-    - SPF: v=spf1 ip4:1.1.1.1/0 -all
-  e2.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4/32 -all
-  e3.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4/33 -all
-  e4.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4/032 -all
-  e5.example.com:
-    - SPF: v=spf1 ip4
-  e6.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4//32
-  e7.example.com:
-    - SPF: v=spf1 -ip4:1.2.3.4 ip6:::FFFF:1.2.3.4
-  e8.example.com:
-    - SPF: v=spf1 ip4:1.2.3.4:8080
-  e9.example.com:
-    - SPF: v=spf1 ip4:1.2.3
-
----
-description: >-
-  IP6 mechanism syntax
-comment: >-
-  IP4 only implementations may skip tests where host is not IP4
-tests:
-  bare-ip6:
-    description: >-
-      IP6              = "ip6"      ":" ip6-network   [ ip6-cidr-length ]
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e1.example.com
-    result: permerror
-  cidr6-0-ip4:
-    description: >-
-      IP4 connections do not match ip6.
-    spec: 5/9/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e2.example.com
-    result: neutral
-  cidr6-ip4:
-    description: >-
-      Even if the SMTP connection is via IPv6, an IPv4-mapped IPv6 IP address
-      (see RFC 3513, Section 2.5.5) MUST still be considered an IPv4 address.
-    spec: 5/9/2
-    helo: mail.example.com
-    host: ::FFFF:1.2.3.4
-    mailfrom: foo@e2.example.com
-    result: neutral
-  cidr6-0:
-    description: >-
-      Match any IP6
-    spec: 5/8
-    helo: mail.example.com
-    host: DEAF:BABE::CAB:FEE
-    mailfrom: foo@e2.example.com
-    result: pass
-  cidr6-129:
-    description: >-
-      Invalid CIDR
-    comment: >-
-      IP4 only implementations MUST fully syntax check all mechanisms,
-      even if they otherwise ignore them.
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e3.example.com
-    result: permerror
-  cidr6-bad:
-    description: >-
-      dual-cidr syntax not used for ip6
-    comment: >-
-      IP4 only implementations MUST fully syntax check all mechanisms,
-      even if they otherwise ignore them.
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e4.example.com
-    result: permerror
-  cidr6-33:
-    description: >-
-      make sure ip4 cidr restriction are not used for ip6
-    spec: 5.6/2
-    helo: mail.example.com
-    host: "CAFE:BABE:8000::"
-    mailfrom: foo@e5.example.com
-    result: pass
-  cidr6-33-ip4:
-    description: >-
-      make sure ip4 cidr restriction are not used for ip6
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e5.example.com
-    result: neutral
-  ip6-bad1:
-    description: >-
-    spec: 5.6/2
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e6.example.com
-    result: permerror
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  e1.example.com:
-    - SPF: v=spf1 -all ip6
-  e2.example.com:
-    - SPF: v=spf1 ip6:::1.1.1.1/0
-  e3.example.com:
-    - SPF: v=spf1 ip6:::1.1.1.1/129
-  e4.example.com:
-    - SPF: v=spf1 ip6:::1.1.1.1//33
-  e5.example.com:
-    - SPF: v=spf1 ip6:CAFE:BABE:8000::/33
-  e6.example.com:
-    - SPF: v=spf1 ip6::CAFE::BABE
-  
----
-description: >-
-  Semantics of exp and other modifiers.  Implementing exp= is optional.  If not
-  implemented, the test driver should not check the explanation field.
-tests:
-  redirect-cancels-exp:
-    description: >-
-      when executing "redirect", exp= from the original domain MUST NOT be used.
-    spec: 6.2/13
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e1.example.com
-    result: fail
-    explanation: DEFAULT
-  include-ignores-exp:
-    description: >-
-      when executing "incde", exp= from the target domain MUST NOT be used.
-    spec: 6.2/13
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e7.example.com
-    result: fail
-    explanation: Correct!
-  redirect-cancels-prior-exp:
-    description: >-
-      when executing "redirect", exp= from the original domain MUST NOT be used.
-    spec: 6.2/13
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e3.example.com
-    result: fail
-    explanation: See me.
-  invalid-modifier:
-    description: |
-      unknown-modifier = name "=" macro-string
-      name             = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
-    comment: >-
-      Unknown modifier name must begin with alpha.
-    spec: A/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e5.example.com
-    result: permerror
-  empty-modifier-name:
-    description: |
-      name             = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
-    comment: >-
-      Unknown modifier name must not be empty.
-    spec: A/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e6.example.com
-    result: permerror
-  dorky-sentinel:
-    description: >-
-      An implementation that uses a legal expansion as a sentinel.  We
-      can't check them all, but we can check this one.
-    comment: >-
-      Spaces are allowed in local-part.
-    spec: 8.1/6
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: "Macro Error@e8.example.com"
-    result: fail
-    explanation: Macro Error in implementation
-  unknown-modifier-syntax:
-    description: |
-      unknown-modifier = name "=" macro-string
-    comment: >-
-      Unknown modifiers must have valid macro syntax.
-    spec: A/3
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e9.example.com
-    result: permerror
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  e1.example.com:
-    - SPF: v=spf1 exp=exp1.example.com redirect=e2.example.com
-  e2.example.com:
-    - SPF: v=spf1 -all
-  e3.example.com:
-    - SPF: v=spf1 exp=exp1.example.com redirect=e4.example.com
-  e4.example.com:
-    - SPF: v=spf1 -all exp=exp2.example.com
-  exp1.example.com:
-    - TXT: No-see-um
-  exp2.example.com:
-    - TXT: See me.
-  exp3.example.com:
-    - TXT: Correct!
-  exp4.example.com:
-    - TXT: "%{l} in implementation"
-  e5.example.com:
-    - SPF: v=spf1 1up=foo
-  e6.example.com:
-    - SPF: v=spf1 =all
-  e7.example.com:
-    - SPF: v=spf1 include:e3.example.com -all exp=exp3.example.com
-  e8.example.com:
-    - SPF: v=spf1 -all exp=exp4.example.com
-  e9.example.com:
-    - SPF: v=spf1 -all foo=%abc
-
----
-description: |
-  check macro expansion rules
-tests:
-  trailing-dot-domain:
-    spec: 8.1/16
-    description: >-
-      trailing dot is ignored for domains
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@example.com
-    result: pass
-  trailing-dot-exp:
-    spec: 8.1
-    description: >-
-      trailing dot is not removed from explanation
-    comment: >-
-      A simple way for an implementation to ignore trailing dots on
-      domains is to remove it when present.  But be careful not to
-      remove it for explanation text.
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@exp.example.com
-    result: fail
-    explanation: This is a test.
-  exp-only-macro-char:
-    spec: 8.1/8
-    description: >-
-      The following macro letters are allowed only in "exp" text: c, r, t
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@e2.example.com
-    result: permerror
-  invalid-macro-char:
-    spec: 8.1/9
-    description: >-
-      A '%' character not followed by a '{', '%', '-', or '_' character
-      is a syntax error.
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@e1.example.com
-    result: permerror
-  exp-txt-macro-char:
-    spec: 8.1/20
-    description: >-
-      For IPv4 addresses, both the "i" and "c" macros expand
-      to the standard dotted-quad format.
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@e3.example.com
-    result: fail
-    explanation: Connections from 192.168.218.40 not authorized.
-  domain-name-truncation:
-    spec: 8.1/25
-    description: >-
-      When the result of macro expansion is used in a domain name query, if the
-      expanded domain name exceeds 253 characters, the left side is truncated
-      to fit, by removing successive domain labels until the total length does
-      not exceed 253 characters.
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@somewhat.long.exp.example.com
-    result: fail
-    explanation: Congratulations!  That was tricky.
-  v-macro-ip4:
-    spec: 8.1/6
-    description: |-
-      v	= the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@e4.example.com
-    result: fail
-    explanation: 192.168.218.40 is queried as 40.218.168.192.in-addr.arpa
-  v-macro-ip6:
-    spec: 8.1/6
-    description: |-
-      v	= the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6
-    helo: msgbas2x.cos.example.com
-    host: CAFE:BABE::1
-    mailfrom: test@e4.example.com
-    result: fail
-    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
-  undef-macro:
-    spec: 8.1/6
-    description: >-
-      Allowed macros chars are 'slodipvh' plus 'crt' in explanation.
-    helo: msgbas2x.cos.example.com
-    host: CAFE:BABE::192.168.218.40
-    mailfrom: test@e5.example.com
-    result: permerror
-  p-macro-ip4-novalid:
-    spec: 8.1/22
-    description: |-
-      p	= the validated domain name of <ip>
-    comment: >-
-      The PTR in this example does not validate.
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.40
-    mailfrom: test@e6.example.com
-    result: fail
-    explanation: connect from unknown
-  p-macro-ip4-valid:
-    spec: 8.1/22
-    description: |-
-      p	= the validated domain name of <ip>
-    comment: >-
-      If a subdomain of the <domain> is present, it SHOULD be used.
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.41
-    mailfrom: test@e6.example.com
-    result: fail
-    explanation: connect from mx.example.com
-  p-macro-ip6-novalid:
-    spec: 8.1/22
-    description: |-
-      p	= the validated domain name of <ip>
-    comment: >-
-      The PTR in this example does not validate.
-    helo: msgbas2x.cos.example.com
-    host: CAFE:BABE::1
-    mailfrom: test@e6.example.com
-    result: fail
-    explanation: connect from unknown
-  p-macro-ip6-valid:
-    spec: 8.1/22
-    description: |-
-      p	= the validated domain name of <ip>
-    comment: >-
-      If a subdomain of the <domain> is present, it SHOULD be used.  
-    helo: msgbas2x.cos.example.com
-    host: CAFE:BABE::3
-    mailfrom: test@e6.example.com
-    result: fail
-    explanation: connect from mx.example.com
-  p-macro-multiple:
-    spec: 8.1/22
-    description: |-
-      p	= the validated domain name of <ip>
-    comment: >-
-      If a subdomain of the <domain> is present, it SHOULD be used.  
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.42
-    mailfrom: test@e7.example.com
-    result: [ pass, softfail ]
-  upper-macro:
-    spec: 8.1/26
-    description: >-
-      Uppercased macros expand exactly as their lowercased equivalents, 
-      and are then URL escaped.
-    helo: msgbas2x.cos.example.com
-    host: 192.168.218.42
-    mailfrom: jack&jill=up@e8.example.com
-    result: fail
-    explanation: http://example.com/why.html?l=jack%26jill%3Dup
-zonedata:
-  example.com.d.spf.example.com:
-    - SPF: v=spf1 redirect=a.spf.example.com
-  a.spf.example.com:
-    - SPF: v=spf1 include:o.spf.example.com. ~all
-  o.spf.example.com:
-    - SPF: v=spf1 ip4:192.168.218.40
-  msgbas2x.cos.example.com:
-    - A: 192.168.218.40
-  example.com:
-    - A: 192.168.90.76
-    - SPF: v=spf1 redirect=%{d}.d.spf.example.com.
-  exp.example.com:
-    - SPF: v=spf1 exp=msg.example.com. -all
-  msg.example.com:
-    - TXT: This is a test.
-  e1.example.com:
-    - SPF: v=spf1 -exists:%(ir).sbl.example.com ?all
-  e2.example.com:
-    - SPF: v=spf1 -all exp=%{r}.example.com
-  e3.example.com:
-    - SPF: v=spf1 -all exp=%{ir}.example.com
-  40.218.168.192.example.com:
-    - TXT: Connections from %{c} not authorized.
-  somewhat.long.exp.example.com:
-    - SPF: v=spf1 -all exp=foobar.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.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.somewhat.long.exp.example.com.example.com:
-    - TXT: Congratulations!  That was tricky.
-  e4.example.com:
-    - SPF: v=spf1 -all exp=e4.example.com
-    - TXT: "%{c} is queried as %{ir}.%{v}.arpa"
-  e5.example.com:
-    - SPF: v=spf1 a:%{a}.example.com -all
-  e6.example.com:
-    - SPF: v=spf1 -all exp=e6.example.com
-    - TXT: "connect from %{p}"
-  mx.example.com:
-    - A: 192.168.218.41
-    - A: 192.168.218.42
-    - AAAA: CAFE:BABE::2
-    - AAAA: CAFE:BABE::3
-  40.218.168.192.in-addr.arpa:
-    - PTR: mx.example.com
-  41.218.168.192.in-addr.arpa:
-    - PTR: mx.example.com
-  42.218.168.192.in-addr.arpa:
-    - PTR: mx.example.com
-    - PTR: mx.e7.example.com
-  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:
-    - PTR: mx.example.com
-  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:
-    - PTR: mx.example.com
-  mx.e7.example.com:
-    - A: 192.168.218.42
-  mx.e7.example.com.should.example.com:
-    - A: 127.0.0.2
-  mx.example.com.ok.example.com:
-    - A: 127.0.0.2
-  e7.example.com:
-    - SPF: v=spf1 exists:%{p}.should.example.com ~exists:%{p}.ok.example.com
-  e8.example.com:
-    - SPF: v=spf1 -all exp=msg8.%{D2}
-  msg8.example.com:
-    - TXT: "http://example.com/why.html?l=%{L}"
-
----
-description: >-
-  Processing limits
-tests:
-  redirect-loop:
-    description: >-
-      SPF implementations MUST limit the number of mechanisms and modifiers 
-      that do DNS lookups to at most 10 per SPF check.
-    spec: 10.1/6
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e1.example.com
-    result: permerror
-  include-loop:
-    description: >-
-      SPF implementations MUST limit the number of mechanisms and modifiers 
-      that do DNS lookups to at most 10 per SPF check.
-    spec: 10.1/6
-    helo: mail.example.com
-    host: 1.2.3.4
-    mailfrom: foo@e2.example.com
-    result: permerror
-  mx-limit:
-    description: >-
-      there MUST be a limit of no more than 10 MX looked up and checked.
-    comment: >-
-      The required result for this test was the subject of much
-      controversy.  Many felt that the RFC *should* have specified
-      permerror, but the concensus was that it failed to actually do so.
-      The preferred result reflects evaluating the 10 allowed MX records in the
-      order returned by the test data - or sorted via priority.
-      If testing with live DNS, the MX order may be random, and a pass
-      result would still be compliant.  The SPF result is effectively
-      random.
-    spec: 10.1/7
-    helo: mail.example.com
-    host: 1.2.3.5
-    mailfrom: foo@e4.example.com
-    result: [neutral, pass]
-  ptr-limit:
-    description: >-
-      there MUST be a limit of no more than 10 PTR looked up and checked.
-    comment: >-
-      The result of this test cannot be permerror not only because the
-      RFC doesn't specify it, but because the sender has no control over
-      the PTR records of spammers.
-      The preferred result reflects evaluating the 10 allowed PTR records in
-      the order returned by the test data.
-      If testing with live DNS, the PTR order may be random, and a pass
-      result would still be compliant.  The SPF result is effectively
-      randomized.
-    spec: 10.1/7
-    helo: mail.example.com
-    host: 1.2.3.5
-    mailfrom: foo@e5.example.com
-    result: [neutral, pass]
-zonedata:
-  mail.example.com:
-    - A: 1.2.3.4
-  e1.example.com:
-    - SPF: v=spf1 ip4:1.1.1.1 redirect=e1.example.com
-  e2.example.com:
-    - SPF: v=spf1 include:e3.example.com
-  e3.example.com:
-    - SPF: v=spf1 include:e2.example.com
-  e4.example.com:
-    - SPF: v=spf1 mx
-    - MX: [0, mail.example.com]
-    - MX: [1, mail.example.com]
-    - MX: [2, mail.example.com]
-    - MX: [3, mail.example.com]
-    - MX: [4, mail.example.com]
-    - MX: [5, mail.example.com]
-    - MX: [6, mail.example.com]
-    - MX: [7, mail.example.com]
-    - MX: [8, mail.example.com]
-    - MX: [9, mail.example.com]
-    - MX: [10, e4.example.com]
-    - A: 1.2.3.5
-  e5.example.com:
-    - SPF: v=spf1 ptr
-    - A: 1.2.3.5
-  5.3.2.1.in-addr.arpa:
-    - PTR: e1.example.com.
-    - PTR: e2.example.com.
-    - PTR: e3.example.com.
-    - PTR: e4.example.com.
-    - PTR: example.com.
-    - PTR: e6.example.com.
-    - PTR: e7.example.com.
-    - PTR: e8.example.com.
-    - PTR: e9.example.com.
-    - PTR: e10.example.com.
-    - PTR: e5.example.com.
+# This is the openspf.org test suite based on RFC 4408.
+# $Id$
+# vim:sw=2 sts=2
+#
+# Contributors:
+#   Stuart D Gathman	everything so far
+# Informal contributors (suggestions but no code):
+#   Craig Whitmore
+#   Frank Ellermann
+#   Wayne Schlitt
+#   Scott Kitterman
+#   Norman Maurer
+#
+---
+description: Initial processing
+tests:
+  toolonglabel:
+    description: >-
+      DNS labels limited to 63 chars.
+    spec: 4.3/1
+    helo: mail.example.net
+    host: 1.2.3.5
+    mailfrom: lyme.eater@A123456789012345678901234567890123456789012345678901234567890123.example.com
+    result: none
+  longlabel:
+    description: >-
+      DNS labels limited to 63 chars.
+    spec: 4.3/1
+    helo: mail.example.net
+    host: 1.2.3.5
+    mailfrom: lyme.eater@A12345678901234567890123456789012345678901234567890123456789012.example.com
+    result: fail
+  emptylabel:
+    spec: 4.3/1
+    helo: mail.example.net
+    host: 1.2.3.5
+    mailfrom: lyme.eater@A..example.com
+    result: none
+  nolocalpart:
+    spec: 4.3/2
+    helo: mail.example.net
+    host: 1.2.3.4
+    mailfrom: '@example.net'
+    result: fail
+    explanation: postmaster
+zonedata:
+  example.com:
+    - TIMEOUT
+  example.net:
+    - SPF:  v=spf1 -all exp=exp.example.net
+  A.example.net:
+    - SPF:  v=spf1 -all exp=exp.example.net
+  exp.example.net:
+    - TXT:  '%{l}'
+  A12345678901234567890123456789012345678901234567890123456789012.example.com:
+    - SPF:  v=spf1 -all
+---
+description: Record lookup
+tests:
+  both:
+    spec: 4.4/1
+    helo: mail.example.net
+    host: 1.2.3.4
+    mailfrom: foo@both.example.net
+    result: fail
+  txtonly:
+    description: Result is none if checking SPF records only.
+    spec: 4.4/1
+    helo: mail.example.net
+    host: 1.2.3.4
+    mailfrom: foo@txtonly.example.net
+    result: [fail, none]
+  spfonly:
+    description: Result is none if checking TXT records only.
+    spec: 4.4/1
+    helo: mail.example.net
+    host: 1.2.3.4
+    mailfrom: foo@spfonly.example.net
+    result: [fail, none]
+  spftimeout:
+    description: >-
+      TXT record present, but SPF lookup times out.
+      Result is temperror if checking SPF records only.
+    comment: >-
+      This actually happens for a popular braindead DNS server.
+    spec: 4.4/1
+    helo: mail.example.net
+    host: 1.2.3.4
+    mailfrom: foo@spftimeout.example.net
+    result: [fail, temperror]
+  txttimeout:
+    description: >-
+      SPF record present, but TXT lookup times out.
+      If only TXT records are checked, result is temperror.
+    spec: 4.4/1
+    helo: mail.example.net
+    host: 1.2.3.4
+    mailfrom: foo@txttimeout.example.net
+    result: [fail, temperror]
+  alltimeout:
+    description: Both TXT and SPF queries time out
+    spec: 4.4/2
+    helo: mail.example.net
+    host: 1.2.3.4
+    mailfrom: foo@alltimeout.example.net
+    result: temperror
+zonedata:
+  both.example.net:
+    - TXT:  v=spf1 -all
+    - SPF:  v=spf1 -all
+  txtonly.example.net:
+    - TXT:  v=spf1 -all
+  spfonly.example.net:
+    - SPF:  v=spf1 -all
+    - TXT:  NONE
+  spftimeout.example.net:
+    - TXT:  v=spf1 -all
+    - TIMEOUT
+  txttimeout.example.net:
+    - SPF:  v=spf1 -all
+    - TXT:  NONE
+    - TIMEOUT
+  alltimeout.example.net:
+    - TIMEOUT
+
+---
+description: Selecting records
+tests:
+  nospace1:
+    description: Version must be terminated by space or end of record.
+    spec: 4.5/4
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example2.com
+    result: none
+  empty:
+    description: Empty SPF record.
+    spec: 4.5/4
+    helo: mail1.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example1.com
+    result: neutral
+  nospace2:
+    spec: 4.5/4
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example3.com
+    result: pass
+  spfoverride:
+    description: >-
+      SPF records override TXT records.  Older implementation may
+      check TXT records only.
+    spec: 4.5/5
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example4.com
+    result: [pass, fail]
+  multitxt1:
+    description: >-
+      Older implementations will give permerror/unknown because of
+      the conflicting TXT records.  However, RFC 4408 says the SPF
+      records overrides them.
+    spec: 4.5/5
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example5.com
+    result: [pass, permerror]
+  multitxt2:
+    description: >-
+      Multiple records is a permerror, v=spf1 is case insensitive
+    spec: 4.5/6
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example6.com
+    result: permerror
+  multispf1:
+    description: >-
+      Multiple records is a permerror, even when they are identical.
+    spec: 4.5/6
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example7.com
+    result: permerror
+  multispf2:
+    description: >-
+      Older implementations will give pass because there is a single
+      TXT record.  But RFC 4408 requires permerror because the SPF
+      records override and there are more than one.
+    spec: 4.5/6
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example8.com
+    result: [permerror, pass]
+  nospf:
+    spec: 4.5/7
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@mail.example1.com
+    result: none
+  case-insensitive:
+    description: >-
+      v=spf1 is case insensitive
+    spec: 4.5/6
+    helo: mail.example1.com
+    host: 1.2.3.4
+    mailfrom: foo@example9.com
+    result: softfail
+zonedata:
+  example3.com:
+    - SPF:  v=spf10
+    - SPF:  v=spf1 mx
+    - MX:   [0, mail.example1.com]
+  example1.com:
+    - SPF:  v=spf1
+  example2.com:
+    - SPF:  v=spf1mx
+  mail.example1.com:
+    - A:    1.2.3.4
+  example4.com:
+    - SPF:  v=spf1 +all
+    - TXT:  v=spf1 -all
+  example5.com:
+    - SPF:  v=spf1 +all
+    - TXT:  v=spf1 -all
+    - TXT:  v=spf1 +all
+  example6.com:
+    - TXT:  v=spf1 -all
+    - TXT:  V=sPf1 +all
+  example7.com:
+    - SPF:  v=spf1 -all
+    - SPF:  v=spf1 -all
+  example8.com:
+    - SPF:  v=spf1 -all
+    - SPF:  v=spf1 -all
+    - TXT:  v=spf1 +all
+  example9.com:
+    - SPF:  v=SpF1 ~all
+---
+description: Record evaluation
+tests:
+  detect-errors-anywhere:
+    description: Any syntax errors anywhere in the record MUST be detected.
+    spec: 4.6
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@t1.example.com
+    result: permerror
+  modifier-charset-good:
+    description: name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
+    spec: 4.6.1/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@t2.example.com
+    result: pass
+  modifier-charset-bad1:
+    description: >-
+      '=' character immediately after the name and before any ":" or "/"
+    spec: 4.6.1/4
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@t3.example.com
+    result: permerror
+  modifier-charset-bad2:
+    description: >-
+      '=' character immediately after the name and before any ":" or "/"
+    spec: 4.6.1/4
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@t4.example.com
+    result: permerror
+  redirect-after-mechanisms1:
+    description: >-
+      The "redirect" modifier has an effect after all the mechanisms.
+    comment: >-
+      The redirect in this example would violate processing limits, except
+      that it is never used because of the all mechanism.
+    spec: 4.6.3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@t5.example.com
+    result: softfail
+  redirect-after-mechanisms2:
+    description: >-
+      The "redirect" modifier has an effect after all the mechanisms.
+    spec: 4.6.3
+    helo: mail.example.com
+    host: 1.2.3.5
+    mailfrom: foo@t6.example.com
+    result: fail
+  default-result:
+    description: Default result is neutral.
+    spec: 4.7/1
+    helo: mail.example.com
+    host: 1.2.3.5
+    mailfrom: foo@t7.example.com
+    result: neutral
+  redirect-is-modifier:
+    description: |-
+      Invalid mechanism.  Redirect is a modifier.
+    spec: 4.6.1/4
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@t8.example.com
+    result: permerror
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  t1.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4 -all moo
+  t2.example.com:
+    - SPF: v=spf1 moo.cow-far_out=man:dog/cat ip4:1.2.3.4 -all
+  t3.example.com:
+    - SPF: v=spf1 moo.cow/far_out=man:dog/cat ip4:1.2.3.4 -all
+  t4.example.com:
+    - SPF: v=spf1 moo.cow:far_out=man:dog/cat ip4:1.2.3.4 -all
+  t5.example.com:
+    - SPF: v=spf1 redirect=t5.example.com ~all
+  t6.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4 redirect=t2.example.com
+  t7.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4
+  t8.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4 redirect:t2.example.com
+
+---
+description: >-
+  ALL mechanism syntax
+tests:
+  all-dot:
+    description: |
+      all              = "all"
+    comment: |-
+      At least one implementation got this wrong
+    spec: 5.1/1
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e1.example.com
+    result: permerror
+  all-arg:
+    description: |
+      all              = "all"
+    comment: |-
+      At least one implementation got this wrong
+    spec: 5.1/1
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e2.example.com
+    result: permerror
+  all-cidr:
+    description: |
+      all              = "all"
+    spec: 5.1/1
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e3.example.com
+    result: permerror
+  all-neutral:
+    description: |
+      all              = "all"
+    spec: 5.1/1
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e4.example.com
+    result: neutral
+  all-double:
+    description: |
+      all              = "all"
+    spec: 5.1/1
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e5.example.com
+    result: pass
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  e1.example.com:
+    - SPF: v=spf1 -all.
+  e2.example.com:
+    - SPF: v=spf1 -all:foobar
+  e3.example.com:
+    - SPF: v=spf1 -all/8
+  e4.example.com:
+    - SPF: v=spf1 ?all
+  e5.example.com:
+    - SPF: v=spf1 all -all
+
+---
+description: >-
+  PTR mechanism syntax
+tests:
+  ptr-cidr:
+    description: |-
+      PTR              = "ptr"    [ ":" domain-spec ]
+    spec: 5.5/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e1.example.com
+    result: permerror
+  ptr-match-target:
+    description: >-
+      Check all validated domain names to see if they end in the <target-name>
+      domain.
+    spec: 5.5/5
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e2.example.com
+    result: pass
+  ptr-match-implicit:
+    description: >-
+      Check all validated domain names to see if they end in the <target-name>
+      domain.
+    spec: 5.5/5
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e3.example.com
+    result: pass
+  ptr-nomatch-invalid:
+    description: >-
+      Check all validated domain names to see if they end in the <target-name>
+      domain.
+    comment: >-
+      This PTR record does not validate
+    spec: 5.5/5
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e4.example.com
+    result: fail
+  ptr-match-ip6:
+    description: >-
+      Check all validated domain names to see if they end in the <target-name>
+      domain.
+    spec: 5.5/5
+    helo: mail.example.com
+    host: CAFE:BABE::1
+    mailfrom: foo@e3.example.com
+    result: pass
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  e1.example.com:
+    - SPF: v=spf1 ptr/0 -all
+  e2.example.com:
+    - SPF: v=spf1 ptr:example.com -all
+  4.3.2.1.in-addr.arpa:
+    - PTR: e3.example.com
+    - PTR: e4.example.com
+    - PTR: mail.example.com
+  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:
+    - PTR: e3.example.com
+  e3.example.com:
+    - SPF: v=spf1 ptr -all
+    - A: 1.2.3.4
+    - AAAA: CAFE:BABE::1
+  e4.example.com:
+    - SPF: v=spf1 ptr -all
+  
+---
+description: >-
+  A mechanism syntax
+tests:
+  a-cidr6:
+    description: |
+      A                = "a"      [ ":" domain-spec ] [ dual-cidr-length ]
+      dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
+    spec: 5.3/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e6.example.com
+    result: fail
+  a-bad-cidr4:
+    description: |
+      A                = "a"      [ ":" domain-spec ] [ dual-cidr-length ]
+      dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
+    spec: 5.3/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e6a.example.com
+    result: permerror
+  a-bad-cidr6:
+    description: |
+      A                = "a"      [ ":" domain-spec ] [ dual-cidr-length ]
+      dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
+    spec: 5.3/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e7.example.com
+    result: permerror
+  a-multi-ip1:
+    description: >-
+      A matches any returned IP.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e10.example.com
+    result: pass
+  a-multi-ip2:
+    description: >-
+      A matches any returned IP.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e10.example.com
+    result: pass
+  a-bad-domain:
+    description: >-
+      domain-spec must pass basic syntax checks, 
+    comment: >-
+      A ':' may appear in domain-spec, but not in top-label.
+    spec: 8.1/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e9.example.com
+    result: permerror
+  a-nxdomain:
+    description: >-
+      If no ips are returned, A mechanism doesn't match, even with /0.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e1.example.com
+    result: fail
+  a-cidr4-0:
+    description: >-
+      Matches if any A records are present in DNS.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e2.example.com
+    result: pass
+  a-cidr4-0-ip6:
+    description: >-
+      Matches if any A records are present in DNS.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1234::1
+    mailfrom: foo@e2.example.com
+    result: fail
+  a-cidr6-0-ip4:
+    description: >-
+      Would match if any AAAA records are present in DNS,
+      but not for an IP4 connection.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e2a.example.com
+    result: fail
+  a-cidr6-0-ip4mapped:
+    description: >-
+      Would match if any AAAA records are present in DNS,
+      but not for an IP4 connection.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: ::FFFF:1.2.3.4
+    mailfrom: foo@e2a.example.com
+    result: fail
+  a-cidr6-0-ip6:
+    description: >-
+      Matches if any AAAA records are present in DNS.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1234::1
+    mailfrom: foo@e2a.example.com
+    result: pass
+  a-cidr6-0-nxdomain:
+    description: >-
+      No match if no AAAA records are present in DNS.
+    spec: 5.3/3
+    helo: mail.example.com
+    host: 1234::1
+    mailfrom: foo@e2b.example.com
+    result: fail
+  a-null:
+    description: >-
+      Null not allowed in top-label.
+    spec: 8.1/2
+    helo: mail.example.com
+    host: 1.2.3.5
+    mailfrom: foo@e3.example.com
+    result: permerror
+  a-numeric:
+    description: >-
+      Top-label may not be all numeric
+    comment: >-
+      A common publishing mistake is using ip4 addresses with A mechanism.
+      This should receive special diagnostic attention in the permerror.
+    spec: 8.1/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e4.example.com
+    result: permerror
+  a-numeric-top-label:
+    description: >-
+      Top-label may not be all numeric
+    spec: 8.1/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e5.example.com
+    result: permerror
+  a-colon-domain:
+    description: >-
+      Domain-spec may contain any visible char except %
+    spec: 8.1/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e11.example.com
+    result: pass
+  a-colon-domain-ip4mapped:
+    description: >-
+      Domain-spec may contain any visible char except %
+    spec: 8.1/2
+    helo: mail.example.com
+    host: ::FFFF:1.2.3.4
+    mailfrom: foo@e11.example.com
+    result: pass
+  a-bad-toplab:
+    description: >-
+      Toplabel may not begin with -
+    spec: 8.1/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e12.example.com
+    result: permerror
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  e1.example.com:
+    - SPF: v=spf1 a/0 -all
+  e2.example.com:
+    - A: 1.1.1.1
+    - AAAA: 1234::2
+    - SPF: v=spf1 a/0 -all
+  e2a.example.com:
+    - AAAA: 1234::1
+    - SPF: v=spf1 a//0 -all
+  e2b.example.com:
+    - A: 1.1.1.1
+    - SPF: v=spf1 a//0 -all
+  e3.example.com:
+    - SPF: "v=spf1 a:foo.example.com\0"
+  e4.example.com:
+    - SPF: v=spf1 a:111.222.33.44
+  e5.example.com:
+    - SPF: v=spf1 a:abc.123
+  e6.example.com:
+    - SPF: v=spf1 a//33 -all
+  e6a.example.com:
+    - SPF: v=spf1 a/33 -all
+  e7.example.com:
+    - SPF: v=spf1 a//129 -all
+  e9.example.com:
+    - SPF: v=spf1 a:example.com:8080
+  e10.example.com:
+    - SPF: v=spf1 a:foo.example.com/24
+  foo.example.com:
+    - A: 1.1.1.1
+    - A: 1.2.3.5
+  e11.example.com:
+    - SPF: v=spf1 a:foo:bar/baz.example.com
+  foo:bar/baz.example.com:
+    - A: 1.2.3.4
+  e12.example.com:
+    - SPF: v=spf1 a:example.-com
+
+---
+description: >-
+  IP4 mechanism syntax
+tests:
+  cidr4-0:
+    description: >-
+      ip4-cidr-length  = "/" 1*DIGIT
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e1.example.com
+    result: pass
+  cidr4-32:
+    description: >-
+      ip4-cidr-length  = "/" 1*DIGIT
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e2.example.com
+    result: pass
+  cidr4-33:
+    description: >-
+      Invalid CIDR should get permerror.
+    comment: >-
+      The RFC is silent on ip4 CIDR > 32 or ip6 CIDR > 128.  However,
+      since there is no reasonable interpretation (except a noop), we have
+      read between the lines to see a prohibition on invalid CIDR.
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e3.example.com
+    result: permerror
+  cidr4-032:
+    description: >-
+      Invalid CIDR should get permerror.
+    comment: >-
+      Leading zeros are not explicitly prohibited by the RFC. However,
+      since the RFC explicity prohibits leading zeros in ip4-network,
+      our interpretation is that CIDR should be also.
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e4.example.com
+    result: permerror
+  bare-ip4:
+    description: >-
+      IP4              = "ip4"      ":" ip4-network   [ ip4-cidr-length ]
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e5.example.com
+    result: permerror
+  bad-ip4-port:
+    description: >-
+      IP4              = "ip4"      ":" ip4-network   [ ip4-cidr-length ]
+    comment: >-
+      This has actually been published in SPF records.
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e8.example.com
+    result: permerror
+  bad-ip4-short:
+    description: >-
+      It is not permitted to omit parts of the IP address instead of
+      using CIDR notations.
+    spec: 5.6/4
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e9.example.com
+    result: permerror
+  ip4-dual-cidr:
+    description: >-
+      dual-cidr-length not permitted on ip4
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e6.example.com
+    result: permerror
+  ip4-mapped-ip6:
+    description: >-
+      IP4 mapped IP6 connections MUST be treated as IP4
+    spec: 5/9/2
+    helo: mail.example.com
+    host: ::FFFF:1.2.3.4
+    mailfrom: foo@e7.example.com
+    result: fail
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  e1.example.com:
+    - SPF: v=spf1 ip4:1.1.1.1/0 -all
+  e2.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4/32 -all
+  e3.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4/33 -all
+  e4.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4/032 -all
+  e5.example.com:
+    - SPF: v=spf1 ip4
+  e6.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4//32
+  e7.example.com:
+    - SPF: v=spf1 -ip4:1.2.3.4 ip6:::FFFF:1.2.3.4
+  e8.example.com:
+    - SPF: v=spf1 ip4:1.2.3.4:8080
+  e9.example.com:
+    - SPF: v=spf1 ip4:1.2.3
+
+---
+description: >-
+  IP6 mechanism syntax
+comment: >-
+  IP4 only implementations may skip tests where host is not IP4
+tests:
+  bare-ip6:
+    description: >-
+      IP6              = "ip6"      ":" ip6-network   [ ip6-cidr-length ]
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e1.example.com
+    result: permerror
+  cidr6-0-ip4:
+    description: >-
+      IP4 connections do not match ip6.
+    spec: 5/9/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e2.example.com
+    result: neutral
+  cidr6-ip4:
+    description: >-
+      Even if the SMTP connection is via IPv6, an IPv4-mapped IPv6 IP address
+      (see RFC 3513, Section 2.5.5) MUST still be considered an IPv4 address.
+    spec: 5/9/2
+    helo: mail.example.com
+    host: ::FFFF:1.2.3.4
+    mailfrom: foo@e2.example.com
+    result: neutral
+  cidr6-0:
+    description: >-
+      Match any IP6
+    spec: 5/8
+    helo: mail.example.com
+    host: DEAF:BABE::CAB:FEE
+    mailfrom: foo@e2.example.com
+    result: pass
+  cidr6-129:
+    description: >-
+      Invalid CIDR
+    comment: >-
+      IP4 only implementations MUST fully syntax check all mechanisms,
+      even if they otherwise ignore them.
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e3.example.com
+    result: permerror
+  cidr6-bad:
+    description: >-
+      dual-cidr syntax not used for ip6
+    comment: >-
+      IP4 only implementations MUST fully syntax check all mechanisms,
+      even if they otherwise ignore them.
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e4.example.com
+    result: permerror
+  cidr6-33:
+    description: >-
+      make sure ip4 cidr restriction are not used for ip6
+    spec: 5.6/2
+    helo: mail.example.com
+    host: "CAFE:BABE:8000::"
+    mailfrom: foo@e5.example.com
+    result: pass
+  cidr6-33-ip4:
+    description: >-
+      make sure ip4 cidr restriction are not used for ip6
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e5.example.com
+    result: neutral
+  ip6-bad1:
+    description: >-
+    spec: 5.6/2
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e6.example.com
+    result: permerror
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  e1.example.com:
+    - SPF: v=spf1 -all ip6
+  e2.example.com:
+    - SPF: v=spf1 ip6:::1.1.1.1/0
+  e3.example.com:
+    - SPF: v=spf1 ip6:::1.1.1.1/129
+  e4.example.com:
+    - SPF: v=spf1 ip6:::1.1.1.1//33
+  e5.example.com:
+    - SPF: v=spf1 ip6:CAFE:BABE:8000::/33
+  e6.example.com:
+    - SPF: v=spf1 ip6::CAFE::BABE
+  
+---
+description: >-
+  Semantics of exp and other modifiers.  Implementing exp= is optional.  If not
+  implemented, the test driver should not check the explanation field.
+tests:
+  redirect-cancels-exp:
+    description: >-
+      when executing "redirect", exp= from the original domain MUST NOT be used.
+    spec: 6.2/13
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e1.example.com
+    result: fail
+    explanation: DEFAULT
+  include-ignores-exp:
+    description: >-
+      when executing "incde", exp= from the target domain MUST NOT be used.
+    spec: 6.2/13
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e7.example.com
+    result: fail
+    explanation: Correct!
+  redirect-cancels-prior-exp:
+    description: >-
+      when executing "redirect", exp= from the original domain MUST NOT be used.
+    spec: 6.2/13
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e3.example.com
+    result: fail
+    explanation: See me.
+  invalid-modifier:
+    description: |
+      unknown-modifier = name "=" macro-string
+      name             = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
+    comment: >-
+      Unknown modifier name must begin with alpha.
+    spec: A/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e5.example.com
+    result: permerror
+  empty-modifier-name:
+    description: |
+      name             = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
+    comment: >-
+      Unknown modifier name must not be empty.
+    spec: A/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e6.example.com
+    result: permerror
+  dorky-sentinel:
+    description: >-
+      An implementation that uses a legal expansion as a sentinel.  We
+      can't check them all, but we can check this one.
+    comment: >-
+      Spaces are allowed in local-part.
+    spec: 8.1/6
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: "Macro Error@e8.example.com"
+    result: fail
+    explanation: Macro Error in implementation
+  unknown-modifier-syntax:
+    description: |
+      unknown-modifier = name "=" macro-string
+    comment: >-
+      Unknown modifiers must have valid macro syntax.
+    spec: A/3
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e9.example.com
+    result: permerror
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  e1.example.com:
+    - SPF: v=spf1 exp=exp1.example.com redirect=e2.example.com
+  e2.example.com:
+    - SPF: v=spf1 -all
+  e3.example.com:
+    - SPF: v=spf1 exp=exp1.example.com redirect=e4.example.com
+  e4.example.com:
+    - SPF: v=spf1 -all exp=exp2.example.com
+  exp1.example.com:
+    - TXT: No-see-um
+  exp2.example.com:
+    - TXT: See me.
+  exp3.example.com:
+    - TXT: Correct!
+  exp4.example.com:
+    - TXT: "%{l} in implementation"
+  e5.example.com:
+    - SPF: v=spf1 1up=foo
+  e6.example.com:
+    - SPF: v=spf1 =all
+  e7.example.com:
+    - SPF: v=spf1 include:e3.example.com -all exp=exp3.example.com
+  e8.example.com:
+    - SPF: v=spf1 -all exp=exp4.example.com
+  e9.example.com:
+    - SPF: v=spf1 -all foo=%abc
+
+---
+description: |
+  check macro expansion rules
+tests:
+  trailing-dot-domain:
+    spec: 8.1/16
+    description: >-
+      trailing dot is ignored for domains
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@example.com
+    result: pass
+  trailing-dot-exp:
+    spec: 8.1
+    description: >-
+      trailing dot is not removed from explanation
+    comment: >-
+      A simple way for an implementation to ignore trailing dots on
+      domains is to remove it when present.  But be careful not to
+      remove it for explanation text.
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@exp.example.com
+    result: fail
+    explanation: This is a test.
+  exp-only-macro-char:
+    spec: 8.1/8
+    description: >-
+      The following macro letters are allowed only in "exp" text: c, r, t
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@e2.example.com
+    result: permerror
+  invalid-macro-char:
+    spec: 8.1/9
+    description: >-
+      A '%' character not followed by a '{', '%', '-', or '_' character
+      is a syntax error.
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@e1.example.com
+    result: permerror
+  exp-txt-macro-char:
+    spec: 8.1/20
+    description: >-
+      For IPv4 addresses, both the "i" and "c" macros expand
+      to the standard dotted-quad format.
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@e3.example.com
+    result: fail
+    explanation: Connections from 192.168.218.40 not authorized.
+  domain-name-truncation:
+    spec: 8.1/25
+    description: >-
+      When the result of macro expansion is used in a domain name query, if the
+      expanded domain name exceeds 253 characters, the left side is truncated
+      to fit, by removing successive domain labels until the total length does
+      not exceed 253 characters.
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@somewhat.long.exp.example.com
+    result: fail
+    explanation: Congratulations!  That was tricky.
+  v-macro-ip4:
+    spec: 8.1/6
+    description: |-
+      v	= the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@e4.example.com
+    result: fail
+    explanation: 192.168.218.40 is queried as 40.218.168.192.in-addr.arpa
+  v-macro-ip6:
+    spec: 8.1/6
+    description: |-
+      v	= the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6
+    helo: msgbas2x.cos.example.com
+    host: CAFE:BABE::1
+    mailfrom: test@e4.example.com
+    result: fail
+    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
+  undef-macro:
+    spec: 8.1/6
+    description: >-
+      Allowed macros chars are 'slodipvh' plus 'crt' in explanation.
+    helo: msgbas2x.cos.example.com
+    host: CAFE:BABE::192.168.218.40
+    mailfrom: test@e5.example.com
+    result: permerror
+  p-macro-ip4-novalid:
+    spec: 8.1/22
+    description: |-
+      p	= the validated domain name of <ip>
+    comment: >-
+      The PTR in this example does not validate.
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.40
+    mailfrom: test@e6.example.com
+    result: fail
+    explanation: connect from unknown
+  p-macro-ip4-valid:
+    spec: 8.1/22
+    description: |-
+      p	= the validated domain name of <ip>
+    comment: >-
+      If a subdomain of the <domain> is present, it SHOULD be used.
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.41
+    mailfrom: test@e6.example.com
+    result: fail
+    explanation: connect from mx.example.com
+  p-macro-ip6-novalid:
+    spec: 8.1/22
+    description: |-
+      p	= the validated domain name of <ip>
+    comment: >-
+      The PTR in this example does not validate.
+    helo: msgbas2x.cos.example.com
+    host: CAFE:BABE::1
+    mailfrom: test@e6.example.com
+    result: fail
+    explanation: connect from unknown
+  p-macro-ip6-valid:
+    spec: 8.1/22
+    description: |-
+      p	= the validated domain name of <ip>
+    comment: >-
+      If a subdomain of the <domain> is present, it SHOULD be used.  
+    helo: msgbas2x.cos.example.com
+    host: CAFE:BABE::3
+    mailfrom: test@e6.example.com
+    result: fail
+    explanation: connect from mx.example.com
+  p-macro-multiple:
+    spec: 8.1/22
+    description: |-
+      p	= the validated domain name of <ip>
+    comment: >-
+      If a subdomain of the <domain> is present, it SHOULD be used.  
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.42
+    mailfrom: test@e7.example.com
+    result: [ pass, softfail ]
+  upper-macro:
+    spec: 8.1/26
+    description: >-
+      Uppercased macros expand exactly as their lowercased equivalents, 
+      and are then URL escaped.
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.42
+    mailfrom: jack&jill=up@e8.example.com
+    result: fail
+    explanation: http://example.com/why.html?l=jack%26jill%3Dup
+  hello-macro:
+    spec: 8.1/6
+    description: |-
+      h	= HELO/EHLO domain
+    helo: msgbas2x.cos.example.com
+    host: 192.168.218.42
+    mailfrom: test@e9.example.com
+    result: pass
+zonedata:
+  example.com.d.spf.example.com:
+    - SPF: v=spf1 redirect=a.spf.example.com
+  a.spf.example.com:
+    - SPF: v=spf1 include:o.spf.example.com. ~all
+  o.spf.example.com:
+    - SPF: v=spf1 ip4:192.168.218.40
+  msgbas2x.cos.example.com:
+    - A: 192.168.218.40
+  example.com:
+    - A: 192.168.90.76
+    - SPF: v=spf1 redirect=%{d}.d.spf.example.com.
+  exp.example.com:
+    - SPF: v=spf1 exp=msg.example.com. -all
+  msg.example.com:
+    - TXT: This is a test.
+  e1.example.com:
+    - SPF: v=spf1 -exists:%(ir).sbl.example.com ?all
+  e2.example.com:
+    - SPF: v=spf1 -all exp=%{r}.example.com
+  e3.example.com:
+    - SPF: v=spf1 -all exp=%{ir}.example.com
+  40.218.168.192.example.com:
+    - TXT: Connections from %{c} not authorized.
+  somewhat.long.exp.example.com:
+    - SPF: v=spf1 -all exp=foobar.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.%{o}.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.somewhat.long.exp.example.com.example.com:
+    - TXT: Congratulations!  That was tricky.
+  e4.example.com:
+    - SPF: v=spf1 -all exp=e4.example.com
+    - TXT: "%{c} is queried as %{ir}.%{v}.arpa"
+  e5.example.com:
+    - SPF: v=spf1 a:%{a}.example.com -all
+  e6.example.com:
+    - SPF: v=spf1 -all exp=e6.example.com
+    - TXT: "connect from %{p}"
+  mx.example.com:
+    - A: 192.168.218.41
+    - A: 192.168.218.42
+    - AAAA: CAFE:BABE::2
+    - AAAA: CAFE:BABE::3
+  40.218.168.192.in-addr.arpa:
+    - PTR: mx.example.com
+  41.218.168.192.in-addr.arpa:
+    - PTR: mx.example.com
+  42.218.168.192.in-addr.arpa:
+    - PTR: mx.example.com
+    - PTR: mx.e7.example.com
+  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:
+    - PTR: mx.example.com
+  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:
+    - PTR: mx.example.com
+  mx.e7.example.com:
+    - A: 192.168.218.42
+  mx.e7.example.com.should.example.com:
+    - A: 127.0.0.2
+  mx.example.com.ok.example.com:
+    - A: 127.0.0.2
+  e7.example.com:
+    - SPF: v=spf1 exists:%{p}.should.example.com ~exists:%{p}.ok.example.com
+  e8.example.com:
+    - SPF: v=spf1 -all exp=msg8.%{D2}
+  msg8.example.com:
+    - TXT: "http://example.com/why.html?l=%{L}"
+  e9.example.com:
+    - SPF: v=spf1 exists:%{h3} -all
+  cos.example.com:
+    - A: 127.0.0.1
+
+---
+description: >-
+  Processing limits
+tests:
+  redirect-loop:
+    description: >-
+      SPF implementations MUST limit the number of mechanisms and modifiers 
+      that do DNS lookups to at most 10 per SPF check.
+    spec: 10.1/6
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e1.example.com
+    result: permerror
+  include-loop:
+    description: >-
+      SPF implementations MUST limit the number of mechanisms and modifiers 
+      that do DNS lookups to at most 10 per SPF check.
+    spec: 10.1/6
+    helo: mail.example.com
+    host: 1.2.3.4
+    mailfrom: foo@e2.example.com
+    result: permerror
+  mx-limit:
+    description: >-
+      there MUST be a limit of no more than 10 MX looked up and checked.
+    comment: >-
+      The required result for this test was the subject of much
+      controversy.  Many felt that the RFC *should* have specified
+      permerror, but the concensus was that it failed to actually do so.
+      The preferred result reflects evaluating the 10 allowed MX records in the
+      order returned by the test data - or sorted via priority.
+      If testing with live DNS, the MX order may be random, and a pass
+      result would still be compliant.  The SPF result is effectively
+      random.
+    spec: 10.1/7
+    helo: mail.example.com
+    host: 1.2.3.5
+    mailfrom: foo@e4.example.com
+    result: [neutral, pass]
+  ptr-limit:
+    description: >-
+      there MUST be a limit of no more than 10 PTR looked up and checked.
+    comment: >-
+      The result of this test cannot be permerror not only because the
+      RFC doesn't specify it, but because the sender has no control over
+      the PTR records of spammers.
+      The preferred result reflects evaluating the 10 allowed PTR records in
+      the order returned by the test data.
+      If testing with live DNS, the PTR order may be random, and a pass
+      result would still be compliant.  The SPF result is effectively
+      randomized.
+    spec: 10.1/7
+    helo: mail.example.com
+    host: 1.2.3.5
+    mailfrom: foo@e5.example.com
+    result: [neutral, pass]
+zonedata:
+  mail.example.com:
+    - A: 1.2.3.4
+  e1.example.com:
+    - SPF: v=spf1 ip4:1.1.1.1 redirect=e1.example.com
+  e2.example.com:
+    - SPF: v=spf1 include:e3.example.com
+  e3.example.com:
+    - SPF: v=spf1 include:e2.example.com
+  e4.example.com:
+    - SPF: v=spf1 mx
+    - MX: [0, mail.example.com]
+    - MX: [1, mail.example.com]
+    - MX: [2, mail.example.com]
+    - MX: [3, mail.example.com]
+    - MX: [4, mail.example.com]
+    - MX: [5, mail.example.com]
+    - MX: [6, mail.example.com]
+    - MX: [7, mail.example.com]
+    - MX: [8, mail.example.com]
+    - MX: [9, mail.example.com]
+    - MX: [10, e4.example.com]
+    - A: 1.2.3.5
+  e5.example.com:
+    - SPF: v=spf1 ptr
+    - A: 1.2.3.5
+  5.3.2.1.in-addr.arpa:
+    - PTR: e1.example.com.
+    - PTR: e2.example.com.
+    - PTR: e3.example.com.
+    - PTR: e4.example.com.
+    - PTR: example.com.
+    - PTR: e6.example.com.
+    - PTR: e7.example.com.
+    - PTR: e8.example.com.
+    - PTR: e9.example.com.
+    - PTR: e10.example.com.
+    - PTR: e5.example.com.



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org