func domainWithNoErrorsOnTheFly() { domain, dnskey, rrsig, lastCheckAt, lastOKAt := generateAndSignDomain("br.") dns.HandleFunc("br.", func(w dns.ResponseWriter, dnsRequestMessage *dns.Msg) { defer w.Close() if dnsRequestMessage.Question[0].Qtype == dns.TypeSOA { dnsResponseMessage := &dns.Msg{ MsgHdr: dns.MsgHdr{ Authoritative: true, }, Question: dnsRequestMessage.Question, Answer: []dns.RR{ &dns.SOA{ Hdr: dns.RR_Header{ Name: "br.", Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: 86400, }, Ns: "ns1.br.", Mbox: "rafael.justo.net.br.", Serial: 2013112600, Refresh: 86400, Retry: 86400, Expire: 86400, Minttl: 900, }, }, } dnsResponseMessage.SetReply(dnsRequestMessage) w.WriteMsg(dnsResponseMessage) } else if dnsRequestMessage.Question[0].Qtype == dns.TypeDNSKEY { dnsResponseMessage := &dns.Msg{ MsgHdr: dns.MsgHdr{ Authoritative: true, }, Question: dnsRequestMessage.Question, Answer: []dns.RR{ dnskey, rrsig, }, } dnsResponseMessage.SetReply(dnsRequestMessage) w.WriteMsg(dnsResponseMessage) } }) scan.ScanDomain(&domain) for _, nameserver := range domain.Nameservers { if nameserver.LastStatus != model.NameserverStatusOK { utils.Fatalln(fmt.Sprintf("Fail to validate a supposedly well configured nameserver '%s'. Found status: %s", nameserver.Host, model.NameserverStatusToString(nameserver.LastStatus)), nil) } if nameserver.LastCheckAt.Before(lastCheckAt) || nameserver.LastCheckAt.Equal(lastCheckAt) { utils.Fatalln(fmt.Sprintf("Last check date was not updated in nameserver '%s'", nameserver.Host), nil) } if nameserver.LastOKAt.Before(lastOKAt) || nameserver.LastOKAt.Equal(lastOKAt) { utils.Fatalln(fmt.Sprintf("Last OK date was not updated in nameserver '%s'", nameserver.Host), nil) } } for _, ds := range domain.DSSet { if ds.LastStatus != model.DSStatusOK { utils.Fatalln(fmt.Sprintf("Fail to validate a supposedly well configured DS %d. "+ "Found status: %s", ds.Keytag, model.DSStatusToString(ds.LastStatus)), nil) } if ds.LastCheckAt.Before(lastCheckAt) || ds.LastCheckAt.Equal(lastCheckAt) { utils.Fatalln(fmt.Sprintf("Last check date was not updated in DS %d", ds.Keytag), nil) } if ds.LastOKAt.Before(lastOKAt) || ds.LastOKAt.Equal(lastOKAt) { utils.Fatalln(fmt.Sprintf("Last OK date was not updated in DS %d", ds.Keytag), nil) } } }
// Put is responsable for checking a domain object on-the-fly without persisting in // database, useful for pre-registration validations in the registry func (h *DomainVerificationHandler) Put(w http.ResponseWriter, r *http.Request) { // We need to set the FQDN in the domain request object because it is sent only in the // URI and not in the domain request body to avoid information redudancy h.Request.FQDN = h.GetFQDN() var domain model.Domain var err error if domain, err = protocol.Merge(domain, h.Request); err != nil { messageId := "" switch err { case protocol.ErrInvalidDNSKEY: messageId = "invalid-dnskey" case protocol.ErrInvalidDSAlgorithm: messageId = "invalid-ds-algorithm" case protocol.ErrInvalidDSDigestType: messageId = "invalid-ds-digest-type" case protocol.ErrInvalidIP: messageId = "invalid-ip" case protocol.ErrInvalidLanguage: messageId = "invalid-language" } if len(messageId) == 0 { log.Println("Error while merging domain objects for domain verification "+ "operation. Details:", err) w.WriteHeader(http.StatusInternalServerError) } else { if err := h.MessageResponse(messageId, r.URL.RequestURI()); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } } return } scan.ScanDomain(&domain) // As we alredy did the scan, if the domain is registered in the system, we update it for this // results. This also gives a more intuitive design for when the user wants to force a check a // specific domain in the Shelter system domainDAO := dao.DomainDAO{ Database: h.GetDatabase(), } if dbDomain, err := domainDAO.FindByFQDN(domain.FQDN); err == nil { update := true // Check if we have the same nameservers, and if so update the last status if len(dbDomain.Nameservers) == len(domain.Nameservers) { for i := range dbDomain.Nameservers { dbNameserver := dbDomain.Nameservers[i] nameserver := domain.Nameservers[i] if dbNameserver.Host == nameserver.Host && dbNameserver.IPv4.Equal(nameserver.IPv4) && dbNameserver.IPv6.Equal(nameserver.IPv6) { dbDomain.Nameservers[i].ChangeStatus(nameserver.LastStatus) } else { update = false break } } } else { update = false } // Check if we have the same DS set, and if so update the last status if len(dbDomain.DSSet) == len(domain.DSSet) { for i := range dbDomain.DSSet { dbDS := dbDomain.DSSet[i] ds := domain.DSSet[i] if dbDS.Keytag == ds.Keytag && dbDS.Algorithm == ds.Algorithm && dbDS.DigestType == ds.DigestType && dbDS.Digest == ds.Digest { dbDomain.DSSet[i].ChangeStatus(ds.LastStatus) } else { update = false break } } } else { update = false } if update { // We don't care about errors resulted here, because the main idea of this service is to scan // a domaion, not persist the results domainDAO.Save(&dbDomain) } } w.WriteHeader(http.StatusOK) domainResponse := protocol.ToDomainResponse(domain, false) h.Response = &domainResponse }