NSEC3 encoding works
Only for 1 windows, but dig has stopped complaining. This needs to be streamlined a little, but its looking good.
This commit is contained in:
parent
32a0b4a6f2
commit
03a8ee13a2
|
@ -9,12 +9,13 @@ implemented in the library.
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
* UDP/TCP queries, IPv4 and IPv6;
|
* UDP/TCP queries, IPv4 and IPv6;
|
||||||
* TSIG;
|
|
||||||
* EDNS0;
|
|
||||||
* AXFR/IXFR;
|
|
||||||
* DNS name compression;
|
|
||||||
* Client and server side programming (mimicking the http package);
|
* Client and server side programming (mimicking the http package);
|
||||||
* Asynchronous queries for client and server;
|
* Asynchronous queries for client and server;
|
||||||
|
* DNSSEC;
|
||||||
|
* EDNS0;
|
||||||
|
* AXFR/IXFR;
|
||||||
|
* TSIG;
|
||||||
|
* DNS name compression;
|
||||||
* RFC 1035 zone file parsing.
|
* RFC 1035 zone file parsing.
|
||||||
|
|
||||||
Sample programs can be found in the `_examples` directory. They can
|
Sample programs can be found in the `_examples` directory. They can
|
||||||
|
@ -50,7 +51,7 @@ Miek Gieben - 2010-2012 - miek@miek.nl
|
||||||
* 4635 - HMAC SHA TSIG
|
* 4635 - HMAC SHA TSIG
|
||||||
* 4892 - id.server
|
* 4892 - id.server
|
||||||
* 5001 - NSID
|
* 5001 - NSID
|
||||||
* 5155 - NSEC
|
* 5155 - NSEC3
|
||||||
* 5933 - GOST
|
* 5933 - GOST
|
||||||
* 5936 - AXFR
|
* 5936 - AXFR
|
||||||
* xxxx - ECDSA
|
* xxxx - ECDSA
|
||||||
|
|
|
@ -75,12 +75,28 @@ func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
|
||||||
m.Extra = append(m.Extra, t)
|
m.Extra = append(m.Extra, t)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
nsec3 := new(dns.RR_NSEC3)
|
||||||
|
nsec3.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeNSEC3, Class: dns.ClassINET, Ttl: 0}
|
||||||
|
nsec3.Hash = dns.SHA1
|
||||||
|
nsec3.Flags = 0
|
||||||
|
nsec3.Iterations = 1
|
||||||
|
nsec3.Salt = "AABB"
|
||||||
|
nsec3.SaltLength = uint8(len(nsec3.Salt)/2)
|
||||||
|
nsec3.NextDomain = "miek.nl."
|
||||||
|
// nsec3.TypeBitMap = []uint16{dns.TypeA, dns.TypeNS, dns.TypeMX, dns.TypeTXT, 4000, 4001}
|
||||||
|
// nsec3.TypeBitMap = []uint16{dns.TypeA, dns.TypeNS, dns.TypeMX, dns.TypeTXT}
|
||||||
|
nsec3.TypeBitMap = []uint16{dns.TypeA, dns.TypeNS, dns.TypeSOA}
|
||||||
|
nsec3.HashNames("miek.nl.")
|
||||||
|
|
||||||
|
m.Extra = append(m.Extra, nsec3)
|
||||||
b, ok := m.Pack()
|
b, ok := m.Pack()
|
||||||
|
fmt.Printf("%v\n", m.String())
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Print("Packing failed")
|
log.Print("Packing failed")
|
||||||
//write formerr back?
|
m.SetRcode(r, dns.RcodeServerFailure)
|
||||||
return
|
m.Extra = nil
|
||||||
|
m.Answer = nil
|
||||||
|
b, _ = m.Pack()
|
||||||
}
|
}
|
||||||
w.Write(b)
|
w.Write(b)
|
||||||
}
|
}
|
||||||
|
|
54
msg.go
54
msg.go
|
@ -16,6 +16,7 @@ import (
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -408,11 +409,34 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
off++
|
off++
|
||||||
}
|
}
|
||||||
case "NSEC": // NSEC/NSEC3
|
case "NSEC": // NSEC/NSEC3
|
||||||
|
// This is the uint16 type bitmap
|
||||||
|
// TODO(mg): overflow
|
||||||
|
lastwindow := uint16(0)
|
||||||
|
octet := uint16(0)
|
||||||
for j := 0; j < val.Field(i).Len(); j++ {
|
for j := 0; j < val.Field(i).Len(); j++ {
|
||||||
var _ = byte(fv.Index(j).Uint())
|
t := uint16((fv.Index(j).Uint()))
|
||||||
|
window := uint16(t / 256)
|
||||||
|
if lastwindow != window {
|
||||||
|
// New window
|
||||||
|
off += 2 + int(octet)
|
||||||
|
}
|
||||||
|
octet := (t - window*256) / 8
|
||||||
|
bit := t - (window * 256) - (octet * 8)
|
||||||
|
|
||||||
|
println("Setting window", off, "to", byte(window))
|
||||||
|
msg[off] = byte(window)
|
||||||
|
println("Setting octet", off+1, "to", byte(octet+1))
|
||||||
|
msg[off+1] = byte(octet+1)
|
||||||
|
println("Setting value", off+1+1+int(octet), "to", byte(1<<bit))
|
||||||
|
msg[off+1+1+int(octet)] |= byte(1 << bit)
|
||||||
|
|
||||||
|
println(t, window, octet, bit, 1<<bit)
|
||||||
|
fmt.Printf("%b\n", msg[off+2+int(octet)])
|
||||||
|
|
||||||
|
lastwindow = window
|
||||||
}
|
}
|
||||||
// handle type bit maps
|
// off++
|
||||||
// TODO(mg)
|
println("off", off)
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
off, ok = packStructValue(fv, msg, off, compression, compress)
|
off, ok = packStructValue(fv, msg, off, compression, compress)
|
||||||
|
@ -464,14 +488,6 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
switch val.Type().Field(i).Tag {
|
switch val.Type().Field(i).Tag {
|
||||||
default:
|
default:
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
case "base32":
|
|
||||||
b32, err := packBase32([]byte(s))
|
|
||||||
if err != nil {
|
|
||||||
println("dns: overflow packing base32")
|
|
||||||
return lenmsg, false
|
|
||||||
}
|
|
||||||
copy(msg[off:off+len(b32)], b32)
|
|
||||||
off += len(b32)
|
|
||||||
case "base64":
|
case "base64":
|
||||||
b64, err := packBase64([]byte(s))
|
b64, err := packBase64([]byte(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -492,6 +508,20 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
println("dns: overflow packing domain-name", off)
|
println("dns: overflow packing domain-name", off)
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
}
|
}
|
||||||
|
case "size-base32":
|
||||||
|
// This is purely for NSEC3 atm, the previous byte must
|
||||||
|
// holds the length of the encoded string. As NSEC3
|
||||||
|
// is only defined to SHA1, the hashlength is 20 (160 bits)
|
||||||
|
msg[off-1] = 20 // Set HashLength... TODO(mg): check
|
||||||
|
fallthrough
|
||||||
|
case "base32":
|
||||||
|
b32, err := packBase32([]byte(s))
|
||||||
|
if err != nil {
|
||||||
|
println("dns: overflow packing base32")
|
||||||
|
return lenmsg, false
|
||||||
|
}
|
||||||
|
copy(msg[off:off+len(b32)], b32)
|
||||||
|
off += len(b32)
|
||||||
case "size-hex":
|
case "size-hex":
|
||||||
fallthrough
|
fallthrough
|
||||||
case "hex":
|
case "hex":
|
||||||
|
@ -594,7 +624,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
|
||||||
fv.Set(reflect.ValueOf(opt))
|
fv.Set(reflect.ValueOf(opt))
|
||||||
off = off1 + int(optlen)
|
off = off1 + int(optlen)
|
||||||
case "NSEC": // NSEC/NSEC3
|
case "NSEC": // NSEC/NSEC3
|
||||||
// Rest of the Record it the type bitmap
|
// Rest of the Record is the type bitmap
|
||||||
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
||||||
rdlength -= (1 + 1 + 2 + len(val.FieldByName("NextDomain").String()) + 1)
|
rdlength -= (1 + 1 + 2 + len(val.FieldByName("NextDomain").String()) + 1)
|
||||||
if off+1 > lenmsg {
|
if off+1 > lenmsg {
|
||||||
|
|
55
update.go
55
update.go
|
@ -11,13 +11,13 @@
|
||||||
//
|
//
|
||||||
// 3.2.4 - Table Of Metavalues Used In Prerequisite Section
|
// 3.2.4 - Table Of Metavalues Used In Prerequisite Section
|
||||||
//
|
//
|
||||||
// CLASS TYPE RDATA Meaning Function
|
// CLASS TYPE RDATA Meaning Function
|
||||||
// ----------------------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
// ANY ANY empty Name is in use NameUsed
|
// ANY ANY empty Name is in use NameUsed
|
||||||
// ANY rrset empty RRset exists (value independent) RRsetUsedNoRdata
|
// ANY rrset empty RRset exists (value indep) RRsetUsedNoRdata
|
||||||
// NONE ANY empty Name is not in use NameNotUsed
|
// NONE ANY empty Name is not in use NameNotUsed
|
||||||
// NONE rrset empty RRset does not exist RRsetNotUsed
|
// NONE rrset empty RRset does not exist RRsetNotUsed
|
||||||
// zone rrset rr RRset exists (value dependent) RRsetUsedRdata
|
// zone rrset rr RRset exists (value dep) RRsetUsedRdata
|
||||||
//
|
//
|
||||||
// The prerequisite section can also be left empty.
|
// The prerequisite section can also be left empty.
|
||||||
// If you have decided an the prerequisites you can tell what RRs should
|
// If you have decided an the prerequisites you can tell what RRs should
|
||||||
|
@ -25,16 +25,17 @@
|
||||||
// what function to call.
|
// what function to call.
|
||||||
// 3.4.2.6 - Table Of Metavalues Used In Update Section
|
// 3.4.2.6 - Table Of Metavalues Used In Update Section
|
||||||
//
|
//
|
||||||
// CLASS TYPE RDATA Meaning Function
|
// CLASS TYPE RDATA Meaning Function
|
||||||
// -------------------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// ANY ANY empty Delete all RRsets from a name NameDelete
|
// ANY ANY empty Delete all RRsets from name NameDelete
|
||||||
// ANY rrset empty Delete an RRset RRsetDelete
|
// ANY rrset empty Delete an RRset RRsetDelete
|
||||||
// NONE rrset rr Delete an RR from an RRset RRsetDeleteRR
|
// NONE rrset rr Delete an RR from RRset RRsetDeleteRR
|
||||||
// zone rrset rr Add to an RRset RRsetAddRdata
|
// zone rrset rr Add to an RRset RRsetAddRdata
|
||||||
//
|
//
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
// NewUpdate creates a new DNS update packet, which is a normal DNS message.
|
// NewUpdate creates a new DNS update packet. This returns a normal
|
||||||
|
// dns *Msg, but sets some options.
|
||||||
func NewUpdate(zone string, class uint16) *Msg {
|
func NewUpdate(zone string, class uint16) *Msg {
|
||||||
u := new(Msg)
|
u := new(Msg)
|
||||||
u.MsgHdr.Response = false
|
u.MsgHdr.Response = false
|
||||||
|
@ -49,13 +50,13 @@ func NewUpdate(zone string, class uint16) *Msg {
|
||||||
//
|
//
|
||||||
// 3.2.4 - Table Of Metavalues Used In Prerequisite Section
|
// 3.2.4 - Table Of Metavalues Used In Prerequisite Section
|
||||||
//
|
//
|
||||||
// CLASS TYPE RDATA Meaning Function
|
// CLASS TYPE RDATA Meaning Function
|
||||||
// ----------------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// ANY ANY empty Name is in use NameUsed
|
// ANY ANY empty Name is in use NameUsed
|
||||||
// ANY rrset empty RRset exists (value independent) RRsetUsedNoRdata
|
// ANY rrset empty RRset exists (value indep) RRsetUsedNoRdata
|
||||||
// NONE ANY empty Name is not in use NameNotUsed
|
// NONE ANY empty Name is not in use NameNotUsed
|
||||||
// NONE rrset empty RRset does not exist RRsetNotUsed
|
// NONE rrset empty RRset does not exist RRsetNotUsed
|
||||||
// zone rrset rr RRset exists (value dependent) RRsetUsedRdata
|
// zone rrset rr RRset exists (value dep) RRsetUsedRdata
|
||||||
|
|
||||||
// NameUsed sets the RRs in the prereq section to
|
// NameUsed sets the RRs in the prereq section to
|
||||||
// "Name is in use" RRs. RFC 2136 section 2.4.4.
|
// "Name is in use" RRs. RFC 2136 section 2.4.4.
|
||||||
|
@ -116,12 +117,12 @@ func (u *Msg) RRsetNotUsed(rr []RR) {
|
||||||
//
|
//
|
||||||
// 3.4.2.6 - Table Of Metavalues Used In Update Section
|
// 3.4.2.6 - Table Of Metavalues Used In Update Section
|
||||||
//
|
//
|
||||||
// CLASS TYPE RDATA Meaning Function
|
// CLASS TYPE RDATA Meaning Function
|
||||||
// --------------------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
// ANY ANY empty Delete all RRsets from a name NameDelete
|
// ANY ANY empty Delete all RRsets from name NameDelete
|
||||||
// ANY rrset empty Delete an RRset RRsetDelete
|
// ANY rrset empty Delete an RRset RRsetDelete
|
||||||
// NONE rrset rr Delete an RR from an RRset RRsetDeleteRR
|
// NONE rrset rr Delete an RR from RRset RRsetDeleteRR
|
||||||
// zone rrset rr Add to an RRset RRsetAddRdata
|
// zone rrset rr Add to an RRset RRsetAddRdata
|
||||||
|
|
||||||
// RRsetAddRdata adds an complete RRset, see RFC 2136 section 2.5.1
|
// RRsetAddRdata adds an complete RRset, see RFC 2136 section 2.5.1
|
||||||
func (u *Msg) RRsetAddRdata(rr []RR) {
|
func (u *Msg) RRsetAddRdata(rr []RR) {
|
||||||
|
|
Loading…
Reference in New Issue