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:
|
||||
|
||||
* UDP/TCP queries, IPv4 and IPv6;
|
||||
* TSIG;
|
||||
* EDNS0;
|
||||
* AXFR/IXFR;
|
||||
* DNS name compression;
|
||||
* Client and server side programming (mimicking the http package);
|
||||
* Asynchronous queries for client and server;
|
||||
* DNSSEC;
|
||||
* EDNS0;
|
||||
* AXFR/IXFR;
|
||||
* TSIG;
|
||||
* DNS name compression;
|
||||
* RFC 1035 zone file parsing.
|
||||
|
||||
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
|
||||
* 4892 - id.server
|
||||
* 5001 - NSID
|
||||
* 5155 - NSEC
|
||||
* 5155 - NSEC3
|
||||
* 5933 - GOST
|
||||
* 5936 - AXFR
|
||||
* xxxx - ECDSA
|
||||
|
|
|
@ -75,12 +75,28 @@ func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
|
|||
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()
|
||||
fmt.Printf("%v\n", m.String())
|
||||
if !ok {
|
||||
log.Print("Packing failed")
|
||||
//write formerr back?
|
||||
return
|
||||
m.SetRcode(r, dns.RcodeServerFailure)
|
||||
m.Extra = nil
|
||||
m.Answer = nil
|
||||
b, _ = m.Pack()
|
||||
}
|
||||
w.Write(b)
|
||||
}
|
||||
|
|
54
msg.go
54
msg.go
|
@ -16,6 +16,7 @@ import (
|
|||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"reflect"
|
||||
|
@ -408,11 +409,34 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
|||
off++
|
||||
}
|
||||
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++ {
|
||||
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
|
||||
// TODO(mg)
|
||||
// off++
|
||||
println("off", off)
|
||||
}
|
||||
case reflect.Struct:
|
||||
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 {
|
||||
default:
|
||||
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":
|
||||
b64, err := packBase64([]byte(s))
|
||||
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)
|
||||
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":
|
||||
fallthrough
|
||||
case "hex":
|
||||
|
@ -594,7 +624,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
|
|||
fv.Set(reflect.ValueOf(opt))
|
||||
off = off1 + int(optlen)
|
||||
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 -= (1 + 1 + 2 + len(val.FieldByName("NextDomain").String()) + 1)
|
||||
if off+1 > lenmsg {
|
||||
|
|
55
update.go
55
update.go
|
@ -11,13 +11,13 @@
|
|||
//
|
||||
// 3.2.4 - Table Of Metavalues Used In Prerequisite Section
|
||||
//
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// ----------------------------------------------------------------------------
|
||||
// ANY ANY empty Name is in use NameUsed
|
||||
// ANY rrset empty RRset exists (value independent) RRsetUsedNoRdata
|
||||
// NONE ANY empty Name is not in use NameNotUsed
|
||||
// NONE rrset empty RRset does not exist RRsetNotUsed
|
||||
// zone rrset rr RRset exists (value dependent) RRsetUsedRdata
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// --------------------------------------------------------------
|
||||
// ANY ANY empty Name is in use NameUsed
|
||||
// ANY rrset empty RRset exists (value indep) RRsetUsedNoRdata
|
||||
// NONE ANY empty Name is not in use NameNotUsed
|
||||
// NONE rrset empty RRset does not exist RRsetNotUsed
|
||||
// zone rrset rr RRset exists (value dep) RRsetUsedRdata
|
||||
//
|
||||
// The prerequisite section can also be left empty.
|
||||
// If you have decided an the prerequisites you can tell what RRs should
|
||||
|
@ -25,16 +25,17 @@
|
|||
// what function to call.
|
||||
// 3.4.2.6 - Table Of Metavalues Used In Update Section
|
||||
//
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// -------------------------------------------------------------------------
|
||||
// ANY ANY empty Delete all RRsets from a name NameDelete
|
||||
// ANY rrset empty Delete an RRset RRsetDelete
|
||||
// NONE rrset rr Delete an RR from an RRset RRsetDeleteRR
|
||||
// zone rrset rr Add to an RRset RRsetAddRdata
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// ---------------------------------------------------------------
|
||||
// ANY ANY empty Delete all RRsets from name NameDelete
|
||||
// ANY rrset empty Delete an RRset RRsetDelete
|
||||
// NONE rrset rr Delete an RR from RRset RRsetDeleteRR
|
||||
// zone rrset rr Add to an RRset RRsetAddRdata
|
||||
//
|
||||
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 {
|
||||
u := new(Msg)
|
||||
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
|
||||
//
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// ----------------------------------------------------------------------
|
||||
// ANY ANY empty Name is in use NameUsed
|
||||
// ANY rrset empty RRset exists (value independent) RRsetUsedNoRdata
|
||||
// NONE ANY empty Name is not in use NameNotUsed
|
||||
// NONE rrset empty RRset does not exist RRsetNotUsed
|
||||
// zone rrset rr RRset exists (value dependent) RRsetUsedRdata
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// ---------------------------------------------------------------
|
||||
// ANY ANY empty Name is in use NameUsed
|
||||
// ANY rrset empty RRset exists (value indep) RRsetUsedNoRdata
|
||||
// NONE ANY empty Name is not in use NameNotUsed
|
||||
// NONE rrset empty RRset does not exist RRsetNotUsed
|
||||
// zone rrset rr RRset exists (value dep) RRsetUsedRdata
|
||||
|
||||
// NameUsed sets the RRs in the prereq section to
|
||||
// "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
|
||||
//
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// --------------------------------------------------------------------------
|
||||
// ANY ANY empty Delete all RRsets from a name NameDelete
|
||||
// ANY rrset empty Delete an RRset RRsetDelete
|
||||
// NONE rrset rr Delete an RR from an RRset RRsetDeleteRR
|
||||
// zone rrset rr Add to an RRset RRsetAddRdata
|
||||
// CLASS TYPE RDATA Meaning Function
|
||||
// -----------------------------------------------------------------
|
||||
// ANY ANY empty Delete all RRsets from name NameDelete
|
||||
// ANY rrset empty Delete an RRset RRsetDelete
|
||||
// NONE rrset rr Delete an RR from RRset RRsetDeleteRR
|
||||
// zone rrset rr Add to an RRset RRsetAddRdata
|
||||
|
||||
// RRsetAddRdata adds an complete RRset, see RFC 2136 section 2.5.1
|
||||
func (u *Msg) RRsetAddRdata(rr []RR) {
|
||||
|
|
Loading…
Reference in New Issue