author | Alberto Bertogli
<albertito@blitiri.com.ar> 2022-08-17 22:37:57 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2022-08-27 16:49:25 UTC |
parent | 2ac5fa58d18d80465dcd039aba3df3d82c54ead4 |
spf.go | +13 | -16 |
spf_test.go | +13 | -8 |
testdata/blitirispf-tests.yml | +2 | -2 |
diff --git a/spf.go b/spf.go index 431b931..d36826a 100644 --- a/spf.go +++ b/spf.go @@ -565,10 +565,10 @@ func (r *resolution) ptrField(res Result, field, domain string) (bool, Result, e r.checkVoidLookup(len(ns), err) if err != nil { // https://tools.ietf.org/html/rfc7208#section-5 - if isTemporary(err) { - return true, TempError, err + if isNotFound(err) { + return false, "", err } - return false, "", err + return true, TempError, err } // Only take the first 10 names, ignore the rest. @@ -628,10 +628,10 @@ func (r *resolution) existsField(res Result, field, domain string) (bool, Result r.checkVoidLookup(len(ips), err) if err != nil { // https://tools.ietf.org/html/rfc7208#section-5 - if isTemporary(err) { - return true, TempError, err + if isNotFound(err) { + return false, "", err } - return false, "", err + return true, TempError, err } // Exists only counts if there are IPv4 matches. @@ -758,10 +758,10 @@ func (r *resolution) aField(res Result, field, domain string) (bool, Result, err r.checkVoidLookup(len(ips), err) if err != nil { // https://tools.ietf.org/html/rfc7208#section-5 - if isTemporary(err) { - return true, TempError, err + if isNotFound(err) { + return false, "", err } - return false, "", err + return true, TempError, err } for _, ip := range ips { if ipMatch(r.ip, ip.IP, masks) { @@ -791,10 +791,10 @@ func (r *resolution) mxField(res Result, field, domain string) (bool, Result, er r.checkVoidLookup(len(mxs), err) if err != nil { // https://tools.ietf.org/html/rfc7208#section-5 - if isTemporary(err) { - return true, TempError, err + if isNotFound(err) { + return false, "", err } - return false, "", err + return true, TempError, err } // There's an explicit maximum of 10 MX records per match. @@ -812,10 +812,7 @@ func (r *resolution) mxField(res Result, field, domain string) (bool, Result, er if isNotFound(err) { continue } - if isTemporary(err) { - return true, TempError, err - } - return false, "", err + return true, TempError, err } for _, ipaddr := range ips { mxips = append(mxips, ipaddr.IP) diff --git a/spf_test.go b/spf_test.go index c2391c8..65d1a86 100644 --- a/spf_test.go +++ b/spf_test.go @@ -303,21 +303,26 @@ func TestDNSPermanentErrors(t *testing.T) { IsTemporary: false, } - // Domain "tmperr" will fail resolution with a temporary error. - dns.Errors["tmperr"] = dnsError + // Domain "permerr" will fail resolution with a permanent error. + dns.Errors["permerr"] = dnsError dns.Errors["1.1.1.1"] = dnsError - dns.Mx["tmpmx"] = []*net.MX{mx("tmperr", 10)} + dns.Mx["permmx"] = []*net.MX{mx("permerr", 10)} defaultTrace = t.Logf cases := []struct { txt string res Result }{ - {"v=spf1 include:tmperr", PermError}, - {"v=spf1 a:tmperr", Neutral}, - {"v=spf1 mx:tmperr", Neutral}, - {"v=spf1 ptr:tmperr", Neutral}, - {"v=spf1 mx:tmpmx", Neutral}, + // Top-level checks will return a permanent error. + {"v=spf1 include:permerr", PermError}, + + // RFC specifies that on any DNS error (other than NXDOMAIN), + // we must return TempError. + // https://www.rfc-editor.org/rfc/rfc7208#section-5 + {"v=spf1 a:permerr", TempError}, + {"v=spf1 mx:permerr", TempError}, + {"v=spf1 ptr:permerr", TempError}, + {"v=spf1 mx:permmx", TempError}, } for _, c := range cases { diff --git a/testdata/blitirispf-tests.yml b/testdata/blitirispf-tests.yml index d0cf364..1f21a3e 100644 --- a/testdata/blitirispf-tests.yml +++ b/testdata/blitirispf-tests.yml @@ -106,10 +106,10 @@ tests: exists-perm-error: description: | Check that if, during an 'exists' forward resolution we get an error, we - fail the check. + return temperror. mailfrom: "foo@domain.net" host: 1.2.3.4 - result: softfail + result: temperror zonedata: domain.net: - SPF: v=spf1 exists:lalala.com ~all