2017-05-26 00:27:36 +08:00
|
|
|
package spflib
|
|
|
|
|
|
|
|
import (
|
2024-03-04 00:47:12 +08:00
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2017-05-26 00:27:36 +08:00
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2024-03-04 00:47:12 +08:00
|
|
|
func dump(rec *SPFRecord, indent string, w io.Writer) {
|
|
|
|
|
|
|
|
fmt.Fprintf(w, "%sTotal Lookups: %d\n", indent, rec.Lookups())
|
|
|
|
fmt.Fprint(w, indent+"v=spf1")
|
|
|
|
for _, p := range rec.Parts {
|
|
|
|
fmt.Fprint(w, " "+p.Text)
|
|
|
|
}
|
|
|
|
fmt.Fprintln(w)
|
|
|
|
indent += "\t"
|
|
|
|
for _, p := range rec.Parts {
|
|
|
|
if p.IsLookup {
|
|
|
|
fmt.Fprintln(w, indent+p.Text)
|
|
|
|
}
|
|
|
|
if p.IncludeRecord != nil {
|
|
|
|
dump(p.IncludeRecord, indent+"\t", w)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-05 09:22:01 +08:00
|
|
|
// Lookups returns the number of DNS lookups required by s.
|
|
|
|
func (s *SPFRecord) Lookups() int {
|
|
|
|
count := 0
|
|
|
|
for _, p := range s.Parts {
|
|
|
|
if p.IsLookup {
|
|
|
|
count++
|
|
|
|
}
|
|
|
|
if p.IncludeRecord != nil {
|
|
|
|
count += p.IncludeRecord.Lookups()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count
|
|
|
|
}
|
|
|
|
|
2024-03-04 00:47:12 +08:00
|
|
|
// Print prints an SPFRecord.
|
|
|
|
func (s *SPFRecord) Print() string {
|
|
|
|
w := &bytes.Buffer{}
|
|
|
|
dump(s, "", w)
|
|
|
|
return w.String()
|
|
|
|
}
|
|
|
|
|
2017-05-26 00:27:36 +08:00
|
|
|
func TestParse(t *testing.T) {
|
2017-09-30 03:30:36 +08:00
|
|
|
dnsres, err := NewCache("testdata-dns1.json")
|
2017-05-26 00:27:36 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
rec, err := Parse(strings.Join([]string{"v=spf1",
|
|
|
|
"ip4:198.252.206.0/24",
|
|
|
|
"ip4:192.111.0.0/24",
|
|
|
|
"include:_spf.google.com",
|
|
|
|
"include:mailgun.org",
|
2021-03-02 09:48:29 +08:00
|
|
|
//"include:spf-basic.fogcreek.com",
|
2017-05-26 00:27:36 +08:00
|
|
|
"include:mail.zendesk.com",
|
|
|
|
"include:servers.mcsv.net",
|
|
|
|
"include:sendgrid.net",
|
|
|
|
"include:spf.mtasv.net",
|
2018-05-03 20:54:19 +08:00
|
|
|
"exists:%{i}._spf.sparkpostmail.com",
|
2018-08-02 22:57:41 +08:00
|
|
|
"ptr:sparkpostmail.com",
|
2017-05-26 00:27:36 +08:00
|
|
|
"~all"}, " "), dnsres)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-09-30 03:30:36 +08:00
|
|
|
t.Log(rec.Print())
|
2017-05-26 00:27:36 +08:00
|
|
|
}
|
2018-05-03 22:03:38 +08:00
|
|
|
|
|
|
|
func TestParseWithDoubleSpaces(t *testing.T) {
|
|
|
|
dnsres, err := NewCache("testdata-dns1.json")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
rec, err := Parse("v=spf1 ip4:192.111.0.0/24 ip4:192.111.1.0/24 -all", dnsres)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
t.Log(rec.Print())
|
|
|
|
}
|
2019-06-20 01:46:56 +08:00
|
|
|
|
|
|
|
func TestParseRedirectNotLast(t *testing.T) {
|
2019-06-21 19:48:59 +08:00
|
|
|
// Make sure redirect=foo fails if it isn't the last item.
|
2019-06-20 01:46:56 +08:00
|
|
|
dnsres, err := NewCache("testdata-dns1.json")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
_, err = Parse(strings.Join([]string{"v=spf1",
|
2019-06-21 19:48:59 +08:00
|
|
|
"redirect=servers.mcsv.net",
|
2019-06-20 01:46:56 +08:00
|
|
|
"~all"}, " "), dnsres)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("should fail")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-21 19:48:59 +08:00
|
|
|
func TestParseRedirectColon(t *testing.T) {
|
|
|
|
// Make sure redirect:foo fails.
|
|
|
|
dnsres, err := NewCache("testdata-dns1.json")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
_, err = Parse(strings.Join([]string{"v=spf1",
|
|
|
|
"redirect:servers.mcsv.net",
|
|
|
|
}, " "), dnsres)
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("should fail")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParseRedirectOnly(t *testing.T) {
|
|
|
|
dnsres, err := NewCache("testdata-dns1.json")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
rec, err := Parse(strings.Join([]string{"v=spf1",
|
|
|
|
"redirect=servers.mcsv.net"}, " "), dnsres)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
t.Log(rec.Print())
|
|
|
|
}
|
|
|
|
|
2019-06-20 01:46:56 +08:00
|
|
|
func TestParseRedirectLast(t *testing.T) {
|
|
|
|
dnsres, err := NewCache("testdata-dns1.json")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
rec, err := Parse(strings.Join([]string{"v=spf1",
|
|
|
|
"ip4:198.252.206.0/24",
|
2019-06-21 19:48:59 +08:00
|
|
|
"redirect=servers.mcsv.net"}, " "), dnsres)
|
2019-06-20 01:46:56 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
t.Log(rec.Print())
|
|
|
|
}
|