TSIG works for AXFR (also with multiple message envelopes)

This commit is contained in:
Miek Gieben 2011-03-15 19:36:03 +01:00
parent b56344d41d
commit e78ef64a54
3 changed files with 52 additions and 35 deletions

4
TODO
View File

@ -2,10 +2,7 @@ Todo:
* Private key file parsing use io.Reader (or the like) - NewReader, NewWriter? * Private key file parsing use io.Reader (or the like) - NewReader, NewWriter?
* Parsing from strings, going with goyacc and .cz lexer? * Parsing from strings, going with goyacc and .cz lexer?
* encoding NSEC3/NSEC bitmaps, DEcoding works * encoding NSEC3/NSEC bitmaps, DEcoding works
* AXFR/IXFR with TSIG validation
* Failed Xfr triggers nil error?
* Use callback in IXFR/AXFR to make tsig happen (and other cool stuff in FunkenSturm) * Use callback in IXFR/AXFR to make tsig happen (and other cool stuff in FunkenSturm)
* A New for all type with some defaults filled in
* Take a good look at hash.Hash take over the digest sizes and names * Take a good look at hash.Hash take over the digest sizes and names
* HIP RR (needs list of domain names, need slice stuff for that) * HIP RR (needs list of domain names, need slice stuff for that)
@ -13,6 +10,7 @@ Issues:
* Check the network order, it works now, but this is on Intel?? * Check the network order, it works now, but this is on Intel??
* Make the testsuite work with public DNS servers * Make the testsuite work with public DNS servers
* pack/Unpack smaller. EDNS 'n stuff can be folded in * pack/Unpack smaller. EDNS 'n stuff can be folded in
* SetDefaults() for *all* types?
Examples: Examples:
* Test impl of nameserver, with a small zone, 1 KSK and online signing * Test impl of nameserver, with a small zone, 1 KSK and online signing

View File

@ -293,12 +293,13 @@ Server:
if tsig && len(in.Extra) > 0 { // What if not included? if tsig && len(in.Extra) > 0 { // What if not included?
t := in.Extra[len(in.Extra)-1] t := in.Extra[len(in.Extra)-1]
switch t.(type) { if t.Header().Rrtype == TypeTSIG {
case *RR_TSIG: if t.(*RR_TSIG).Verify(inb, secret, reqmac, first) {
if t.(*RR_TSIG).Verify(inb, secret, reqmac) { println("Validates!!!!!")
println("Validates") // Set the MAC for the next round.
reqmac = t.(*RR_TSIG).MAC
} else { } else {
println("DOES NOT validate") println("DOES NOT validate :-(")
} }
} }
} }

72
tsig.go
View File

