Fix zonesigning branch

This commit is contained in:
Miek Gieben 2012-12-09 20:16:46 +01:00
parent 940b786161
commit f56b237012
2 changed files with 28 additions and 29 deletions

8
msg.go
View File

@ -932,7 +932,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er
case `dns:"size-base32"`: case `dns:"size-base32"`:
var size int var size int
switch val.Type().Name() { switch val.Type().Name() {
case "RR_NSEC3": case "NSEC3":
switch val.Type().Field(i).Name { switch val.Type().Field(i).Name {
case "NextDomain": case "NextDomain":
name := val.FieldByName("HashLength") name := val.FieldByName("HashLength")
@ -948,7 +948,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er
// a "size" string, but it must be encoded in hex in the string // a "size" string, but it must be encoded in hex in the string
var size int var size int
switch val.Type().Name() { switch val.Type().Name() {
case "RR_NSEC3": case "NSEC3":
switch val.Type().Field(i).Name { switch val.Type().Field(i).Name {
case "Salt": case "Salt":
name := val.FieldByName("SaltLength") name := val.FieldByName("SaltLength")
@ -957,7 +957,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er
name := val.FieldByName("HashLength") name := val.FieldByName("HashLength")
size = int(name.Uint()) size = int(name.Uint())
} }
case "RR_TSIG": case "TSIG":
switch val.Type().Field(i).Name { switch val.Type().Field(i).Name {
case "MAC": case "MAC":
name := val.FieldByName("MACSize") name := val.FieldByName("MACSize")
@ -1085,7 +1085,7 @@ func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
// make an rr of that type and re-unpack. // make an rr of that type and re-unpack.
mk, known := rr_mk[h.Rrtype] mk, known := rr_mk[h.Rrtype]
if !known { if !known {
rr = new(RR_RFC3597) rr = new(RFC3597)
} else { } else {
rr = mk() rr = mk()
} }

49
zone.go
View File

@ -92,8 +92,7 @@ func NewZone(origin string) *Zone {
type ZoneData struct { type ZoneData struct {
Name string // Domain name for this node Name string // Domain name for this node
RR map[uint16][]RR // Map of the RR type to the RR RR map[uint16][]RR // Map of the RR type to the RR
Signatures map[uint16][]*RR_RRSIG // DNSSEC signatures for the RRs, stored under type covered Signatures map[uint16][]*RRSIG // DNSSEC signatures for the RRs, stored under type covered
// moet een map[uint16]map[uint16]*RR_RRSIG worden, typeocvert + keyid
NonAuth bool // Always false, except for NSsets that differ from z.Origin NonAuth bool // Always false, except for NSsets that differ from z.Origin
*sync.RWMutex *sync.RWMutex
} }
@ -103,7 +102,7 @@ func NewZoneData(s string) *ZoneData {
zd := new(ZoneData) zd := new(ZoneData)
zd.Name = s zd.Name = s
zd.RR = make(map[uint16][]RR) zd.RR = make(map[uint16][]RR)
zd.Signatures = make(map[uint16][]*RR_RRSIG) zd.Signatures = make(map[uint16][]*RRSIG)
zd.RWMutex = new(sync.RWMutex) zd.RWMutex = new(sync.RWMutex)
return zd return zd
} }
@ -215,8 +214,8 @@ func (z *Zone) Insert(r RR) error {
zd := NewZoneData(r.Header().Name) zd := NewZoneData(r.Header().Name)
switch t := r.Header().Rrtype; t { switch t := r.Header().Rrtype; t {
case TypeRRSIG: case TypeRRSIG:
sigtype := r.(*RR_RRSIG).TypeCovered sigtype := r.(*RRSIG).TypeCovered
zd.Signatures[sigtype] = append(zd.Signatures[sigtype], r.(*RR_RRSIG)) zd.Signatures[sigtype] = append(zd.Signatures[sigtype], r.(*RRSIG))
case TypeNS: case TypeNS:
// NS records with other names than z.Origin are non-auth // NS records with other names than z.Origin are non-auth
if r.Header().Name != z.Origin { if r.Header().Name != z.Origin {
@ -235,8 +234,8 @@ func (z *Zone) Insert(r RR) error {
// Name already there // Name already there
switch t := r.Header().Rrtype; t { switch t := r.Header().Rrtype; t {
case TypeRRSIG: case TypeRRSIG:
sigtype := r.(*RR_RRSIG).TypeCovered sigtype := r.(*RRSIG).TypeCovered
zd.Value.(*ZoneData).Signatures[sigtype] = append(zd.Value.(*ZoneData).Signatures[sigtype], r.(*RR_RRSIG)) zd.Value.(*ZoneData).Signatures[sigtype] = append(zd.Value.(*ZoneData).Signatures[sigtype], r.(*RRSIG))
case TypeNS: case TypeNS:
if r.Header().Name != z.Origin { if r.Header().Name != z.Origin {
zd.Value.(*ZoneData).NonAuth = true zd.Value.(*ZoneData).NonAuth = true
@ -265,7 +264,7 @@ func (z *Zone) Remove(r RR) error {
remove := false remove := false
switch t := r.Header().Rrtype; t { switch t := r.Header().Rrtype; t {
case TypeRRSIG: case TypeRRSIG:
sigtype := r.(*RR_RRSIG).TypeCovered sigtype := r.(*RRSIG).TypeCovered
for i, zr := range zd.Value.(*ZoneData).Signatures[sigtype] { for i, zr := range zd.Value.(*ZoneData).Signatures[sigtype] {
if r == zr { if r == zr {
zd.Value.(*ZoneData).Signatures[sigtype] = append(zd.Value.(*ZoneData).Signatures[sigtype][:i], zd.Value.(*ZoneData).Signatures[sigtype][i+1:]...) zd.Value.(*ZoneData).Signatures[sigtype] = append(zd.Value.(*ZoneData).Signatures[sigtype][:i], zd.Value.(*ZoneData).Signatures[sigtype][i+1:]...)
@ -359,7 +358,7 @@ func (z *Zone) RemoveRRset(s string, t uint16) error {
// apex can not be found (thereby making it an illegal DNS zone) it returns nil. // apex can not be found (thereby making it an illegal DNS zone) it returns nil.
// Updating the zone's SOA serial, provided the apex exists: // Updating the zone's SOA serial, provided the apex exists:
// //
// z.Apex.RR[TypeSOA][0].(*RR_SOA).Serial++ // z.Apex.RR[TypeSOA][0].(*SOA).Serial++
// //
// Note the a) this increment is not protected by locks and b) if you use DNSSEC // Note the a) this increment is not protected by locks and b) if you use DNSSEC
// you MUST resign the SOA record. // you MUST resign the SOA record.
@ -416,12 +415,12 @@ func (z *Zone) isSubDomain(child string) bool {
// Basic use pattern for signing a zone with the default SignatureConfig: // Basic use pattern for signing a zone with the default SignatureConfig:
// //
// // A single PublicKey/PrivateKey have been read from disk. // // A single PublicKey/PrivateKey have been read from disk.
// e := z.Sign(map[*dns.RR_DNSKEY]dns.PrivateKey{pubkey.(*dns.RR_DNSKEY): privkey}, nil) // e := z.Sign(map[*dns.DNSKEY]dns.PrivateKey{pubkey.(*dns.DNSKEY): privkey}, nil)
// if e != nil { // if e != nil {
// // signing error // // signing error
// } // }
// // Admire your signed zone... // // Admire your signed zone...
func (z *Zone) Sign(keys map[*RR_DNSKEY]PrivateKey, config *SignatureConfig) error { func (z *Zone) Sign(keys map[*DNSKEY]PrivateKey, config *SignatureConfig) error {
z.Lock() z.Lock()
z.ModTime = time.Now().UTC() z.ModTime = time.Now().UTC()
defer z.Unlock() defer z.Unlock()
@ -429,7 +428,7 @@ func (z *Zone) Sign(keys map[*RR_DNSKEY]PrivateKey, config *SignatureConfig) err
config = DefaultSignatureConfig config = DefaultSignatureConfig
} }
// Pre-calc the key tag // Pre-calc the key tag
keytags := make(map[*RR_DNSKEY]uint16) keytags := make(map[*DNSKEY]uint16)
for k, _ := range keys { for k, _ := range keys {
keytags[k] = k.KeyTag() keytags[k] = k.KeyTag()
} }
@ -448,7 +447,7 @@ func (z *Zone) Sign(keys map[*RR_DNSKEY]PrivateKey, config *SignatureConfig) err
if !e { if !e {
return ErrSoa return ErrSoa
} }
config.Minttl = apex.Value.(*ZoneData).RR[TypeSOA][0].(*RR_SOA).Minttl config.Minttl = apex.Value.(*ZoneData).RR[TypeSOA][0].(*SOA).Minttl
next := apex.Next() next := apex.Next()
radChan <- apex radChan <- apex
@ -473,7 +472,7 @@ Sign:
} }
// signerRoutine is a small helper routine to make the concurrent signing work. // signerRoutine is a small helper routine to make the concurrent signing work.
func signerRoutine(wg *sync.WaitGroup, keys map[*RR_DNSKEY]PrivateKey, keytags map[*RR_DNSKEY]uint16, config *SignatureConfig, in chan *radix.Radix, err chan error) { func signerRoutine(wg *sync.WaitGroup, keys map[*DNSKEY]PrivateKey, keytags map[*DNSKEY]uint16, config *SignatureConfig, in chan *radix.Radix, err chan error) {
defer wg.Done() defer wg.Done()
for { for {
select { select {
@ -496,7 +495,7 @@ func signerRoutine(wg *sync.WaitGroup, keys map[*RR_DNSKEY]PrivateKey, keytags m
// For a more complete description see zone.Sign. // For a more complete description see zone.Sign.
// Note, because this method has no (direct) // Note, because this method has no (direct)
// access to the zone's SOA record, the SOA's Minttl value should be set in *config. // access to the zone's SOA record, the SOA's Minttl value should be set in *config.
func (node *ZoneData) Sign(next string, keys map[*RR_DNSKEY]PrivateKey, keytags map[*RR_DNSKEY]uint16, config *SignatureConfig) error { func (node *ZoneData) Sign(next string, keys map[*DNSKEY]PrivateKey, keytags map[*DNSKEY]uint16, config *SignatureConfig) error {
node.Lock() node.Lock()
defer node.Unlock() defer node.Unlock()
@ -508,7 +507,7 @@ func (node *ZoneData) Sign(next string, keys map[*RR_DNSKEY]PrivateKey, keytags
// Check if the current (if available) nsec has these types too // Check if the current (if available) nsec has these types too
// Grr O(n^2) // Grr O(n^2)
found := false found := false
for _, v := range n[0].(*RR_NSEC).TypeBitMap { for _, v := range n[0].(*NSEC).TypeBitMap {
if v == t { if v == t {
found = true found = true
break break
@ -534,14 +533,14 @@ func (node *ZoneData) Sign(next string, keys map[*RR_DNSKEY]PrivateKey, keytags
// There is an NSEC, check if it still points to the correct next node. // There is an NSEC, check if it still points to the correct next node.
// Secondly the type bitmap may have changed. // Secondly the type bitmap may have changed.
// TODO(mg): actually checked the types in the map // TODO(mg): actually checked the types in the map
if n[0].(*RR_NSEC).NextDomain != next || !bitmapEqual { if n[0].(*NSEC).NextDomain != next || !bitmapEqual {
n[0].(*RR_NSEC).NextDomain = next n[0].(*NSEC).NextDomain = next
n[0].(*RR_NSEC).TypeBitMap = bitmap n[0].(*NSEC).TypeBitMap = bitmap
node.Signatures[TypeNSEC] = nil // drop all sigs node.Signatures[TypeNSEC] = nil // drop all sigs
} }
} else { } else {
// No NSEC at all, create one // No NSEC at all, create one
nsec := &RR_NSEC{Hdr: RR_Header{node.Name, TypeNSEC, ClassINET, config.Minttl, 0}, NextDomain: next} nsec := &NSEC{Hdr: RR_Header{node.Name, TypeNSEC, ClassINET, config.Minttl, 0}, NextDomain: next}
nsec.TypeBitMap = bitmap nsec.TypeBitMap = bitmap
node.RR[TypeNSEC] = []RR{nsec} node.RR[TypeNSEC] = []RR{nsec}
node.Signatures[TypeNSEC] = nil // drop all sigs (just in case) node.Signatures[TypeNSEC] = nil // drop all sigs (just in case)
@ -552,14 +551,14 @@ func (node *ZoneData) Sign(next string, keys map[*RR_DNSKEY]PrivateKey, keytags
for k, p := range keys { for k, p := range keys {
for t, rrset := range node.RR { for t, rrset := range node.RR {
if k.Flags&SEP == SEP { if k.Flags&SEP == SEP {
if _, ok := rrset[0].(*RR_DNSKEY); !ok { if _, ok := rrset[0].(*DNSKEY); !ok {
// only sign keys with SEP keys // only sign keys with SEP keys
continue continue
} }
} }
if node.NonAuth == true { if node.NonAuth == true {
_, ok1 := rrset[0].(*RR_DS) _, ok1 := rrset[0].(*DS)
_, ok2 := rrset[0].(*RR_NSEC) _, ok2 := rrset[0].(*NSEC)
if !ok1 && !ok2 { if !ok1 && !ok2 {
continue continue
} }
@ -567,7 +566,7 @@ func (node *ZoneData) Sign(next string, keys map[*RR_DNSKEY]PrivateKey, keytags
j, q := signatures(node.Signatures[t], keytags[k]) j, q := signatures(node.Signatures[t], keytags[k])
if q == nil || now.Sub(uint32ToTime(q.Expiration)) < config.Refresh { // no there, are almost expired if q == nil || now.Sub(uint32ToTime(q.Expiration)) < config.Refresh { // no there, are almost expired
s := new(RR_RRSIG) s := new(RRSIG)
s.SignerName = k.Hdr.Name s.SignerName = k.Hdr.Name
s.Hdr.Ttl = k.Hdr.Ttl s.Hdr.Ttl = k.Hdr.Ttl
s.Hdr.Class = ClassINET s.Hdr.Class = ClassINET
@ -602,7 +601,7 @@ func (node *ZoneData) Sign(next string, keys map[*RR_DNSKEY]PrivateKey, keytags
// Return the signature for the typecovered and make with the keytag. It // Return the signature for the typecovered and make with the keytag. It
// returns the index of the RRSIG and the RRSIG itself. // returns the index of the RRSIG and the RRSIG itself.
func signatures(signatures []*RR_RRSIG, keytag uint16) (int, *RR_RRSIG) { func signatures(signatures []*RRSIG, keytag uint16) (int, *RRSIG) {
for i, s := range signatures { for i, s := range signatures {
if s.KeyTag == keytag { if s.KeyTag == keytag {
return i, s return i, s