func checkDSs(DSs []*DS, ns *Nameserver, fqdn string) (errs map[string][]string) { if len(ns.Name) == 0 { // Don't need to check DS if the nameserver is empty return } errs = make(map[string][]string) msg := new(dns.Msg) msg.SetQuestion(fqdn, dns.TypeDNSKEY) msg.RecursionDesired = false server := ns.Name if strings.HasSuffix(ns.Name, fqdn) { server = ns.Glue } client := new(dns.Client) response, _, err := client.Exchange(msg, server+":53") if err != nil { log.Printf("Error while querying DNSKEY in %s [%s]. Details: %s", ns.Name, ns.Glue, err.Error()) errs["ds0-keytag"] = append(errs["ds0-keytag"], "Fail to query server "+ns.Name+"!") errs["ds1-keytag"] = append(errs["ds1-keytag"], "Fail to query server "+ns.Name+"!") return } if response.Truncated { client.Net = "tcp" response, _, err = client.Exchange(msg, server+":53") if err != nil { log.Printf("Error while querying DNSKEY in %s [%s]. Details: %s", ns.Name, ns.Glue, err.Error()) errs["ds0-keytag"] = append(errs["ds0-keytag"], "Fail to query server "+ns.Name+"!") errs["ds1-keytag"] = append(errs["ds1-keytag"], "Fail to query server "+ns.Name+"!") return } } ds1 := DSs[0] ds2 := DSs[1] foundDS1 := false foundDS2 := false for _, rr := range response.Answer { if rr.Header().Rrtype == dns.TypeDNSKEY { dnskeyRR := rr.(*dns.DNSKEY) if int(dnskeyRR.KeyTag()) == ds1.KeyTag { foundDS1 = true ds := dnskeyRR.ToDS(ds1.DigestType) if int(ds.Algorithm) != ds1.Algorithm { errs["ds0-algorithm"] = append(errs["ds0-algorithm"], "Algorithm does not match with DNSKEY in "+ns.Name) } else if strings.ToUpper(ds.Digest) != ds1.Digest { errs["ds0-digest"] = append(errs["ds0-digest"], "Digest does not match with DNSKEY in "+ns.Name) } else if dnskeyRR.Flags&dns.SEP == 0 { errs["ds0-keytag"] = append(errs["ds0-keytag"], "DNSKEY is not a SEP in "+ns.Name) } } if int(dnskeyRR.KeyTag()) == ds2.KeyTag { foundDS2 = true ds := dnskeyRR.ToDS(ds2.DigestType) if int(ds.Algorithm) != ds2.Algorithm { errs["ds1-algorithm"] = append(errs["ds1-algorithm"], "Algorithm does not match with DNSKEY in "+ns.Name) } else if strings.ToUpper(ds.Digest) != ds2.Digest { errs["ds1-digest"] = append(errs["ds1-digest"], "Digest does not match with DNSKEY in "+ns.Name) } else if dnskeyRR.Flags&dns.SEP == 0 { errs["ds1-keytag"] = append(errs["ds1-keytag"], "DNSKEY is not a SEP in "+ns.Name) } } } } if !foundDS1 && len(ds1.Digest) > 0 { errs["ds0-keytag"] = append(errs["ds0-keytag"], "Related DNSKEY not found in "+ns.Name) } if !foundDS2 && len(ds2.Digest) > 0 { errs["ds1-keytag"] = append(errs["ds1-keytag"], "Related DNSKEY not found in "+ns.Name) } return }
func retrieveDomains() map[string]*Domain { var domains map[string]*Domain domains = make(map[string]*Domain) client := new(dns.Client) client.TsigSecret = map[string]string{"transfer-key.": "zasDqD5nW1USPh4vhLfDBw=="} client.Net = "tcp" msg := new(dns.Msg) msg.SetAxfr(".") msg.SetTsig("transfer-key.", dns.HmacMD5, 300, time.Now().Unix()) transfer := dns.Transfer{ TsigSecret: map[string]string{"transfer-key.": "zasDqD5nW1USPh4vhLfDBw=="}, } transferChannel, err := transfer.In(msg, "localhost:53") if err != nil { log.Printf("Error retrieving zones: %s", err.Error()) return domains } var glues map[string]string glues = make(map[string]string) for { response, ok := <-transferChannel if !ok { break } if response.Error != nil { log.Printf("Error retrieving zones: %s", response.Error.Error()) return domains } for _, rr := range response.RR { if rr.Header().Name == "." || rr.Header().Name == "music." { continue } if rr.Header().Rrtype == dns.TypeNS { nsRR := rr.(*dns.NS) ns := new(Nameserver) ns.Name = nsRR.Ns domain := domains[rr.Header().Name] if domain == nil { domain = new(Domain) domain.Name = rr.Header().Name } domain.Nameservers = append(domain.Nameservers, ns) domains[rr.Header().Name] = domain } else if rr.Header().Rrtype == dns.TypeDS { dsRR := rr.(*dns.DS) ds := new(DS) ds.KeyTag = int(dsRR.KeyTag) ds.Algorithm = int(dsRR.Algorithm) ds.DigestType = dsRR.DigestType ds.Digest = strings.ToUpper(dsRR.Digest) domain := domains[rr.Header().Name] if domain == nil { domain = new(Domain) domain.Name = rr.Header().Name } domain.DSs = append(domain.DSs, ds) domains[rr.Header().Name] = domain } else if rr.Header().Rrtype == dns.TypeA { aRR := rr.(*dns.A) glues[aRR.Header().Name] = aRR.A.String() } } } for _, domain := range domains { for _, nameserver := range domain.Nameservers { for name, glue := range glues { if nameserver.Name == name { nameserver.Glue = glue } } } } return domains }