136 lines
3.9 KiB
Go
136 lines
3.9 KiB
Go
package checker
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
func TestDiffStringSets(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
want, got []string
|
|
missing, extra []string
|
|
}{
|
|
{
|
|
name: "identical",
|
|
want: []string{"a.example.", "b.example."},
|
|
got: []string{"a.example.", "b.example."},
|
|
missing: nil, extra: nil,
|
|
},
|
|
{
|
|
name: "case and trailing dot are normalized",
|
|
want: []string{"A.Example."},
|
|
got: []string{"a.example"},
|
|
missing: nil, extra: nil,
|
|
},
|
|
{
|
|
name: "missing and extra reported",
|
|
want: []string{"a.example.", "b.example."},
|
|
got: []string{"b.example.", "c.example."},
|
|
missing: []string{"a.example"},
|
|
extra: []string{"c.example"},
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
gotMissing, gotExtra := diffStringSets(tc.want, tc.got)
|
|
if !reflect.DeepEqual(gotMissing, tc.missing) {
|
|
t.Errorf("missing: got %v want %v", gotMissing, tc.missing)
|
|
}
|
|
if !reflect.DeepEqual(gotExtra, tc.extra) {
|
|
t.Errorf("extra: got %v want %v", gotExtra, tc.extra)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsInBailiwick(t *testing.T) {
|
|
cases := []struct {
|
|
host, zone string
|
|
want bool
|
|
}{
|
|
{"ns1.example.com.", "example.com.", true},
|
|
{"ns1.example.com", "example.com", true},
|
|
{"example.com.", "example.com.", true},
|
|
{"ns1.other.com.", "example.com.", false},
|
|
{"ns1.notexample.com.", "example.com.", false}, // suffix-but-not-subdomain trap
|
|
{"NS1.Example.COM", "example.com", true},
|
|
}
|
|
for _, tc := range cases {
|
|
if got := isInBailiwick(tc.host, tc.zone); got != tc.want {
|
|
t.Errorf("isInBailiwick(%q,%q)=%v want %v", tc.host, tc.zone, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHostPort(t *testing.T) {
|
|
cases := []struct {
|
|
host, port, want string
|
|
}{
|
|
{"192.0.2.1", "53", "192.0.2.1:53"},
|
|
{"2001:db8::1", "53", "[2001:db8::1]:53"},
|
|
{"ns1.example.com.", "53", "ns1.example.com:53"},
|
|
}
|
|
for _, tc := range cases {
|
|
if got := hostPort(tc.host, tc.port); got != tc.want {
|
|
t.Errorf("hostPort(%q,%q)=%q want %q", tc.host, tc.port, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNormalizeNSList(t *testing.T) {
|
|
in := []*dns.NS{
|
|
{Ns: "B.example.COM"},
|
|
nil, // must be skipped
|
|
{Ns: "a.example.com."},
|
|
}
|
|
want := []string{"a.example.com.", "b.example.com."}
|
|
got := normalizeNSList(in)
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("normalizeNSList: got %v want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestDiffDS(t *testing.T) {
|
|
a := &dns.DS{KeyTag: 1, Algorithm: 8, DigestType: 2, Digest: "AAAA"}
|
|
b := &dns.DS{KeyTag: 2, Algorithm: 8, DigestType: 2, Digest: "BBBB"}
|
|
c := &dns.DS{KeyTag: 1, Algorithm: 8, DigestType: 2, Digest: "aaaa"} // case-insensitive digest
|
|
|
|
missing, extra := diffDS([]*dns.DS{a, b}, []*dns.DS{c})
|
|
if len(missing) != 1 || missing[0] != b {
|
|
t.Errorf("missing: got %v want [b]", missing)
|
|
}
|
|
if len(extra) != 0 {
|
|
t.Errorf("extra: got %v want []", extra)
|
|
}
|
|
}
|
|
|
|
func TestDSMatchesAnyKey(t *testing.T) {
|
|
// Build a DNSKEY and derive its DS, so we know they match.
|
|
key := &dns.DNSKEY{
|
|
Hdr: dns.RR_Header{Name: "example.com.", Rrtype: dns.TypeDNSKEY, Class: dns.ClassINET},
|
|
Flags: 257,
|
|
Protocol: 3,
|
|
Algorithm: dns.RSASHA256,
|
|
// A throwaway public key; ToDS only needs the wire form to be deterministic.
|
|
PublicKey: "AwEAAcMnWBKLuvG/LwnPVykcmpvnntwxfshHlHRhlY0F3oz8AMcuF8gw" +
|
|
"2Ge56vG9oqVxTzHl4Ss2dEqCQOjFlOVo+pa3JwIO1lUzbQ==",
|
|
}
|
|
matchingDS := key.ToDS(dns.SHA256)
|
|
if matchingDS == nil {
|
|
t.Fatal("could not derive DS from DNSKEY")
|
|
}
|
|
other := &dns.DS{KeyTag: 9999, Algorithm: 99, DigestType: 99, Digest: "DEAD"}
|
|
|
|
if !dsMatchesAnyKey([]*dns.DS{matchingDS, other}, []*dns.DNSKEY{key}) {
|
|
t.Error("expected match between key and its derived DS")
|
|
}
|
|
if dsMatchesAnyKey([]*dns.DS{other}, []*dns.DNSKEY{key}) {
|
|
t.Error("unexpected match against unrelated DS")
|
|
}
|
|
if dsMatchesAnyKey(nil, []*dns.DNSKEY{key}) {
|
|
t.Error("no DS records: must not match")
|
|
}
|
|
}
|