func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) { if *debug { Log.Printf("handleRequest: message: %+v\n", r) } m := new(dns.Msg) m.SetReply(r) m.Compress = false switch r.Opcode { case dns.OpcodeQuery: parseQuery(m) case dns.OpcodeUpdate: for _, question := range r.Question { for _, rr := range r.Ns { updateRecord(rr, &question) } } } if r.IsTsig() != nil { if w.TsigStatus() == nil { m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix()) } else { Log.Println("Status", w.TsigStatus().Error()) } } w.WriteMsg(m) }
func formerr(w dns.ResponseWriter, req *dns.Msg) { m := new(dns.Msg) m.MsgHdr.Opcode = dns.OpcodeUpdate if req.IsTsig() != nil { m.SetTsig(userFromTsig(req), dns.HmacMD5, 300, time.Now().Unix()) } w.WriteMsg(m.SetRcode(req, dns.RcodeFormatError)) }
func serverHandlerReturnSuccess(w dns.ResponseWriter, req *dns.Msg) { m := new(dns.Msg) m.SetReply(req) if t := req.IsTsig(); t != nil { if w.TsigStatus() == nil { // Validated m.SetTsig(rfc2136TestZone, dns.HmacMD5, 300, time.Now().Unix()) } } w.WriteMsg(m) }
func serverHandlerReturnSuccess(w dns.ResponseWriter, req *dns.Msg) { m := new(dns.Msg) m.SetReply(req) if req.Opcode == dns.OpcodeQuery && req.Question[0].Qtype == dns.TypeSOA && req.Question[0].Qclass == dns.ClassINET { // Return SOA to appease findZoneByFqdn() soaRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN SOA ns1.%s admin.%s 2016022801 28800 7200 2419200 1200", rfc2136TestZone, rfc2136TestTTL, rfc2136TestZone, rfc2136TestZone)) m.Answer = []dns.RR{soaRR} } if t := req.IsTsig(); t != nil { if w.TsigStatus() == nil { // Validated m.SetTsig(rfc2136TestZone, dns.HmacMD5, 300, time.Now().Unix()) } } w.WriteMsg(m) }
func (d *DNSResponder) handleDNS(w dns.ResponseWriter, r *dns.Msg) { var ( v4 bool rr dns.RR a net.IP ) dom := r.Question[0].Name m := new(dns.Msg) m.SetReply(r) if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok { a = ip.IP v4 = a.To4() != nil } if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok { a = ip.IP v4 = a.To4() != nil } if v4 { rr = new(dns.A) rr.(*dns.A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.A).A = a.To4() } else { rr = new(dns.AAAA) rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.AAAA).AAAA = a } switch r.Question[0].Qtype { case dns.TypeAAAA, dns.TypeA: m.Answer = append(m.Answer, rr) } if r.IsTsig() != nil { if w.TsigStatus() == nil { m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix()) } } w.WriteMsg(m) }
// base handler for dns server func dnsHandler(w dns.ResponseWriter, request *dns.Msg) { response := new(dns.Msg) response.SetReply(request) response.Compress = false switch request.Opcode { case dns.OpcodeQuery: for _, q := range response.Question { if readRR, e := getRecord(q.Name, q.Qtype); e == nil { rr := readRR.(dns.RR) if rr.Header().Name == q.Name { response.Answer = append(response.Answer, rr) } } } case dns.OpcodeUpdate: if request.IsTsig() != nil && w.TsigStatus() == nil { for _, question := range request.Question { for _, rr := range request.Ns { updateRecord(rr, &question) } } } else { log.Println("droping update without tsig or with bad sig") } } if request.IsTsig() != nil { if w.TsigStatus() == nil { response.SetTsig(request.Extra[len(request.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix()) } else { log.Println("Status: ", w.TsigStatus().Error()) } } w.WriteMsg(response) }
func handleReflect(w dns.ResponseWriter, r *dns.Msg) { var ( v4 bool rr dns.RR str string a net.IP ) // TC must be done here m := new(dns.Msg) m.SetReply(r) m.Compress = *compress if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (udp)" a = ip.IP v4 = a.To4() != nil } if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)" a = ip.IP v4 = a.To4() != nil } if v4 { rr = new(dns.RR_A) rr.(*dns.RR_A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_A).A = a.To4() } else { rr = new(dns.RR_AAAA) rr.(*dns.RR_AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.RR_AAAA).AAAA = a } t := new(dns.RR_TXT) t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} t.Txt = []string{str} switch r.Question[0].Qtype { case dns.TypeAXFR: c := make(chan *dns.XfrToken) var e *error if err := dns.XfrSend(w, r, c, e); err != nil { close(c) return } soa, _ := dns.NewRR(`whoami.miek.nl. IN SOA elektron.atoom.net. miekg.atoom.net. ( 2009032802 21600 7200 604800 3600)`) c <- &dns.XfrToken{RR: []dns.RR{soa, t, rr, soa}} close(c) w.Hijack() // w.Close() // Client closes return case dns.TypeTXT: m.Answer = append(m.Answer, t) m.Extra = append(m.Extra, rr) default: fallthrough case dns.TypeAAAA, dns.TypeA: m.Answer = append(m.Answer, rr) m.Extra = append(m.Extra, t) } if r.IsTsig() != nil { if w.TsigStatus() == nil { m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.RR_TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix()) } else { println("Status", w.TsigStatus().Error()) } } if *printf { fmt.Printf("%v\n", m.String()) } w.Write(m) }
// config stuff in Auth section (just as dynamic updates (*hint* *hint*) // SUBSYSTEM. IN TXT "OPERATION<SPACE>OPTIONS..." // ZONE. IN TXT "READ origin /z/bloep" - absolute path in fs func config(w dns.ResponseWriter, req *dns.Msg, c *Config) { logPrintf("config command") if req.Question[0].Qclass != dns.ClassCHAOS { logPrintf("non config command (wrong class)") if z, ok := c.Zones[req.Question[0].Name]; ok { serve(w, req, z) return } formerr(w, req) return } if req.IsTsig() == nil { logPrintf("non config command (no tsig) - attemping metazone") metazone(w, req, c) return } if req.MsgHdr.Opcode != dns.OpcodeUpdate || req.Question[0].Qtype != dns.TypeSOA { logPrintf("non config command (no update)") formerr(w, req) return } if e := w.TsigStatus(); e != nil { logPrintf("non config command (tsig fail): %s", e.Error()) formerr(w, req) return } // No need to check the user, if the tsig checks out, the user exists logPrintf("config command ok") for _, rr := range req.Ns { t, ok := rr.(*dns.TXT) if !ok { formerr(w, req) return } switch strings.ToUpper(t.Header().Name) { case "ZONE.": if e := configZONE(w, req, t, c); e != nil { formerr(w, req) return } case "USER.": if userFromTsig(req) != dns.Fqdn(*superuser) { logPrintf("user management is only for the superuser\n") formerr(w, req) return } if e := configUSER(w, req, t, c); e != nil { formerr(w, req) return } default: formerr(w, req) return } } }
func handleReflect(w dns.ResponseWriter, r *dns.Msg) { reflectHandled += 1 if reflectHandled%1000 == 0 { fmt.Printf("Served %d reflections\n", reflectHandled) } var ( v4 bool rr dns.RR str string a net.IP ) m := new(dns.Msg) m.SetReply(r) m.Compress = *compress if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (udp)" a = ip.IP v4 = a.To4() != nil } if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok { str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)" a = ip.IP v4 = a.To4() != nil } if v4 { rr = new(dns.A) rr.(*dns.A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.A).A = a.To4() } else { rr = new(dns.AAAA) rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} rr.(*dns.AAAA).AAAA = a } t := new(dns.TXT) t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} t.Txt = []string{str} switch r.Question[0].Qtype { case dns.TypeTXT: m.Answer = append(m.Answer, t) m.Extra = append(m.Extra, rr) default: fallthrough case dns.TypeAAAA, dns.TypeA: m.Answer = append(m.Answer, rr) m.Extra = append(m.Extra, t) case dns.TypeAXFR, dns.TypeIXFR: c := make(chan *dns.Envelope) tr := new(dns.Transfer) defer close(c) err := tr.Out(w, r, c) if err != nil { return } soa, _ := dns.NewRR(`whoami.miek.nl. 0 IN SOA linode.atoom.net. miek.miek.nl. 2009032802 21600 7200 604800 3600`) c <- &dns.Envelope{RR: []dns.RR{soa, t, rr, soa}} w.Hijack() // w.Close() // Client closes connection return } if r.IsTsig() != nil { if w.TsigStatus() == nil { m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix()) } else { println("Status", w.TsigStatus().Error()) } } if *printf { fmt.Printf("%v\n", m.String()) } // set TC when question is tc.miek.nl. if m.Question[0].Name == "tc.miek.nl." { m.Truncated = true // send half a message buf, _ := m.Pack() w.Write(buf[:len(buf)/2]) return } w.WriteMsg(m) }