@ -73,12 +73,19 @@ type tsigWireFmt struct {
OtherData string "size-hex" OtherData string "size-hex"
} }
// If we have the MAC use this type to convert it to wiredata // If we have the MAC use this type to convert it to wiredata.
// Section 3.4.3. Request MAC
type macWireFmt struct { type macWireFmt struct {
MACSize uint16 MACSize uint16
MAC string "size-hex" MAC string "size-hex"
} }
// 3.3. Time values used in TSIG calculations
type timerWireFmt struct {
TimeSigned uint64
Fudge uint16
}
// Generate the HMAC for message. The TSIG RR is modified // Generate the HMAC for message. The TSIG RR is modified
// to include the MAC and MACSize. Note the the msg Id must // to include the MAC and MACSize. Note the the msg Id must
// already be set, otherwise the MAC will not be correct when // already be set, otherwise the MAC will not be correct when
@ -92,13 +99,13 @@ func (t *RR_TSIG) Generate(m *Msg, secret string) bool {
t.OrigId = m.MsgHdr.Id t.OrigId = m.MsgHdr.Id
msg, ok := m.Pack() msg, ok := m.Pack()
if !ok { if !ok {
return false return false
} }
buf, ok1 := tsigToBuf(t, msg, "") buf, ok1 := tsigToBuf(t, msg, "", true)
if !ok1 { if !ok1 {
return false return false
} }
h := hmac.NewMD5([]byte(rawsecret)) h := hmac.NewMD5([]byte(rawsecret))
io.WriteString(h, string(buf)) io.WriteString(h, string(buf))
@ -114,7 +121,7 @@ func (t *RR_TSIG) Generate(m *Msg, secret string) bool {
// the TSIG record still attached (as the last rr in the Additional // the TSIG record still attached (as the last rr in the Additional
// section). Return true on success. // section). Return true on success.
// The secret is a base64 encoded string with the secret. // The secret is a base64 encoded string with the secret.
func (t *RR_TSIG) Verify(msg []byte, secret, reqmac string) bool { func (t *RR_TSIG) Verify(msg []byte, secret, reqmac string, timers bool) bool {
rawsecret, err := packBase64([]byte(secret)) rawsecret, err := packBase64([]byte(secret))
if err != nil { if err != nil {
return false return false
@ -129,7 +136,7 @@ func (t *RR_TSIG) Verify(msg []byte, secret, reqmac string) bool {
if !ok { if !ok {
return false return false
} }
buf, ok := tsigToBuf(t, stripped, reqmac) buf, ok := tsigToBuf(t, stripped, reqmac, timers)
if !ok { if !ok {
return false return false
} }
@ -140,10 +147,10 @@ func (t *RR_TSIG) Verify(msg []byte, secret, reqmac string) bool {
} }
// Create the buffer which we use for the MAC calculation. // Create the buffer which we use for the MAC calculation.
func tsigToBuf(rr *RR_TSIG, msg []byte, reqmac string) ([]byte, bool) { func tsigToBuf(rr *RR_TSIG, msg []byte, reqmac string, timers bool) ([]byte, bool) {
var ( var (
macbuf []byte macbuf []byte
buf []byte buf []byte
) )
if reqmac != "" { if reqmac != "" {
@ -159,21 +166,32 @@ func tsigToBuf(rr *RR_TSIG, msg []byte, reqmac string) ([]byte, bool) {
} }
tsigvar := make([]byte, DefaultMsgSize) tsigvar := make([]byte, DefaultMsgSize)
tsig := new(tsigWireFmt) if timers {
tsig.Name = strings.ToLower(rr.Header().Name) tsig := new(tsigWireFmt)
tsig.Class = rr.Header().Class tsig.Name = strings.ToLower(rr.Header().Name)
tsig.Ttl = rr.Header().Ttl tsig.Class = rr.Header().Class
tsig.Algorithm = strings.ToLower(rr.Algorithm) tsig.Ttl = rr.Header().Ttl
tsig.TimeSigned = rr.TimeSigned tsig.Algorithm = strings.ToLower(rr.Algorithm)
tsig.Fudge = rr.Fudge tsig.TimeSigned = rr.TimeSigned
tsig.Error = rr.Error tsig.Fudge = rr.Fudge
tsig.OtherLen = rr.OtherLen tsig.Error = rr.Error
tsig.OtherData = rr.OtherData tsig.OtherLen = rr.OtherLen
n, ok1 := packStruct(tsig, tsigvar, 0) tsig.OtherData = rr.OtherData
if !ok1 { n, ok1 := packStruct(tsig, tsigvar, 0)
return nil, false if !ok1 {
return nil, false
}
tsigvar = tsigvar[:n]
} else {
tsig := new(timerWireFmt)
tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = rr.Fudge
n, ok1 := packStruct(tsig, tsigvar, 0)
if !ok1 {
return nil, false
}
tsigvar = tsigvar[:n]
} }
tsigvar = tsigvar[:n]
if reqmac != "" { if reqmac != "" {
x := append(macbuf, msg...) x := append(macbuf, msg...)
buf = append(x, tsigvar...) buf = append(x, tsigvar...)