// Recursively takes an spf record and resolves into a list of IP addresses //TODO: Handle IPv6 addresses. Currently ignoring due to the huge // performance hit. Too slow. func TraverseSPF(records []string) string { var expandedSPF string var recordArr []string for _, record := range records { // Skip non SPF TXT records if !strings.Contains(record, "spf") { continue } //fmt.Printf("\nExpanding \"%s\"", record) // Explode record on spaces recordArr = strings.Split(record, " ") //fmt.Printf("\nSplit \"%q\"", recordArr) // Loop through all directives and process for _, r := range recordArr { // Lines start with - are fails if strings.HasPrefix(r, "-") { continue } // Get TXT records and for each include if strings.Contains(r, "include:") { temp := strings.Replace(strings.Replace(strings.Replace(r, "+include:", "", -1), "~include:", "", -1), "include:", "", -1) passArr, _ := net.LookupTXT(temp) //fmt.Printf("\n Found include") expandedSPF = expandedSPF + " " + TraverseSPF(passArr) // Expand redirects } else if strings.Contains(r, "redirect=") { passArr, _ := net.LookupTXT(strings.Replace(r, "redirect=", "", -1)) //fmt.Printf("\n Found redirect") expandedSPF = expandedSPF + " " + TraverseSPF(passArr) // If contains mx get mx records } else if strings.Contains(r, "mx:") { //TODO: Add MX expansion // Currently this is just ignoring mx records as if they were invalid //passArr, _ := net.LookupMX(strings.Replace(r, "mx:", "", -1)) //fmt.Printf("\n Found mx") //expandedSPF = expandedSPF + " " + TraverseSPF(passArr) } else { //fmt.Printf("\n Nothing to expand") expandedSPF = expandedSPF + " " + r } } } return expandedSPF }
func main() { txt, err := net.LookupTXT("rs.dns-oarc.net") if err != nil { fmt.Println(err) } fmt.Printf("%v", txt) }
func (rbl *RBL) LookupRBL(ip net.IP) (RBLResult, error) { res := RBLResult{ Listed: false, Ip: ip, Zone: rbl.Zone, Text: "", } query, err := rbl.query(ip) if err != nil { return res, err } addrs, err := net.LookupHost(query) reg, _ := regexp.Compile("(?i:no such host)") if err != nil && reg.FindStringIndex(err.Error()) == nil { return res, err } if len(addrs) > 0 { res.Listed = true text, err := net.LookupTXT(query) if err == nil { res.Text = strings.Join(text, "\n") } } return res, nil }
func runTraceroute(targetHost string, ipChan chan []string, waitChan chan int) { app := "traceroute" arg0 := "-f" //-f 2 arg1 := "1" //first ttl arg2 := "-m" arg3 := "25" //max ttl arg4 := "-q" arg5 := "3" //number of tries per hop arg6 := "-w" arg7 := "2" //wait time (in seconds) arg8 := "-n" //no dns resolution arg9 := "64" //packet size, bytes cmd := exec.Command(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, targetHost, arg9) //execute the commands above, with the host passed out, err := cmd.Output() //output the results of the command if err != nil { fmt.Printf(err.Error()) return } //fmt.Printf("%s\n", string(out)) traceResult := findIPaddr(string(out)) //fmt.Printf("%q\n", traceResult) var ipArray = make([]string, 0) dnsPtr := "" asnResult := "" for i := 2; i < len(traceResult); i++ { currIpAddr := traceResult[i][0] reverseDNSaddr, _ := net.LookupAddr(currIpAddr) if len(reverseDNSaddr) > 0 { //fmt.Printf("%s\n", reverseDNSaddr[0]) dnsPtr = reverseDNSaddr[0] //if it has a PTR, put it in the PTR array section } else { dnsPtr = "noPTR" //everything that does not have a PTR listed } reverseIPaddrResult := reverseIPaddr(currIpAddr) //call the function to reverse the IP address dnsQueryAddress := reverseIPaddrResult + ".origin.asn.cymru.com" //query team cymru database for IP to ASN ipToAsnLookup, _ := net.LookupTXT(dnsQueryAddress) //get TXT record result if len(ipToAsnLookup) > 0 { asnIndex := strings.Index(ipToAsnLookup[0], " ") //if so, parse out the ASN from the result queryString := ipToAsnLookup[0] asnResult = queryString[0:asnIndex] } else { asnResult = "noASN" } ipRowString := currIpAddr + "," + dnsPtr + "," + asnResult ipArray = append(ipArray, ipRowString) } //fmt.Printf("%d\n", len(traceIpArray)) //fmt.Printf("%q\n", ipArray) ipChan <- ipArray waitChan <- 1 return }
func (d Domain) txt() string { addrs, err := net.LookupTXT(d.domain) if err != nil { return "\nTXT records\n" + "--\n" + err.Error() } records := "\nTXT records\n" + "--\n" for _, val := range addrs { records += val + "\n" } return records }
func resourceDnsTxtRecordCreate(d *schema.ResourceData, meta interface{}) error { d.SetId(d.Get("name").(string)) records, err := net.LookupTXT(d.Id()) if err != nil { return err } if len(records) > 0 { d.Set("record", records[0]) } d.Set("records", records) return nil }
func dataSourceDnsTxtRecordRead(d *schema.ResourceData, meta interface{}) error { records, err := net.LookupTXT(d.Get("host").(string)) if err != nil { return err } if len(records) > 0 { d.Set("record", records[0]) } else { d.Set("record", "") } d.Set("records", records) return nil }
// MustResolveOneIPByName takes in a string and returns the single // string value for the IP which is being resolved. // If it fails, or returns other values, panic func MustResolveOneTXTByName(name string) string { // Do the resolve t, err := net.LookupTXT(name) // Check the initial error and panic if need be if err != nil { panic(err) } // Check for multiple return values if len(t) != 1 { panic(fmt.Errorf("Invalid response: %v", t)) } // Return the single value return t[0] }
func CountryForIPString(ipstr string) (country string, err error) { rev, err := reverseIP(ipstr) if err != nil { return "", err } query := fmt.Sprintf("%s.%s", rev, *flCountriesZone) txtList, err := net.LookupTXT(query) if err != nil { return "", err } if len(txtList) > 0 { return strings.ToUpper(txtList[0]), nil } return "", fmt.Errorf("No TXT records (and no error) for: %s", query) }
func resourceDnsTxtRecordRead(d *schema.ResourceData, meta interface{}) error { // Read if forcing an update, or we haven't yet read any records if d.Get("update").(bool) { records, err := net.LookupTXT(d.Id()) if err != nil { return err } if len(records) > 0 { d.Set("record", records[0]) } d.Set("records", records) } return nil }
// ResolveOneIPByName takes in a string and returns a string and error // indicator. The error indicator is used if the resolve fails or returns // multiple values. func ResolveOneTXTByName(name string) (string, error) { // Do the resolve t, err := net.LookupTXT(name) // Check the initial error and return that if present if err != nil { return "", err } // Check for multiple IPs. If so, send back an error w/ "Multiple IPs returned" if len(t) != 1 { err = fmt.Errorf("Multiple TXT records returned") return "", err } // Return the single value return t[0], nil }
func txt(host string) (data []byte, err error) { txts, err := net.LookupTXT(host) if err != nil { err = os.ErrNotExist return } buf := bytes.NewBuffer(make([]byte, 0, len(txts)*80)) for _, txt := range txts { buf.WriteString(txt) buf.WriteByte('\n') } data = buf.Bytes() return }
func Query(hash []byte) (*Response, error) { txts, err := net.LookupTXT(dnsname(hash)) if err != nil { if isnxdomain(err) { return nil, nil } return nil, err } if len(txts) != 1 { return nil, errMultipleRecords } return parseResponse(txts[0]) }
func GetPksAuthTXTRecord(domain string) (pksAuth PksAuthTXT, err error) { txts, err1 := net.LookupTXT(domain) found := false if err1 != nil { log.Println(err1) err = err1 return } net.LookupAddr(domain) for _, r := range txts { //log.Println("TXT of " + domain + " : " + r) rcds := strings.Split(r, "=") if len(rcds) != 2 { log.Println("Not Found = in TXT Record of " + domain) } else if rcds[0] != "pks" { log.Println("pks not found in TXT Record of " + domain) } else { rcds = strings.Split(rcds[1], " ") if len(rcds) != 3 { log.Println("Not Enough values in TXT Record of domain " + domain) } else { pksAuth.authAddr = rcds[0] //fmt.Println("pks_Addr=", rcds[0]) //fmt.Println("key_FingerPrint=", rcds[1]) pksAuth.keyFingerPrint = rcds[1] since, err2 := strconv.Atoi(rcds[2]) if err2 != nil { log.Println(err2) err = err2 return } pksAuth.since = int64(since) found = true break //fmt.Println("time=", time.Unix(int64(since), 0)) } } } if found == false { err = errors.New("TXT Record of domain " + domain + "doesnt contain valid pksAuth Record") return } return }
func ltxt(domain string) { txts, err := net.LookupTXT(domain) if err != nil { //fmt.Printf("err:%s\n", err) return } fmt.Printf("-----------------\n") fmt.Printf(" Information TXT \n") fmt.Printf("-----------------\n") for _, txt := range txts { fmt.Printf("\t%s\n", txt) } }
func (rc *DNSChecker) CheckDomain(sig string, domain string) ProofError { txt, err := net.LookupTXT(domain) if err != nil { return NewProofError(keybase1.ProofStatus_DNS_ERROR, "DNS failure for %s: %s", domain, err) } for _, record := range txt { G.Log.Debug("For %s, got TXT record: %s", domain, record) if record == sig { return nil } } return NewProofError(keybase1.ProofStatus_NOT_FOUND, "Checked %d TXT entries of %s, but didn't find signature %s", len(txt), domain, sig) }
func handler(w http.ResponseWriter, r *http.Request) { parts := strings.Split(r.Host, ":") host := parts[0] hostname := fmt.Sprintf("_redirect.%s", host) txt, err := net.LookupTXT(hostname) if err != nil { fallback(w, r, fmt.Sprintf("Could not resolve hostname (%v)", err)) return } redirect, err := getRedirect(txt, r.URL.String()) if err != nil { fallback(w, r, err.Error()) } else { http.Redirect(w, r, redirect.Location, redirect.Status) } }
func (GoogleCatalogVerifier) Check(address string, fingerprint string) (fp string, err error) { fp = strings.ToLower(fingerprint) txts, err := net.LookupTXT(fp + "." + GOOGLE_CATALOG) if err != nil { return "", err } if len(txts) > 0 { return fingerprint, nil } //ok, google has seen this one. But how long ago?*/ //t := time.Now().UTC().Unix() //currentDay := t / int64(60*60*24) return "", errors.New("google catalog didn't contain ") }
func dns(w http.ResponseWriter, r *http.Request) { q := r.URL.Query().Get("q") // Note that the below is NOT safe from input attacks, but that's OK // because this is just for debugging. fmt.Fprintf(w, `<html><body> <form action="/dns"> <input name="q" type="text" value="%v"></input> <button type="submit">Lookup</button> </form> <br/><br/><pre>`, q) { res, err := net.LookupNS(q) spew.Fprintf(w, "LookupNS(%v):\nResult: %#v\nError: %v\n\n", q, res, err) } { res, err := net.LookupTXT(q) spew.Fprintf(w, "LookupTXT(%v):\nResult: %#v\nError: %v\n\n", q, res, err) } { cname, res, err := net.LookupSRV("", "", q) spew.Fprintf(w, `LookupSRV("", "", %v): cname: %v Result: %#v Error: %v `, q, cname, res, err) } { res, err := net.LookupHost(q) spew.Fprintf(w, "LookupHost(%v):\nResult: %#v\nError: %v\n\n", q, res, err) } { res, err := net.LookupIP(q) spew.Fprintf(w, "LookupIP(%v):\nResult: %#v\nError: %v\n\n", q, res, err) } { res, err := net.LookupMX(q) spew.Fprintf(w, "LookupMX(%v):\nResult: %#v\nError: %v\n\n", q, res, err) } fmt.Fprintf(w, `</pre> </body> </html>`) }
// Given a SBL hit on a remote IP, try to give us what SBL records were hit. func getSBLHits(t *smtpTransaction) []string { var sbls []string // since we know this hit, we can omit a lot of checks. s := strings.Split(t.rip, ".") ln := fmt.Sprintf("%s.%s.%s.%s.sbl.spamhaus.org.", s[3], s[2], s[1], s[0]) txts, err := net.LookupTXT(ln) if err != nil { return sbls } for _, txt := range txts { idx := strings.LastIndex(txt, "/") if idx == -1 || idx == len(txt)-1 { continue } sbls = append(sbls, txt[idx+1:]) } sort.Strings(sbls) return sbls }
func main() { var err error cmdFlags() flag.Parse() if interfaces, err = net.Interfaces(); err != nil { panic(err) } if interfaceAddrs, err = net.InterfaceAddrs(); err != nil { panic(err) } if Options.listInterfaces { listInterfaces(interfaces) } else if Options.listInterfaceAddrs { listInterfaceAddrs(interfaceAddrs) } else if Options.rdns != "" { hostnames, _ := net.LookupAddr(Options.rdns) for _, hostname := range hostnames { fmt.Println(hostname) } } else if Options.ip != "" { ips, _ := net.LookupIP(Options.ip) for _, ip := range ips { fmt.Println(ip) } } else if Options.mx != "" { mxs, _ := net.LookupMX(Options.mx) for _, mx := range mxs { fmt.Println(mx.Pref, mx.Host) } } else if Options.ns != "" { nss, _ := net.LookupNS(Options.ns) for _, ns := range nss { fmt.Println(ns.Host) } } else if Options.txt != "" { txts, _ := net.LookupTXT(Options.txt) for _, txt := range txts { fmt.Println(txt) } } }
// Resolve implements Resolver // TXT records for a given domain name should contain a b58 // encoded multihash. func (r *DNSResolver) Resolve(name string) (string, error) { log.Info("DNSResolver resolving %v", name) txt, err := net.LookupTXT(name) if err != nil { return "", err } for _, t := range txt { chk := b58.Decode(t) if len(chk) == 0 { continue } _, err := mh.Cast(chk) if err != nil { continue } return t, nil } return "", ErrResolveFailed }
// Query will query a single dnsbl server about a host and return a struct // containing information returned by the dnsbl server. func Query(rbl, host string) (r Result, err error) { // Format the host address in the format of google.com.bad.example.com or // 99.2.0.192.bad.example.com name := fmt.Sprintf("%s.%s", host, rbl) addrs, err := net.LookupHost(name) if err != nil { return } // Check if the dnsbl server replied with an A record that points to // a local address such as 127.0.0.0/8 or [::1]. if len(addrs) == 0 { return } // Check if the address returned by the dnsbl is an address that // has 127 as the first octet. If this is true then we can safely // assume that the host or IP is on the dnsrbl. if net.ParseIP(addrs[0]).IsLoopback() { r.Listed = true } // A dnsbl may return a txt record explaining why the host or IP // is on the list. txts, err := net.LookupTXT(name) if err != nil { return } // Usually only the first txt first is populated so we don't need to // loop through them. if len(txts) != 0 { r.Text = txts[0] } return }
func serve(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { http.Error(w, fmt.Sprintf("This resource does not accept %s requests.", r.Method), http.StatusMethodNotAllowed) return } domain := r.URL.Path[1:] h := w.Header() h.Set("Content-Type", "application/json; charset=utf-8") h.Set("Cache-Control", "public, max-age=900") h.Set("Access-Control-Allow-Origin", "*") srvFound := true _, srv, err := net.LookupSRV("xmpp-client", "tcp", domain) if err != nil { if !strings.HasSuffix(err.Error(), "DNS name does not exist.") { log.Printf("Error resolving SRV records for %q: %v", domain, err) httpError(w, internalServerError, http.StatusInternalServerError) return } srvFound = false } txtFound := true txt, err := net.LookupTXT("_xmppconnect." + domain) if err != nil { if !strings.HasSuffix(err.Error(), "DNS name does not exist.") { log.Printf("Error resolving TXT records for %q: %v", domain, err) httpError(w, internalServerError, http.StatusInternalServerError) return } txtFound = false } if !txtFound && !srvFound { httpError(w, notFoundError, http.StatusNotFound) return } res := &response{ Version: "1.0", Data: &struct { Servers serverList `json:"servers"` Alternatives alternativeList `json:"alternatives"` }{ Servers: make([]*server, len(srv)), Alternatives: make([]*alternative, len(txt)), }, } for i, service := range srv { res.Data.Servers[i] = &server{ Target: service.Target, Port: service.Port, Priority: service.Priority, Weight: service.Weight, } } for i, rec := range txt { split := strings.SplitN(rec, "=", 2) name := split[0] if !strings.HasPrefix(strings.ToLower(name), "_xmpp-client-") { continue } name = name[13:] res.Data.Alternatives[i] = &alternative{ Name: name, Value: split[1], } } if len(res.Data.Servers) == 0 && len(res.Data.Alternatives) == 0 { httpError(w, notFoundError, http.StatusNotFound) return } sort.Sort(res.Data.Servers) sort.Sort(res.Data.Alternatives) encoded, err := json.Marshal(res) if err != nil { log.Fatalf("Error marshalling JSON for %q: %v", domain, err) } hash := crc64.Checksum(encoded, crcTable) h.Set("ETag", "\""+strconv.FormatUint(hash, 16)+"\"") content := bytes.NewReader(encoded) http.ServeContent(w, r, domain, time.Time{}, content) }
func resolvTXT(addr string) string { txts, _ := net.LookupTXT(addr) return strings.Join(txts, ", ") }
// Process request func Process(sEmail string, sHeader string) (Reply, error) { var r Reply var sIP string var sDomain string var sReceived = sHeader var bSPFPass bool = false var ApprovedIPs []string // Init _, sDomain = SplitAddress(sEmail) r.Email = sEmail r.Header = sHeader r.Domain = sDomain r.IP = sIP // Get records of sender domain records, _ := net.LookupTXT(sDomain) sSPF := TraverseSPF(records) //fmt.Printf("\n\n\nFinal: %s", sSPF) SPF := strings.Split(sSPF, " ") // Now let's only look at IPs for _, el := range SPF { if strings.Contains(el, "ip4:") { ApprovedIPs = append(ApprovedIPs, el) } //TODO: ipv6 } // See if received from is valid sender ips, _ := net.LookupIP(sReceived) for _, ip := range ips { //fmt.Printf("\nFound %v", ip) r.IP = ip.String() for _, el := range ApprovedIPs { // See if IP in spf if strings.Contains(el, ip.String()) { bSPFPass = true break // If this is a network block, do lookup } else if strings.Contains(el, "/") { //fmt.Printf("\n Resolving cidr of %v", el) _, cidrNet, _ := net.ParseCIDR(strings.Replace(strings.Replace(el, "ip4:", "", -1), "ip6:", "", -1)) if cidrNet.Contains(ip) { bSPFPass = true break } } } // See if IP in any networks of spf } //fmt.Printf("\n\n") //for _, ip := range ips { // fmt.Printf("\nSent by %s", ip.String()) //} // Build success reply r.Result = "Fail" if bSPFPass { r.Result = "Pass" } return r, nil }
func newPubKeyFromDnsTxt(selector, domain string) (*pubKeyRep, verifyOutput, error) { txt, err := net.LookupTXT(selector + "._domainkey." + domain) if err != nil { if strings.HasSuffix(err.Error(), "no such host") { return nil, PERMFAIL, ErrVerifyNoKeyForSignature } else { return nil, TEMPFAIL, ErrVerifyKeyUnavailable } } // empty record if len(txt) == 0 { return nil, PERMFAIL, ErrVerifyNoKeyForSignature } pkr := new(pubKeyRep) pkr.Version = "DKIM1" pkr.HashAlgo = []string{"sha1", "sha256"} pkr.KeyType = "rsa" pkr.ServiceType = []string{"all"} pkr.FlagTesting = false pkr.FlagIMustBeD = false // parsing, we keep the first record // TODO: if there is multiple record p := strings.Split(txt[0], ";") for i, data := range p { keyVal := strings.SplitN(data, "=", 2) val := "" if len(keyVal) > 1 { val = strings.TrimSpace(keyVal[1]) } switch strings.ToLower(strings.TrimSpace(keyVal[0])) { case "v": // RFC: is this tag is specified it MUST be the first in the record if i != 0 { return nil, PERMFAIL, ErrVerifyTagVMustBeTheFirst } pkr.Version = val if pkr.Version != "DKIM1" { return nil, PERMFAIL, ErrVerifyVersionMusBeDkim1 } case "h": p := strings.Split(strings.ToLower(val), ":") pkr.HashAlgo = []string{} for _, h := range p { h = strings.TrimSpace(h) if h == "sha1" || h == "sha256" { pkr.HashAlgo = append(pkr.HashAlgo, h) } } // if empty switch back to default if len(pkr.HashAlgo) == 0 { pkr.HashAlgo = []string{"sha1", "sha256"} } case "k": if strings.ToLower(val) != "rsa" { return nil, PERMFAIL, ErrVerifyBadKeyType } case "n": pkr.Note = val case "p": rawkey := val if rawkey == "" { return nil, PERMFAIL, ErrVerifyRevokedKey } un64, err := base64.StdEncoding.DecodeString(rawkey) if err != nil { return nil, PERMFAIL, ErrVerifyBadKey } pk, err := x509.ParsePKIXPublicKey(un64) pkr.PubKey = *pk.(*rsa.PublicKey) case "s": t := strings.Split(strings.ToLower(val), ":") for _, tt := range t { if tt == "*" { pkr.ServiceType = []string{"all"} break } if tt == "email" { pkr.ServiceType = []string{"email"} } } case "t": flags := strings.Split(strings.ToLower(val), ":") for _, flag := range flags { if flag == "y" { pkr.FlagTesting = true continue } if flag == "s" { pkr.FlagIMustBeD = true } } } } // if no pubkey if pkr.PubKey == (rsa.PublicKey{}) { return nil, PERMFAIL, ErrVerifyNoKey } return pkr, SUCCESS, nil }
func resolveSRV(uri *URI, proto string) (*e3x.Identity, error) { // ignore port host, _, _ := net.SplitHostPort(uri.Canonical) if host == "" { host = uri.Canonical } // normalize if !strings.HasSuffix(host, ".") { host += "." } // ignore .public if strings.HasSuffix(host, ".public.") { return nil, &net.DNSError{Name: host, Err: "cannot resolve .public hostnames using DNS"} } // lookup SRV records _, srvs, err := net.LookupSRV("mesh", proto, host) if err != nil { return nil, err } if len(srvs) > 1 { return nil, &net.DNSError{Name: host, Err: "too many SRV records"} } if len(srvs) == 0 { return nil, &net.DNSError{Name: host, Err: "no SRV records"} } var ( srv = srvs[0] port = srv.Port portStr = strconv.Itoa(int(port)) hn hashname.H keys cipherset.Keys ) { // detect valid target parts := strings.SplitN(srv.Target, ".", 2) if len(parts) != 2 || len(parts[0]) != 52 || len(parts[1]) == 0 { return nil, &net.DNSError{Name: host, Err: "SRV must target a <hashname>.<domain> domain"} } hn = hashname.H(parts[0]) if !hn.Valid() { return nil, &net.DNSError{Name: host, Err: "SRV must target a <hashname>.<domain> domain"} } } // detect CNAMEs (they are not allowed) cname, err := net.LookupCNAME(srv.Target) if err != nil { return nil, err } if cname != "" && cname != srv.Target { return nil, &net.DNSError{Name: host, Err: "CNAME record are not allowed"} } // lookup A AAAA records ips, err := net.LookupIP(srv.Target) if err != nil { return nil, err } if len(ips) == 0 { return nil, &net.DNSError{Name: host, Err: "no A or AAAA records"} } // lookup TXT txts, err := net.LookupTXT(srv.Target) if err != nil { return nil, err } if len(txts) == 0 { return nil, &net.DNSError{Name: host, Err: "no TXT records"} } // make addrs addrs := make([]net.Addr, 0, len(ips)) for _, ip := range ips { var ( addr net.Addr ) switch proto { case "udp": addr, _ = transports.ResolveAddr("udp4", net.JoinHostPort(ip.String(), portStr)) if addr == nil { addr, _ = transports.ResolveAddr("udp6", net.JoinHostPort(ip.String(), portStr)) } case "tcp": addr, _ = transports.ResolveAddr("tcp4", net.JoinHostPort(ip.String(), portStr)) if addr == nil { addr, _ = transports.ResolveAddr("tcp6", net.JoinHostPort(ip.String(), portStr)) } // case "http": // addr, _ = http.NewAddr(ip, port) } if addr != nil { addrs = append(addrs, addr) } } { // parse keys // Sort txts so they form ascending sequences of key parts sort.Strings(txts) keyData := make(map[uint8]string, 10) for len(txts) > 0 { var ( txt = txts[0] parts = strings.Split(txt, "=") ) if len(parts) != 2 { txts = txts[1:] continue } var ( label = parts[0] value = parts[1] csid uint8 ) if len(label) < 2 { txts = txts[1:] continue } // parse the CSID portion of the label i, err := strconv.ParseUint(label[:2], 16, 8) if err != nil { txts = txts[1:] continue } csid = uint8(i) // verify the key-part portion of the label if len(label) > 2 { _, err = strconv.ParseUint(label[2:], 10, 8) if err != nil { txts = txts[1:] continue } } keyData[csid] += value txts = txts[1:] } keys = make(cipherset.Keys, len(keyData)) for csid, str := range keyData { key, err := cipherset.DecodeKey(csid, str, "") if err != nil { continue } keys[csid] = key } } ident, err := e3x.NewIdentity(keys, nil, addrs) if err != nil { return nil, err } if hn != ident.Hashname() { return nil, &net.DNSError{Name: host, Err: "invalid keys"} } return ident, nil }
func configure(hub *StatusHub) { cfg, err := configRead(*configFile) if err != nil { log.Printf("Could not read config file: %s\n", err) os.Exit(2) } hub.MarkConfigurationStart() wg := &sync.WaitGroup{} errch := make(chan error, 20) for _, server := range cfg.Servers.A { log.Println("Adding", server) wg.Add(1) hub.AddNameBackground(server, errch) } for _, domain := range cfg.Servers.Domain { log.Println("Adding NSes for", domain) nses, err := net.LookupNS(domain) log.Printf("NSes: %#v: %s\n", nses, err) for _, ns := range nses { log.Printf("Adding '%s'\n", ns.Host) wg.Add(1) hub.AddNameBackground(ns.Host, errch) } } for _, txtconfig := range cfg.Servers.Txt { x := strings.SplitN(txtconfig, ",", 2) txtname := strings.TrimSpace(x[0]) txtbase := strings.TrimSpace(x[1]) log.Println("Adding TXT for", txtname, txtbase) txts, err := net.LookupTXT(txtname) log.Printf("TXTs: %#v: %s\n", txts, err) names := []string{} for _, txt := range txts { for _, name := range strings.Split(txt, " ") { names = append(names, name) } } nameSlice := []string{"", txtbase} for _, name := range names { nameSlice[0] = name hub.AddNameBackground(strings.Join(nameSlice, "."), errch) } } go func() { for err := range errch { if err != nil { log.Println(err) } wg.Done() } }() wg.Wait() close(errch) hub.MarkConfigurationEnd() }