// FindZoneByFqdn determines the zone of the given fqdn func FindZoneByFqdn(fqdn, nameserver string) (string, error) { // Do we have it cached? if zone, ok := fqdnToZone[fqdn]; ok { return zone, nil } // Query the authoritative nameserver for a hopefully non-existing SOA record, // in the authority section of the reply it will have the SOA of the // containing zone. rfc2308 has this to say on the subject: // Name servers authoritative for a zone MUST include the SOA record of // the zone in the authority section of the response when reporting an // NXDOMAIN or indicating that no data (NODATA) of the requested type exists in, err := dnsQuery(fqdn, dns.TypeSOA, nameserver, true) if err != nil { return "", err } if in.Rcode != dns.RcodeNameError { if in.Rcode != dns.RcodeSuccess { return "", fmt.Errorf("NS %s returned %s for %s", nameserver, dns.RcodeToString[in.Rcode], fqdn) } // We have a success, so one of the answers has to be a SOA RR for _, ans := range in.Answer { if soa, ok := ans.(*dns.SOA); ok { zone := soa.Hdr.Name // If we ended up on one of the TLDs, it means the domain did not exist. publicsuffix, _ := publicsuffix.PublicSuffix(UnFqdn(zone)) if publicsuffix == UnFqdn(zone) { return "", fmt.Errorf("Could not determine zone authoritatively") } fqdnToZone[fqdn] = zone return zone, nil } } // Or it is NODATA, fall through to NXDOMAIN } // Search the authority section for our precious SOA RR for _, ns := range in.Ns { if soa, ok := ns.(*dns.SOA); ok { zone := soa.Hdr.Name // If we ended up on one of the TLDs, it means the domain did not exist. publicsuffix, _ := publicsuffix.PublicSuffix(UnFqdn(zone)) if publicsuffix == UnFqdn(zone) { return "", fmt.Errorf("Could not determine zone authoritatively") } fqdnToZone[fqdn] = zone return zone, nil } } return "", fmt.Errorf("NS %s did not return the expected SOA record in the authority section", nameserver) }
// This follows https://fedoraproject.org/wiki/PackagingDrafts/Go#Package_Names func debianNameFromGopkg(gopkg, t string) string { parts := strings.Split(gopkg, "/") if t == "program" { return parts[len(parts)-1] } host := parts[0] if host == "github.com" { host = "github" } else if host == "code.google.com" { host = "googlecode" } else if host == "gopkg.in" { host = "gopkg" } else if host == "golang.org" { host = "golang" } else if host == "google.golang.org" { host = "google" } else if host == "bitbucket.org" { host = "bitbucket" } else if host == "bazil.org" { host = "bazil" } else if host == "pault.ag" { host = "pault" } else { if *allowUnknownHoster { suffix, _ := publicsuffix.PublicSuffix(host) host = host[:len(host)-len(suffix)-len(".")] log.Printf("WARNING: Using %q as canonical hostname for %q. If that is not okay, please file a bug against %s.\n", host, parts[0], os.Args[0]) } else { log.Fatalf("Cannot derive Debian package name: unknown hoster %q. See -help output for -allow_unknown_hoster\n", host) } } parts[0] = host return "golang-" + strings.ToLower(strings.Join(parts, "-")) }
func (self *Server) Blocked(host string) bool { blocked, cached := false, false host = HostOnly(host) self.mutex.RLock() if self.BlockedHosts[host] { blocked = true cached = true } self.mutex.RUnlock() if !blocked { tld, _ := publicsuffix.EffectiveTLDPlusOne(host) blocked = self.Cfg.Blocked(tld) } if !blocked { suffix, _ := publicsuffix.PublicSuffix(host) blocked = self.Cfg.Blocked(suffix) } if blocked && !cached { self.mutex.Lock() self.BlockedHosts[host] = true self.mutex.Unlock() } return blocked }
func printSuffix() { host := *FSuffix tld, _ := publicsuffix.EffectiveTLDPlusOne(host) fmt.Printf("EffectiveTLDPlusOne: %s\n", tld) suffix, _ := publicsuffix.PublicSuffix(host) fmt.Printf("PublicSuffix: %s\n", suffix) }
func MainLetterFromURL(URL string) string { URL = strings.TrimSpace(URL) if !strings.HasPrefix(URL, "http") { URL = "http://" + URL } url, err := url.Parse(URL) if err != nil { return "" } host := url.Host hostSuffix, _ := publicsuffix.PublicSuffix(host) if hostSuffix != "" { host = strings.TrimSuffix(host, hostSuffix) host = strings.TrimSuffix(host, ".") } hostParts := strings.Split(host, ".") domain := hostParts[len(hostParts)-1] if len(domain) > 0 { return string(domain[0]) } else if len(hostSuffix) > 0 { return string(hostSuffix[0]) } return "" }
func isTLD(domain string) bool { publicsuffix, _ := publicsuffix.PublicSuffix(UnFqdn(domain)) if publicsuffix == UnFqdn(domain) { return true } return false }
func CheckPublicSuffix(zones map[string]*Zone) { color.Fprintf(os.Stderr, "@{.}Checking against the Public Suffix List for %d zones...\n", len(zones)) mapZones(zones, func(z *Zone) { host, err := idna.ToASCII(pfx + z.Domain) if err != nil { LogWarning(err) return } s, _ := publicsuffix.PublicSuffix(host) s = Normalize(s) switch { // ZoneDB and PSL agree case s == z.Domain: return // PSL wildcard case strings.HasPrefix(s, pfx) && len(z.Subdomains) != 0: return // ZoneDB and PSL disagree default: color.Fprintf(os.Stderr, "@{y}Public Suffix List: @{y!}%s@{y} for @{y!}%s\n", s, z.Domain) } }) }
func main() { for _, host := range os.Args[1:] { fmt.Printf("Host: %s\n", host) tld, _ := publicsuffix.EffectiveTLDPlusOne(host) fmt.Printf("\tEffectiveTLDPlusOne: %s\n", tld) suffix, _ := publicsuffix.PublicSuffix(host) fmt.Printf("\tPublicSuffix: %s\n", suffix) } }
func checkIfTLD(fqdn string, soa *dns.SOA) (string, error) { zone := soa.Hdr.Name // If we ended up on one of the TLDs, it means the domain did not exist. publicsuffix, _ := publicsuffix.PublicSuffix(UnFqdn(zone)) if publicsuffix == UnFqdn(zone) { return "", fmt.Errorf("Could not determine zone authoritatively") } fqdnToZone[fqdn] = zone return zone, nil }
func (edb *EntriesDatabase) insertRegisteredDomains(txn *gorp.Transaction, certId uint64, names map[string]struct{}) error { domains := make(map[string]struct{}) for name, _ := range names { domain, err := publicsuffix.EffectiveTLDPlusOne(name) if err != nil { // This is non-critical. We'd rather have the cert with an incomplete // eTLD, so mask this error if edb.Verbose { fmt.Printf("%s\n", err) } continue } domains[domain] = struct{}{} } for domain, _ := range domains { etld, _ := publicsuffix.PublicSuffix(domain) label := strings.Replace(domain, "."+etld, "", 1) var regdomId uint64 err := txn.SelectOne(®domId, "SELECT regdomID FROM registereddomain WHERE domain = ? LIMIT 1", domain) if err != nil { domainObj := &RegisteredDomain{ Domain: domain, ETLD: etld, Label: label, } // Ignore errors on insert err := txn.Insert(domainObj) if errorIsNotDuplicate(err) { return fmt.Errorf("DB error on Registered Domain: %s: %s", domain, err) } regdomId = domainObj.RegDomID } certRegDomObj := &CertToRegisteredDomain{ RegDomID: regdomId, CertID: certId, } // Ignore errors on insert err = txn.Insert(certRegDomObj) if errorIsNotDuplicate(err) { return fmt.Errorf("DB error on Registered Domain: %s: %s", domain, err) } } return nil }