diff --git a/middleware/cache/cache_test.go b/middleware/cache/cache_test.go index ab3a14bfb..d4b9752ff 100644 --- a/middleware/cache/cache_test.go +++ b/middleware/cache/cache_test.go @@ -39,6 +39,23 @@ var cacheTestCases = []cacheTestCase{ }, }, }, + { + RecursionAvailable: true, AuthenticatedData: true, Authoritative: true, + Case: test.Case{ + Qname: "mIEK.nL.", Qtype: dns.TypeMX, + Answer: []dns.RR{ + test.MX("mIEK.nL. 3600 IN MX 1 aspmx.l.google.com."), + test.MX("mIEK.nL. 3600 IN MX 10 aspmx2.googlemail.com."), + }, + }, + in: test.Case{ + Qname: "mIEK.nL.", Qtype: dns.TypeMX, + Answer: []dns.RR{ + test.MX("mIEK.nL. 3601 IN MX 1 aspmx.l.google.com."), + test.MX("mIEK.nL. 3601 IN MX 10 aspmx2.googlemail.com."), + }, + }, + }, { Truncated: true, Case: test.Case{ diff --git a/middleware/dnssec/black_lies_test.go b/middleware/dnssec/black_lies_test.go index 092c36f56..22ccac91b 100644 --- a/middleware/dnssec/black_lies_test.go +++ b/middleware/dnssec/black_lies_test.go @@ -39,7 +39,6 @@ func TestZoneSigningBlackLies(t *testing.T) { if nsec.NextDomain != "\\000.ww.miek.nl." { t.Errorf("expected %s, got %s", "\\000.ww.miek.nl.", nsec.NextDomain) } - t.Logf("%+v\n", m) } func testNxdomainMsg() *dns.Msg { diff --git a/middleware/dnssec/dnssec_test.go b/middleware/dnssec/dnssec_test.go index 1b3894204..a3eeec6af 100644 --- a/middleware/dnssec/dnssec_test.go +++ b/middleware/dnssec/dnssec_test.go @@ -52,7 +52,6 @@ func TestZoneSigningDouble(t *testing.T) { if !section(m.Ns, 2) { t.Errorf("authority section should have 1 sig") } - t.Logf("%+v\n", m) } // TestSigningDifferentZone tests if a key for miek.nl and be used for example.org. @@ -73,11 +72,12 @@ func TestSigningDifferentZone(t *testing.T) { m = d.Sign(state, "example.org.", time.Now().UTC()) if !section(m.Answer, 1) { t.Errorf("answer section should have 1 sig") + t.Logf("%+v\n", m) } if !section(m.Ns, 1) { t.Errorf("authority section should have 1 sig") + t.Logf("%+v\n", m) } - t.Logf("%+v\n", m) } func TestSigningCname(t *testing.T) { @@ -91,7 +91,6 @@ func TestSigningCname(t *testing.T) { if !section(m.Answer, 1) { t.Errorf("answer section should have 1 sig") } - t.Logf("%+v\n", m) } func TestZoneSigningDelegation(t *testing.T) { diff --git a/middleware/file/dnssex_test.go b/middleware/file/dnssex_test.go new file mode 100644 index 000000000..d9a0a4568 --- /dev/null +++ b/middleware/file/dnssex_test.go @@ -0,0 +1,145 @@ +package file + +const dbDnssexNLSigned = ` +; File written on Tue Mar 29 21:02:24 2016 +; dnssec_signzone version 9.10.3-P4-Ubuntu +dnssex.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. ( + 1459281744 ; serial + 14400 ; refresh (4 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 14400 ; minimum (4 hours) + ) + 1800 RRSIG SOA 8 2 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + CA/Y3m9hCOiKC/8ieSOv8SeP964BUdG/8MC3 + WtKljUosK9Z9bBGrVizDjjqgq++lyH8BZJcT + aabAsERs4xj5PRtcxicwQXZACX5VYjXHQeZm + CyytFU5wq2gcXSmvUH86zZzftx3RGPvn1aOo + TlcvoC3iF8fYUCpROlUS0YR8Cdw= ) + 1800 NS omval.tednet.nl. + 1800 NS linode.atoom.net. + 1800 NS ns-ext.nlnetlabs.nl. + 1800 RRSIG NS 8 2 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + dLIeEvP86jj5nd3orv9bH7hTvkblF4Na0sbl + k6fJA6ha+FPN1d6Pig3NNEEVQ/+wlOp/JTs2 + v07L7roEEUCbBprI8gMSld2gFDwNLW3DAB4M + WD/oayYdAnumekcLzhgvWixTABjWAGRTGQsP + sVDFXsGMf9TGGC9FEomgkCVeNC0= ) + 1800 A 139.162.196.78 + 1800 RRSIG A 8 2 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + LKJKLzPiSEDWOLAag2YpfD5EJCuDcEAJu+FZ + Xy+4VyOv9YvRHCTL4vbrevOo5+XymY2RxU1q + j+6leR/Fe7nlreSj2wzAAk2bIYn4m6r7hqeO + aKZsUFfpX8cNcFtGEywfHndCPELbRxFeEziP + utqHFLPNMX5nYCpS28w4oJ5sAnM= ) + 1800 TXT "Doing It Safe Is Better" + 1800 RRSIG TXT 8 2 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + f6S+DUfJK1UYdOb3AHgUXzFTTtu+yLp/Fv7S + Hv0CAGhXAVw+nBbK719igFvBtObS33WKwzxD + 1pQNMaJcS6zeevtD+4PKB1KDC4fyJffeEZT6 + E30jGR8Y29/xA+Fa4lqDNnj9zP3b8TiABCle + ascY5abkgWCALLocFAzFJQ/27YQ= ) + 1800 AAAA 2a01:7e00::f03c:91ff:fef1:6735 + 1800 RRSIG AAAA 8 2 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + PWcPSawEUBAfCuv0liEOQ8RYe7tfNW4rubIJ + LE+dbrub1DUer3cWrDoCYFtOufvcbkYJQ2CQ + AGjJmAQ5J2aqYDOPMrKa615V0KT3ifbZJcGC + gkIic4U/EXjaQpRoLdDzR9MyVXOmbA6sKYzj + ju1cNkLqM8D7Uunjl4pIr6rdSFo= ) + 14400 NSEC *.dnssex.nl. A NS SOA TXT AAAA RRSIG NSEC DNSKEY + 14400 RRSIG NSEC 8 2 14400 ( + 20160428190224 20160329190224 14460 dnssex.nl. + oIvM6JZIlNc1aNKGTxv58ApSnDr1nDPPgnD9 + 9oJZRIn7eb5WnpeDz2H3z5+x6Bhlp5hJJaUp + KJ3Ss6Jg/IDnrmIvKmgq6L6gHj1Y1IiHmmU8 + VeZTRzdTsDx/27OsN23roIvsytjveNSEMfIm + iLZ23x5kg1kBdJ9p3xjYHm5lR+8= ) + 1800 DNSKEY 256 3 8 ( + AwEAAazSO6uvLPEVknDA8yxjFe8nnAMU7txp + wb19k55hQ81WV3G4bpBM1NdN6sbYHrkXaTNx + 2bQWAkvX6pz0XFx3z/MPhW+vkakIWFYpyQ7R + AT5LIJfToVfiCDiyhhF0zVobKBInO9eoGjd9 + BAW3TUt+LmNAO/Ak5D5BX7R3CuA7v9k7 + ) ; ZSK; alg = RSASHA256; key id = 14460 + 1800 DNSKEY 257 3 8 ( + AwEAAbyeaV9zg0IqdtgYoqK5jJ239anzwG2i + gvH1DxSazLyaoNvEkCIvPgMLW/JWfy7Z1mQp + SMy9DtzL5pzRyQgw7kIeXLbi6jufUFd9pxN+ + xnzKLf9mY5AcnGToTrbSL+jnMT67wG+c34+Q + PeVfucHNUePBxsbz2+4xbXiViSQyCQGv + ) ; KSK; alg = RSASHA256; key id = 18772 + 1800 RRSIG DNSKEY 8 2 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + cFSFtJE+DBGNxb52AweFaVHBe5Ue5MDpqNdC + TIneUnEhP2m+vK4zJ/TraK0WdQFpsX63pod8 + PZ9y03vHUfewivyonCCBD3DcNdoU9subhN22 + tez9Ct8Z5/9E4RAz7orXal4M1VUEhRcXSEH8 + SJW20mfVsqJAiKqqNeGB/pAj23I= ) + 1800 RRSIG DNSKEY 8 2 1800 ( + 20160428190224 20160329190224 18772 dnssex.nl. + oiiwo/7NYacePqohEp50261elhm6Dieh4j2S + VZGAHU5gqLIQeW9CxKJKtSCkBVgUo4cvO4Rn + 2tzArAuclDvBrMXRIoct8u7f96moeFE+x5FI + DYqICiV6k449ljj9o4t/5G7q2CRsEfxZKpTI + A/L0+uDk0RwVVzL45+TnilcsmZs= ) +*.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better" + 1800 RRSIG TXT 8 2 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + FUZSTyvZfeuuOpCmNzVKOfITRHJ6/ygjmnnb + XGBxVUyQjoLuYXwD5XqZWGw4iKH6QeSDfGCx + 4MPqA4qQmW7Wwth7mat9yMfA4+p2sO84bysl + 7/BG9+W2G+q1uQiM9bX9V42P2X/XuW5Y/t9Y + 8u1sljQ7D8WwS6naH/vbaJxnDBw= ) + 14400 NSEC a.dnssex.nl. TXT RRSIG NSEC + 14400 RRSIG NSEC 8 2 14400 ( + 20160428190224 20160329190224 14460 dnssex.nl. + os6INm6q2eXknD5z8TpfbK00uxVbQefMvHcR + /RNX/kh0xXvzAaaDOV+Ge/Ko+2dXnKP+J1LY + G9ffXNpdbaQy5ygzH5F041GJst4566GdG/jt + 7Z7vLHYxEBTpZfxo+PLsXQXH3VTemZyuWyDf + qJzafXJVH1F0nDrcXmMlR6jlBHA= ) +www.dnssex.nl. 1800 IN CNAME a.dnssex.nl. + 1800 RRSIG CNAME 8 3 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + Omv42q/uVvdNsWQoSrQ6m6w6U7r7Abga7uF4 + 25b3gZlse0C+WyMyGFMGUbapQm7azvBpreeo + uKJHjzd+ufoG+Oul6vU9vyoj+ejgHzGLGbJQ + HftfP+UqP5SWvAaipP/LULTWKPuiBcLDLiBI + PGTfsq0DB6R+qCDTV0fNnkgxEBQ= ) + 14400 NSEC dnssex.nl. CNAME RRSIG NSEC + 14400 RRSIG NSEC 8 3 14400 ( + 20160428190224 20160329190224 14460 dnssex.nl. + TBN3ddfZW+kC84/g3QlNNJMeLZoyCalPQylt + KXXLPGuxfGpl3RYRY8KaHbP+5a8MnHjqjuMB + Lofb7yKMFxpSzMh8E36vnOqry1mvkSakNj9y + 9jM8PwDjcpYUwn/ql76MsmNgEV5CLeQ7lyH4 + AOrL79yOSQVI3JHJIjKSiz88iSw= ) +a.dnssex.nl. 1800 IN A 139.162.196.78 + 1800 RRSIG A 8 3 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + OXHpFj9nSpKi5yA/ULH7MOpGAWfyJ2yC/2xa + Pw0fqSY4QvcRt+V3adcFA4H9+P1b32GpxEjB + lXmCJID+H4lYkhUR4r4IOZBVtKG2SJEBZXip + pH00UkOIBiXxbGzfX8VL04v2G/YxUgLW57kA + aknaeTOkJsO20Y+8wmR9EtzaRFI= ) + 1800 AAAA 2a01:7e00::f03c:91ff:fef1:6735 + 1800 RRSIG AAAA 8 3 1800 ( + 20160428190224 20160329190224 14460 dnssex.nl. + jrepc/VnRzJypnrG0WDEqaAr3HMjWrPxJNX0 + 86gbFjZG07QxBmrA1rj0jM9YEWTjjyWb2tT7 + lQhzKDYX/0XdOVUeeOM4FoSks80V+pWR8fvj + AZ5HmX69g36tLosMDKNR4lXcrpv89QovG4Hr + /r58fxEKEFJqrLDjMo6aOrg+uKA= ) + 14400 NSEC www.dnssex.nl. A AAAA RRSIG NSEC + 14400 RRSIG NSEC 8 3 14400 ( + 20160428190224 20160329190224 14460 dnssex.nl. + S+UM62wXRNNFN3QDWK5YFWUbHBXC4aqaqinZ + A2ZDeC+IQgyw7vazPz7cLI5T0YXXks0HTMlr + soEjKnnRZsqSO9EuUavPNE1hh11Jjm0fB+5+ + +Uro0EmA5Dhgc0Z2VpbXVQEhNDf/pI1gem15 + RffN2tBYNykZn4Has2ySgRaaRYQ= )` diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go index 6a09c7072..9655e08b2 100644 --- a/middleware/file/lookup.go +++ b/middleware/file/lookup.go @@ -44,7 +44,7 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, glue := []dns.RR{} for _, ns := range rrs { if dns.IsSubDomain(ns.Header().Name, ns.(*dns.NS).Ns) { - // even with Do, this should be unsigned. + // Even with Do, this should be unsigned. elem, res := z.Tree.SearchGlue(ns.(*dns.NS).Ns) if res == tree.Found { glue = append(glue, elem.Types(dns.TypeAAAA)...) @@ -55,21 +55,22 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, return nil, rrs, glue, Delegation } - rrs := elem.Types(dns.TypeCNAME) + rrs := elem.Types(dns.TypeCNAME, qname) if len(rrs) > 0 { // should only ever be 1 actually; TODO(miek) check for this? return z.lookupCNAME(rrs, qtype, do) } - rrs = elem.Types(qtype) + rrs = elem.Types(qtype, qname) if len(rrs) == 0 { return z.noData(elem, do) } if do { - sigs := elem.Types(dns.TypeRRSIG) + sigs := elem.Types(dns.TypeRRSIG, qname) sigs = signatureForSubType(sigs, qtype) rrs = append(rrs, sigs...) } + return rrs, nil, nil, Success } @@ -156,6 +157,7 @@ func (z *Zone) lookupCNAME(rrs []dns.RR, qtype uint16, do bool) ([]dns.RR, []dns if elem == nil { return rrs, nil, nil, Success } + targets := cnameForType(elem.All(), qtype) if do { sigs := elem.Types(dns.TypeRRSIG) diff --git a/middleware/file/tree/elem.go b/middleware/file/tree/elem.go index ac913042a..75429c97a 100644 --- a/middleware/file/tree/elem.go +++ b/middleware/file/tree/elem.go @@ -4,7 +4,8 @@ import "github.com/miekg/dns" // Elem is an element in the tree. type Elem struct { - m map[uint16][]dns.RR + m map[uint16][]dns.RR + name string // owner name } // newElem returns a new elem. @@ -14,13 +15,20 @@ func newElem(rr dns.RR) *Elem { return &e } -// Types returns the RRs with type qtype from e. -func (e *Elem) Types(qtype uint16) []dns.RR { - if rrs, ok := e.m[qtype]; ok { - return rrs +// Types returns the RRs with type qtype from e. If qname is given (only the +// first one is used), the RR are copied and the owner is replaced with qname[0]. +func (e *Elem) Types(qtype uint16, qname ...string) []dns.RR { + rrs := e.m[qtype] + + if rrs != nil && len(qname) > 0 { + copied := make([]dns.RR, len(rrs)) + for i := range rrs { + copied[i] = dns.Copy(rrs[i]) + copied[i].Header().Name = qname[0] + } + return copied } - // nodata - return nil + return rrs } // All returns all RRs from e, regardless of type. @@ -34,12 +42,25 @@ func (e *Elem) All() []dns.RR { // Name returns the name for this node. func (e *Elem) Name() string { + if e.name != "" { + return e.name + } for _, rrs := range e.m { - return rrs[0].Header().Name + e.name = rrs[0].Header().Name + return e.name } return "" } +// Wildcard returns true if this name starts with a wildcard label (*.) +func (e *Elem) IsWildcard() bool { + n := e.Name() + if len(n) < 2 { + return false + } + return n[0] == '*' && n[1] == '.' +} + // Insert inserts rr into e. If rr is equal to existing rrs this is a noop. func (e *Elem) Insert(rr dns.RR) { t := rr.Header().Rrtype diff --git a/middleware/file/tree/tree.go b/middleware/file/tree/tree.go index 0e2171cf5..668c19734 100644 --- a/middleware/file/tree/tree.go +++ b/middleware/file/tree/tree.go @@ -179,12 +179,22 @@ func (t *Tree) SearchGlue(qname string) (*Elem, Result) { } // search searches the tree for qname and type. If glue is true the search *does* not -// spot when hitting NS records, but descends in search of glue. The qtype for this +// stop when hitting NS records, but descends in search of glue. The qtype for this // kind of search can only be AAAA or A. func (n *Node) search(qname string, qtype uint16, glue bool) (*Node, Result) { old := n + + var wild *Node + for n != nil { + // Is this a wildcard that applies to us + if n.Elem.IsWildcard() { + if dns.IsSubDomain(n.Elem.Name()[2:], qname) { + wild = n + } + } + switch c := Less(n.Elem, qname); { case c == 0: return n, Found @@ -200,6 +210,13 @@ func (n *Node) search(qname string, qtype uint16, glue bool) (*Node, Result) { n = n.Right } } + + // If we have seen a wildcard "on-the-way-to-here", we should return this wildcard + // instead. This is to be able to have a more specific RR defined *under* the wildcard. + if wild != nil { + return wild, Found + } + if dns.CountLabel(qname) < dns.CountLabel(old.Elem.Name()) { return n, EmptyNonTerminal } diff --git a/middleware/file/wildcard_test.go b/middleware/file/wildcard_test.go index 847275ffc..5e7251d88 100644 --- a/middleware/file/wildcard_test.go +++ b/middleware/file/wildcard_test.go @@ -19,6 +19,12 @@ var wildcardTestCases = []test.Case{ test.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`), }, }, + { + Qname: "a.wild.dnssex.nl.", Qtype: dns.TypeTXT, + Answer: []dns.RR{ + test.TXT(`a.wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`), + }, + }, { Qname: "wild.dnssex.nl.", Qtype: dns.TypeTXT, Do: true, Answer: []dns.RR{ @@ -27,22 +33,31 @@ var wildcardTestCases = []test.Case{ }, Extra: []dns.RR{test.OPT(4096, true)}, }, - // nodata reponse - /* - { - Qname: "wild.dnssex.nl.", Qtype: dns.TypeSRV, - Answer: []dns.RR{ - test.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`), - }, + { + Qname: "a.wild.dnssex.nl.", Qtype: dns.TypeTXT, Do: true, + Answer: []dns.RR{ + test.RRSIG("a.wild.dnssex.nl. 1800 IN RRSIG TXT 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. FUZSTyvZfeuuOpCm"), + test.TXT(`a.wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`), }, - { - Qname: "wild.dnssex.nl.", Qtype: dns.TypeSRV, Do: true, - Answer: []dns.RR{ - test.RRSIG("wild.dnssex.nl. 1800 IN RRSIG TXT 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. FUZSTyvZfeuuOpCm"), - test.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`), - }, + Extra: []dns.RR{test.OPT(4096, true)}, + }, + // nodata responses + { + Qname: "wild.dnssex.nl.", Qtype: dns.TypeSRV, + Ns: []dns.RR{ + test.SOA(`dnssex.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1459281744 14400 3600 604800 14400`), }, - */ + }, + { + Qname: "wild.dnssex.nl.", Qtype: dns.TypeSRV, Do: true, + Ns: []dns.RR{ + test.NSEC(`*.dnssex.nl. 14400 IN NSEC a.dnssex.nl. TXT RRSIG NSEC`), + test.RRSIG(`*.dnssex.nl. 14400 IN RRSIG NSEC 8 2 14400 20160428190224 20160329190224 14460 dnssex.nl. os6INm6q2eXknD5z8TpfbK00uxVbQefMvHcR/RNX/kh0xXvzAaaDOV+Ge/Ko+2dXnKP+J1LYG9ffXNpdbaQy5ygzH5F041GJst4566GdG/jt7Z7vLHYxEBTpZfxo+PLsXQXH3VTemZyuWyDfqJzafXJVH1F0nDrcXmMlR6jlBHA=`), + test.RRSIG(`dnssex.nl. 1800 IN RRSIG SOA 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. CA/Y3m9hCOiKC/8ieSOv8SeP964BUdG/8MC3WtKljUosK9Z9bBGrVizDjjqgq++lyH8BZJcTaabAsERs4xj5PRtcxicwQXZACX5VYjXHQeZmCyytFU5wq2gcXSmvUH86zZzftx3RGPvn1aOoTlcvoC3iF8fYUCpROlUS0YR8Cdw=`), + test.SOA(`dnssex.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1459281744 14400 3600 604800 14400`), + }, + Extra: []dns.RR{test.OPT(4096, true)}, + }, } func TestLookupWildcard(t *testing.T) { @@ -85,146 +100,83 @@ func TestLookupWildcard(t *testing.T) { } } -const dbDnssexNLSigned = ` -; File written on Tue Mar 29 21:02:24 2016 -; dnssec_signzone version 9.10.3-P4-Ubuntu -dnssex.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. ( - 1459281744 ; serial - 14400 ; refresh (4 hours) - 3600 ; retry (1 hour) - 604800 ; expire (1 week) - 14400 ; minimum (4 hours) - ) - 1800 RRSIG SOA 8 2 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - CA/Y3m9hCOiKC/8ieSOv8SeP964BUdG/8MC3 - WtKljUosK9Z9bBGrVizDjjqgq++lyH8BZJcT - aabAsERs4xj5PRtcxicwQXZACX5VYjXHQeZm - CyytFU5wq2gcXSmvUH86zZzftx3RGPvn1aOo - TlcvoC3iF8fYUCpROlUS0YR8Cdw= ) - 1800 NS omval.tednet.nl. - 1800 NS linode.atoom.net. - 1800 NS ns-ext.nlnetlabs.nl. - 1800 RRSIG NS 8 2 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - dLIeEvP86jj5nd3orv9bH7hTvkblF4Na0sbl - k6fJA6ha+FPN1d6Pig3NNEEVQ/+wlOp/JTs2 - v07L7roEEUCbBprI8gMSld2gFDwNLW3DAB4M - WD/oayYdAnumekcLzhgvWixTABjWAGRTGQsP - sVDFXsGMf9TGGC9FEomgkCVeNC0= ) - 1800 A 139.162.196.78 - 1800 RRSIG A 8 2 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - LKJKLzPiSEDWOLAag2YpfD5EJCuDcEAJu+FZ - Xy+4VyOv9YvRHCTL4vbrevOo5+XymY2RxU1q - j+6leR/Fe7nlreSj2wzAAk2bIYn4m6r7hqeO - aKZsUFfpX8cNcFtGEywfHndCPELbRxFeEziP - utqHFLPNMX5nYCpS28w4oJ5sAnM= ) - 1800 TXT "Doing It Safe Is Better" - 1800 RRSIG TXT 8 2 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - f6S+DUfJK1UYdOb3AHgUXzFTTtu+yLp/Fv7S - Hv0CAGhXAVw+nBbK719igFvBtObS33WKwzxD - 1pQNMaJcS6zeevtD+4PKB1KDC4fyJffeEZT6 - E30jGR8Y29/xA+Fa4lqDNnj9zP3b8TiABCle - ascY5abkgWCALLocFAzFJQ/27YQ= ) - 1800 AAAA 2a01:7e00::f03c:91ff:fef1:6735 - 1800 RRSIG AAAA 8 2 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - PWcPSawEUBAfCuv0liEOQ8RYe7tfNW4rubIJ - LE+dbrub1DUer3cWrDoCYFtOufvcbkYJQ2CQ - AGjJmAQ5J2aqYDOPMrKa615V0KT3ifbZJcGC - gkIic4U/EXjaQpRoLdDzR9MyVXOmbA6sKYzj - ju1cNkLqM8D7Uunjl4pIr6rdSFo= ) - 14400 NSEC *.dnssex.nl. A NS SOA TXT AAAA RRSIG NSEC DNSKEY - 14400 RRSIG NSEC 8 2 14400 ( - 20160428190224 20160329190224 14460 dnssex.nl. - oIvM6JZIlNc1aNKGTxv58ApSnDr1nDPPgnD9 - 9oJZRIn7eb5WnpeDz2H3z5+x6Bhlp5hJJaUp - KJ3Ss6Jg/IDnrmIvKmgq6L6gHj1Y1IiHmmU8 - VeZTRzdTsDx/27OsN23roIvsytjveNSEMfIm - iLZ23x5kg1kBdJ9p3xjYHm5lR+8= ) - 1800 DNSKEY 256 3 8 ( - AwEAAazSO6uvLPEVknDA8yxjFe8nnAMU7txp - wb19k55hQ81WV3G4bpBM1NdN6sbYHrkXaTNx - 2bQWAkvX6pz0XFx3z/MPhW+vkakIWFYpyQ7R - AT5LIJfToVfiCDiyhhF0zVobKBInO9eoGjd9 - BAW3TUt+LmNAO/Ak5D5BX7R3CuA7v9k7 - ) ; ZSK; alg = RSASHA256; key id = 14460 - 1800 DNSKEY 257 3 8 ( - AwEAAbyeaV9zg0IqdtgYoqK5jJ239anzwG2i - gvH1DxSazLyaoNvEkCIvPgMLW/JWfy7Z1mQp - SMy9DtzL5pzRyQgw7kIeXLbi6jufUFd9pxN+ - xnzKLf9mY5AcnGToTrbSL+jnMT67wG+c34+Q - PeVfucHNUePBxsbz2+4xbXiViSQyCQGv - ) ; KSK; alg = RSASHA256; key id = 18772 - 1800 RRSIG DNSKEY 8 2 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - cFSFtJE+DBGNxb52AweFaVHBe5Ue5MDpqNdC - TIneUnEhP2m+vK4zJ/TraK0WdQFpsX63pod8 - PZ9y03vHUfewivyonCCBD3DcNdoU9subhN22 - tez9Ct8Z5/9E4RAz7orXal4M1VUEhRcXSEH8 - SJW20mfVsqJAiKqqNeGB/pAj23I= ) - 1800 RRSIG DNSKEY 8 2 1800 ( - 20160428190224 20160329190224 18772 dnssex.nl. - oiiwo/7NYacePqohEp50261elhm6Dieh4j2S - VZGAHU5gqLIQeW9CxKJKtSCkBVgUo4cvO4Rn - 2tzArAuclDvBrMXRIoct8u7f96moeFE+x5FI - DYqICiV6k449ljj9o4t/5G7q2CRsEfxZKpTI - A/L0+uDk0RwVVzL45+TnilcsmZs= ) -*.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better" - 1800 RRSIG TXT 8 2 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - FUZSTyvZfeuuOpCmNzVKOfITRHJ6/ygjmnnb - XGBxVUyQjoLuYXwD5XqZWGw4iKH6QeSDfGCx - 4MPqA4qQmW7Wwth7mat9yMfA4+p2sO84bysl - 7/BG9+W2G+q1uQiM9bX9V42P2X/XuW5Y/t9Y - 8u1sljQ7D8WwS6naH/vbaJxnDBw= ) - 14400 NSEC a.dnssex.nl. TXT RRSIG NSEC - 14400 RRSIG NSEC 8 2 14400 ( - 20160428190224 20160329190224 14460 dnssex.nl. - os6INm6q2eXknD5z8TpfbK00uxVbQefMvHcR - /RNX/kh0xXvzAaaDOV+Ge/Ko+2dXnKP+J1LY - G9ffXNpdbaQy5ygzH5F041GJst4566GdG/jt - 7Z7vLHYxEBTpZfxo+PLsXQXH3VTemZyuWyDf - qJzafXJVH1F0nDrcXmMlR6jlBHA= ) -www.dnssex.nl. 1800 IN CNAME a.dnssex.nl. - 1800 RRSIG CNAME 8 3 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - Omv42q/uVvdNsWQoSrQ6m6w6U7r7Abga7uF4 - 25b3gZlse0C+WyMyGFMGUbapQm7azvBpreeo - uKJHjzd+ufoG+Oul6vU9vyoj+ejgHzGLGbJQ - HftfP+UqP5SWvAaipP/LULTWKPuiBcLDLiBI - PGTfsq0DB6R+qCDTV0fNnkgxEBQ= ) - 14400 NSEC dnssex.nl. CNAME RRSIG NSEC - 14400 RRSIG NSEC 8 3 14400 ( - 20160428190224 20160329190224 14460 dnssex.nl. - TBN3ddfZW+kC84/g3QlNNJMeLZoyCalPQylt - KXXLPGuxfGpl3RYRY8KaHbP+5a8MnHjqjuMB - Lofb7yKMFxpSzMh8E36vnOqry1mvkSakNj9y - 9jM8PwDjcpYUwn/ql76MsmNgEV5CLeQ7lyH4 - AOrL79yOSQVI3JHJIjKSiz88iSw= ) -a.dnssex.nl. 1800 IN A 139.162.196.78 - 1800 RRSIG A 8 3 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - OXHpFj9nSpKi5yA/ULH7MOpGAWfyJ2yC/2xa - Pw0fqSY4QvcRt+V3adcFA4H9+P1b32GpxEjB - lXmCJID+H4lYkhUR4r4IOZBVtKG2SJEBZXip - pH00UkOIBiXxbGzfX8VL04v2G/YxUgLW57kA - aknaeTOkJsO20Y+8wmR9EtzaRFI= ) - 1800 AAAA 2a01:7e00::f03c:91ff:fef1:6735 - 1800 RRSIG AAAA 8 3 1800 ( - 20160428190224 20160329190224 14460 dnssex.nl. - jrepc/VnRzJypnrG0WDEqaAr3HMjWrPxJNX0 - 86gbFjZG07QxBmrA1rj0jM9YEWTjjyWb2tT7 - lQhzKDYX/0XdOVUeeOM4FoSks80V+pWR8fvj - AZ5HmX69g36tLosMDKNR4lXcrpv89QovG4Hr - /r58fxEKEFJqrLDjMo6aOrg+uKA= ) - 14400 NSEC www.dnssex.nl. A AAAA RRSIG NSEC - 14400 RRSIG NSEC 8 3 14400 ( - 20160428190224 20160329190224 14460 dnssex.nl. - S+UM62wXRNNFN3QDWK5YFWUbHBXC4aqaqinZ - A2ZDeC+IQgyw7vazPz7cLI5T0YXXks0HTMlr - soEjKnnRZsqSO9EuUavPNE1hh11Jjm0fB+5+ - +Uro0EmA5Dhgc0Z2VpbXVQEhNDf/pI1gem15 - RffN2tBYNykZn4Has2ySgRaaRYQ= )` +var wildcardDoubleTestCases = []test.Case{ + { + Qname: "wild.w.example.org.", Qtype: dns.TypeTXT, + Answer: []dns.RR{ + test.TXT(`wild.w.example.org. IN TXT "Wildcard"`), + }, + }, + { + Qname: "wild.c.example.org.", Qtype: dns.TypeTXT, + Answer: []dns.RR{ + test.TXT(`wild.c.example.org. IN TXT "c Wildcard"`), + }, + }, + { + Qname: "wild.d.example.org.", Qtype: dns.TypeTXT, + Answer: []dns.RR{ + test.TXT(`alias.example.org. IN TXT "Wildcard CNAME expansion"`), + test.CNAME(`wild.d.example.org. IN CNAME alias.example.org`), + }, + }, + { + Qname: "alias.example.org.", Qtype: dns.TypeTXT, + Answer: []dns.RR{ + test.TXT(`alias.example.org. IN TXT "Wildcard CNAME expansion"`), + }, + }, +} + +func TestLookupDoubleWildcard(t *testing.T) { + zone, err := Parse(strings.NewReader(exampleOrg), "example.org.", "stdin") + if err != nil { + t.Fatalf("expect no error when reading zone, got %q", err) + } + + fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{"example.org.": zone}, Names: []string{"example.org."}}} + ctx := context.TODO() + + for _, tc := range wildcardDoubleTestCases { + m := tc.Msg() + + rec := dnsrecorder.New(&test.ResponseWriter{}) + _, err := fm.ServeDNS(ctx, rec, m) + if err != nil { + t.Errorf("expected no error, got %v\n", err) + return + } + + resp := rec.Msg + sort.Sort(test.RRSet(resp.Answer)) + sort.Sort(test.RRSet(resp.Ns)) + sort.Sort(test.RRSet(resp.Extra)) + + if !test.Header(t, tc, resp) { + t.Logf("%v\n", resp) + continue + } + if !test.Section(t, tc, test.Answer, resp.Answer) { + t.Logf("%v\n", resp) + } + if !test.Section(t, tc, test.Ns, resp.Ns) { + t.Logf("%v\n", resp) + } + if !test.Section(t, tc, test.Extra, resp.Extra) { + t.Logf("%v\n", resp) + } + } +} + +const exampleOrg = `; example.org test file +example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600 +example.org. IN NS b.iana-servers.net. +example.org. IN NS a.iana-servers.net. +example.org. IN A 127.0.0.1 +example.org. IN A 127.0.0.2 +*.w.example.org. IN TXT "Wildcard" +a.b.c.w.example.org. IN TXT "Not a wildcard" +*.c.example.org. IN TXT "c Wildcard" +*.d.example.org. IN CNAME alias.example.org. +alias.example.org. IN TXT "Wildcard CNAME expansion" +` diff --git a/middleware/kubernetes/setup_test.go b/middleware/kubernetes/setup_test.go index 6e0918a3b..5d2154350 100644 --- a/middleware/kubernetes/setup_test.go +++ b/middleware/kubernetes/setup_test.go @@ -319,12 +319,9 @@ func TestKubernetesParse(t *testing.T) { }, } - t.Logf("Parser test cases count: %v", len(tests)) for i, test := range tests { c := caddy.NewTestController("dns", test.input) k8sController, err := kubernetesParse(c) - t.Logf("setup test: %2v -- %v\n", i, test.description) - //t.Logf("controller: %v\n", k8sController) if test.shouldErr && err == nil { t.Errorf("Test %d: Expected error, but did not find error for input '%s'. Error was: '%v'", i, test.input, err) diff --git a/middleware/whoami/whoami_test.go b/middleware/whoami/whoami_test.go index a143185ef..f5376bde1 100644 --- a/middleware/whoami/whoami_test.go +++ b/middleware/whoami/whoami_test.go @@ -42,8 +42,6 @@ func TestWhoami(t *testing.T) { rec := dnsrecorder.New(&test.ResponseWriter{}) code, err := wh.ServeDNS(ctx, rec, req) - t.Logf("%s\n", rec.Msg) - if err != tc.expectedErr { t.Errorf("Test %d: Expected error %v, but got %v", i, tc.expectedErr, err) } diff --git a/test/example_test.go b/test/example_test.go new file mode 100644 index 000000000..5b6df9dcc --- /dev/null +++ b/test/example_test.go @@ -0,0 +1,11 @@ +package test + +const exampleOrg = `; example.org test file +example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600 +example.org. IN NS b.iana-servers.net. +example.org. IN NS a.iana-servers.net. +example.org. IN A 127.0.0.1 +example.org. IN A 127.0.0.2 +*.w.example.org. IN TXT "Wildcard" +a.b.c.w.example.org. IN TXT "Not a wildcard" +` diff --git a/test/proxy_test.go b/test/proxy_test.go index 15e3ccdcd..b8765ef10 100644 --- a/test/proxy_test.go +++ b/test/proxy_test.go @@ -12,14 +12,6 @@ import ( "github.com/miekg/dns" ) -const exampleOrg = `; example.org test file -example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600 -example.org. IN NS b.iana-servers.net. -example.org. IN NS a.iana-servers.net. -example.org. IN A 127.0.0.1 -example.org. IN A 127.0.0.2 -` - func TestLookupProxy(t *testing.T) { name, rm, err := test.TempFile(".", exampleOrg) if err != nil { diff --git a/test/wildcard_test.go b/test/wildcard_test.go new file mode 100644 index 000000000..05a1b94f8 --- /dev/null +++ b/test/wildcard_test.go @@ -0,0 +1,100 @@ +package test + +import ( + "io/ioutil" + "log" + "testing" + + "github.com/miekg/coredns/middleware/proxy" + "github.com/miekg/coredns/middleware/test" + "github.com/miekg/coredns/request" + + "github.com/miekg/dns" +) + +func TestLookupWildcard(t *testing.T) { + name, rm, err := test.TempFile(".", exampleOrg) + if err != nil { + t.Fatalf("failed to created zone: %s", err) + } + defer rm() + + corefile := `example.org:0 { + file ` + name + ` +} +` + + i, err := CoreDNSServer(corefile) + if err != nil { + t.Fatalf("Could not get CoreDNS serving instance: %s", err) + } + + udp, _ := CoreDNSServerPorts(i, 0) + if udp == "" { + t.Fatalf("Could not get UDP listening port") + } + defer i.Stop() + + log.SetOutput(ioutil.Discard) + + p := proxy.New([]string{udp}) + state := request.Request{W: &test.ResponseWriter{}, Req: new(dns.Msg)} + + for _, lookup := range []string{"w.example.org.", "a.w.example.org.", "a.a.w.example.org."} { + resp, err := p.Lookup(state, lookup, dns.TypeTXT) + if err != nil || resp == nil { + t.Fatal("Expected to receive reply, but didn't for %s", lookup) + } + + // ;; ANSWER SECTION: + // a.w.example.org. 1800 IN TXT "Wildcard" + if resp.Rcode != dns.RcodeSuccess { + t.Errorf("Expected NOERROR RCODE, got %s for %s", dns.RcodeToString[resp.Rcode], lookup) + continue + } + if len(resp.Answer) == 0 { + t.Errorf("Expected to at least one RR in the answer section, got none for %s TXT", lookup) + t.Logf("%s", resp) + continue + } + if resp.Answer[0].Header().Name != lookup { + t.Errorf("Expected name to be %s, got: %s for TXT", lookup, resp.Answer[0].Header().Name) + continue + } + if resp.Answer[0].Header().Rrtype != dns.TypeTXT { + t.Errorf("Expected RR to be TXT, got: %d, for %s TXT", resp.Answer[0].Header().Rrtype, lookup) + continue + } + if resp.Answer[0].(*dns.TXT).Txt[0] != "Wildcard" { + t.Errorf("Expected Wildcard, got: %s, for %s TXT", resp.Answer[0].(*dns.TXT).Txt[0], lookup) + continue + } + } + + for _, lookup := range []string{"w.example.org.", "a.w.example.org.", "a.a.w.example.org."} { + resp, err := p.Lookup(state, lookup, dns.TypeSRV) + if err != nil || resp == nil { + t.Fatal("Expected to receive reply, but didn't", lookup) + } + + // ;; AUTHORITY SECTION: + // example.org. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1454960557 14400 3600 604800 14400 + if resp.Rcode != dns.RcodeSuccess { + t.Errorf("Expected NOERROR RCODE, got %s for %s", dns.RcodeToString[resp.Rcode], lookup) + continue + } + if len(resp.Answer) != 0 { + t.Errorf("Expected zero RRs in the answer section, got some, for %s SRV", lookup) + continue + } + if len(resp.Ns) == 0 { + t.Errorf("Expected to at least one RR in the authority section, got none, for %s SRV", lookup) + continue + } + if resp.Ns[0].Header().Rrtype != dns.TypeSOA { + t.Errorf("Expected RR to be SOA, got: %d, for %s SRV", resp.Ns[0].Header().Rrtype, lookup) + continue + } + } + +}