Merge branch 'master' of github.com:miekg/dns
This commit is contained in:
commit
c37493cbbf
36
defaults.go
36
defaults.go
|
@ -1,5 +1,12 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const hexDigit = "0123456789abcdef"
|
||||
|
||||
// Everything is assumed in the ClassINET class. If
|
||||
// you need other classes you are on your own.
|
||||
|
||||
|
@ -311,3 +318,32 @@ func Fqdn(s string) string {
|
|||
}
|
||||
return s + "."
|
||||
}
|
||||
|
||||
// Copied from the official Go code
|
||||
|
||||
// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
|
||||
// address addr suitable for rDNS (PTR) record lookup or an error if it fails
|
||||
// to parse the IP address.
|
||||
func ReverseAddr(addr string) (arpa string, err error) {
|
||||
ip := net.ParseIP(addr)
|
||||
if ip == nil {
|
||||
return "", &Error{Err: "unrecognized address", Name: addr}
|
||||
}
|
||||
if ip.To4() != nil {
|
||||
return strconv.Itoa(int(ip[15])) + "." + strconv.Itoa(int(ip[14])) + "." + strconv.Itoa(int(ip[13])) + "." +
|
||||
strconv.Itoa(int(ip[12])) + ".in-addr.arpa.", nil
|
||||
}
|
||||
// Must be IPv6
|
||||
buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
|
||||
// Add it, in reverse, to the buffer
|
||||
for i := len(ip) - 1; i >= 0; i-- {
|
||||
v := ip[i]
|
||||
buf = append(buf, hexDigit[v&0xF])
|
||||
buf = append(buf, '.')
|
||||
buf = append(buf, hexDigit[v>>4])
|
||||
buf = append(buf, '.')
|
||||
}
|
||||
// Append "ip6.arpa." and return (buf already has the final .)
|
||||
buf = append(buf, "ip6.arpa."...)
|
||||
return string(buf), nil
|
||||
}
|
||||
|
|
199
lookup.go
199
lookup.go
|
@ -1,199 +0,0 @@
|
|||
package dns
|
||||
|
||||
// This file is in flux
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SecurityStatus int
|
||||
|
||||
const (
|
||||
SECURE SecurityStatus = iota
|
||||
INSECURE
|
||||
BOGUS
|
||||
INDETERMINATE
|
||||
)
|
||||
|
||||
// Check if the returned message has a delegation signer record
|
||||
// Algo:
|
||||
// The auth section's owner name (should be all equal) - seperate check!
|
||||
// The ownername of the DS records must match the right side of the qname
|
||||
//
|
||||
func AssertDelegationSigner(m *Msg, trustdb []*RR_DNSKEY) error {
|
||||
|
||||
// look for the DS(s)
|
||||
dss := make([]*RR_DS, 0)
|
||||
// If there are ddssen, there should also be a SIG (what if not?)
|
||||
var sig *RR_RRSIG
|
||||
for _, r := range m.Ns {
|
||||
if d, ok := r.(*RR_DS); ok {
|
||||
dss = append(dss, d)
|
||||
continue
|
||||
}
|
||||
if s, ok := r.(*RR_RRSIG); ok {
|
||||
if s.TypeCovered == TypeDS {
|
||||
sig = s
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(dss) == 0 {
|
||||
// No DSs found ...
|
||||
return nil
|
||||
}
|
||||
println("DSs found", len(dss))
|
||||
if sig == nil {
|
||||
// No SIG found ...
|
||||
return nil
|
||||
}
|
||||
println("SIG found")
|
||||
|
||||
// Ownername of the DSs should match the qname
|
||||
if CompareLabels(dss[0].Header().Name, m.Question[0].Name) == 0 {
|
||||
// No match
|
||||
}
|
||||
// Optionally keep track of these comparison, it should increase
|
||||
println("Match found between delegation DS and qname")
|
||||
println(dss[0].String())
|
||||
println(sig.String())
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Types of answers (without looking the RFCs)
|
||||
// len(m.Ns) > 0
|
||||
// NS records in there? -> delegation (rcode should be rcode.Success)
|
||||
// - secure delegation -> DS should be there
|
||||
// - insecure delegation -> Proof of no DS (either NSEC or NSEC3)
|
||||
// - plain old DNS delegation -> ...
|
||||
// SOA record in there? -> nxdomain (rcode should be rcode.Nxdomain)
|
||||
|
||||
// Lookup does a (secure) DNS lookup. The message m contains
|
||||
// the question to be asked. Lookup returns last packet seen
|
||||
// which is either the answer or a packet somewhere in the
|
||||
// tree where the error occured.
|
||||
// TODO: check return code - see unbound for what we want
|
||||
//
|
||||
func Lookup(m *Msg) (*Msg, error) {
|
||||
|
||||
// This is actually what needs to be done when parsing packets too
|
||||
a, aaaa := primingZone()
|
||||
ds := primingTrust()
|
||||
for i, r := range a {
|
||||
println(i, r)
|
||||
}
|
||||
for i, r := range aaaa {
|
||||
println(i, r)
|
||||
}
|
||||
for i, r := range ds {
|
||||
println(i, r.String())
|
||||
}
|
||||
c := new(Client)
|
||||
a1 := randomAddress(a)
|
||||
println(a1)
|
||||
n, _, _, e := c.ExchangeRtt(m, a1+":53")
|
||||
if e == nil {
|
||||
println(n.String())
|
||||
} else {
|
||||
println(e.Error())
|
||||
return nil, e
|
||||
}
|
||||
// n is our reply, deal with it
|
||||
// Check for DS
|
||||
// Check for DS absent (NSEC/NSEC3)
|
||||
if len(n.Ns) > 0 && len(n.Answer) == 0 && n.Rcode == RcodeSuccess { // Referral
|
||||
// the ns name of the nameservers should match the right most labels. Check the answer
|
||||
println("Referral")
|
||||
for i, j := range addrFromReferral4(n) {
|
||||
println(i, j)
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Parse a referral packet and return two lists (v4 and v6) of
|
||||
// ip addresses to try next. As the NS records in a referral
|
||||
// are not signed (the belong to the child), no validation takes
|
||||
// place at this step.
|
||||
func parseReferral(m *Msg) ([]*RR_A, []*RR_AAAA) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Parse the builtin root zone and return two lists (v4 and v6) of
|
||||
// ip addresses to try.
|
||||
// Glue checking this is -- should be done much nicer/better
|
||||
func primingZone() (a, aaaa []string) {
|
||||
nss := make(map[string]bool) // List of ns names
|
||||
// Walk the records, get each NS for . and look for the addresses
|
||||
for rr := range ParseZone(strings.NewReader(NamedRoot), "", "named.root") {
|
||||
if rr.RR.Header().Name == "." && rr.RR.Header().Rrtype == TypeNS {
|
||||
nss[rr.RR.(*RR_NS).Ns] = true
|
||||
continue
|
||||
}
|
||||
if rr.RR.Header().Rrtype == TypeA {
|
||||
for n, _ := range nss {
|
||||
if rr.RR.Header().Name == n {
|
||||
a = append(a, rr.RR.(*RR_A).A.String())
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if rr.RR.Header().Rrtype == TypeAAAA {
|
||||
for n, _ := range nss {
|
||||
if rr.RR.Header().Name == n {
|
||||
aaaa = append(aaaa, rr.RR.(*RR_AAAA).AAAA.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Randomize
|
||||
return
|
||||
}
|
||||
|
||||
// Validate the root key with the DS records we've gotten offline
|
||||
func createTrustDB(dss []*RR_DS, a, aaaa []string) *[]RR_DNSKEY {
|
||||
// Query a root server, get the DNSKEY, toDS() and check
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Parse the builtin trust anchor and return the DS records
|
||||
func primingTrust() []*RR_DS {
|
||||
ta, _ := ReadTrustAnchor(strings.NewReader(RootAnchorXML))
|
||||
// Don't care about validity just yet
|
||||
dss := make([]*RR_DS, 0)
|
||||
for _, t := range ta {
|
||||
dss = append(dss, t.Anchor)
|
||||
}
|
||||
return dss
|
||||
}
|
||||
|
||||
func randomAddress(list []string) string {
|
||||
rand.Seed(int64(time.Now().Nanosecond()))
|
||||
if len(list) == 0 {
|
||||
return ""
|
||||
}
|
||||
return list[rand.Intn(len(list))]
|
||||
}
|
||||
|
||||
// Pull the addresses out of the referral message
|
||||
// Check the zone
|
||||
func addrFromReferral4(m *Msg) (addr []string) {
|
||||
for _, ns := range m.Ns {
|
||||
if ns.Header().Rrtype != TypeNS {
|
||||
continue
|
||||
}
|
||||
for _, a := range m.Extra {
|
||||
if a.Header().Rrtype != TypeA {
|
||||
continue
|
||||
}
|
||||
if ns.(*RR_NS).Ns == a.Header().Name {
|
||||
addr = append(addr, a.(*RR_A).A.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue