Tsig fixes

make tsig easier to use and even transparant when using the API
This commit is contained in:
Miek Gieben 2011-09-11 01:10:47 +02:00
parent 356b532385
commit 3be73fcea9
4 changed files with 31 additions and 36 deletions

View File

@ -346,7 +346,7 @@ func (w *reply) readClient(p []byte) (n int, err os.Error) {
return
}
// Send a msg to the address specified in w.
// Send sends a dns msg to the address specified in w.
// If the message m contains a TSIG record the transaction
// signature is calculated.
func (w *reply) Send(m *Msg) os.Error {
@ -356,8 +356,10 @@ func (w *reply) Send(m *Msg) os.Error {
if !ok {
return ErrSecret
}
m, _ = TsigGenerate(m, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly)
w.tsigRequestMAC = m.Extra[len(m.Extra)-1].(*RR_TSIG).MAC // Save the requestMAC
if err := TsigGenerate(m, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly); err != nil {
return err
}
w.tsigRequestMAC = m.Extra[len(m.Extra)-1].(*RR_TSIG).MAC // Save the requestMAC for the next packet
}
out, ok := m.Pack()
if !ok {

View File

@ -81,9 +81,11 @@ func TestClientTsigAXFR(t *testing.T) {
m.SetAxfr("miek.nl")
m.SetTsig("axfr", HmacMD5, 300, uint64(time.Seconds()))
TsigGenerate(m, "so6ZGir4GPAqINNh9U5c3A==", "", false)
secrets := make(map[string]string)
secrets["axfr"] = "so6ZGir4GPAqINNh9U5c3A=="
println(m.String())
c := NewClient()
c.Net = "tcp"
c.TsigSecret = secrets

View File

@ -80,12 +80,15 @@ func (dns *Msg) SetAxfr(z string) {
dns.Question[0] = Question{z, TypeAXFR, ClassINET}
}
// SetTsig Calculates and appends a TSIG RR to the message.
// SetTsig appends a TSIG RR to the message.
// This is only a skeleton Tsig RR that added as the last RR in the
// additional section. The caller should then call TsigGenerate,
// to generate the complete TSIG from the secret.
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64) {
t := new(RR_TSIG)
t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
t.Algorithm = algo
t.Fudge = fudge
t.Fudge = 300
t.TimeSigned = timesigned
dns.Extra = append(dns.Extra, t)
}
@ -160,7 +163,8 @@ func (dns *Msg) IsIxfr() (ok bool) {
return
}
// IsTsig checks if the message has a TSIG record as the last record.
// IsTsig checks if the message has a TSIG record as the last record
// in the additional section.
func (dns *Msg) IsTsig() (ok bool) {
if len(dns.Extra) > 0 {
return dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG

47
tsig.go
View File

@ -54,24 +54,23 @@ type timerWireFmt struct {
// TsigGenerate add add TSIG RR to a message. The TSIG MAC is saved
// in the Tsig RR that is added. When TsigGenerate is called for the
// first time requestMAC is generaly set to the empty string. TODO(mg): Really?
// If something went wrong an error is returned, otherwise nil.
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) (*Msg, os.Error) {
// first time requestMAC is set to the empty string.
// If something goes wrong an error is returned, otherwise it is nil.
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) os.Error {
if !m.IsTsig() {
// panic? panic?
panic("TSIG not last RR in additional")
}
// If we barf here, the caller is to blame
rawsecret, err := packBase64([]byte(secret))
if err != nil {
return nil, err
}
if err != nil {
return err
}
rr := m.Extra[len(m.Extra)-1].(*RR_TSIG)
m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
mbuf, _ := m.Pack()
buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
if err != nil {
return nil, err
}
buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
t := new(RR_TSIG)
@ -88,7 +87,7 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) (*Msg, os.
t.OrigId = m.MsgHdr.Id
m.Extra = append(m.Extra, t)
return m, nil
return nil
}
// TsigVerify verifies the TSIG on a message.
@ -105,10 +104,7 @@ func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) os.Error
return err
}
buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
if err != nil {
return err
}
buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
/*
if t.Name != "" {
if t.Name != dns.Extra[i].Header().Name {
@ -137,7 +133,7 @@ func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) os.Error
}
// Create a wiredata buffer for the MAC calculation.
func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool) ([]byte, os.Error) {
func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool) []byte {
var (
macbuf []byte
buf []byte
@ -146,7 +142,7 @@ func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool)
rr.TimeSigned = uint64(time.Seconds())
}
if rr.Fudge == 0 {
rr.Fudge = 300
rr.Fudge = 300 // Standard (RFC) default.
}
if requestMAC != "" {
@ -154,10 +150,7 @@ func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool)
m.MACSize = uint16(len(requestMAC) / 2)
m.MAC = requestMAC
macbuf = make([]byte, len(requestMAC)) // reqmac should be twice as long
n, ok := packStruct(m, macbuf, 0)
if !ok {
return nil, ErrSigGen
}
n, _ := packStruct(m, macbuf, 0)
macbuf = macbuf[:n]
}
@ -166,10 +159,7 @@ func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool)
tsig := new(timerWireFmt)
tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = rr.Fudge
n, ok1 := packStruct(tsig, tsigvar, 0)
if !ok1 {
return nil, ErrSigGen
}
n, _ := packStruct(tsig, tsigvar, 0)
tsigvar = tsigvar[:n]
} else {
tsig := new(tsigWireFmt)
@ -182,10 +172,7 @@ func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool)
tsig.Error = rr.Error
tsig.OtherLen = rr.OtherLen
tsig.OtherData = rr.OtherData
n, ok1 := packStruct(tsig, tsigvar, 0)
if !ok1 {
return nil, ErrSigGen
}
n, _ := packStruct(tsig, tsigvar, 0)
tsigvar = tsigvar[:n]
}
if rr.MAC != "" {
@ -194,7 +181,7 @@ func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool)
} else {
buf = append(msgbuf, tsigvar...)
}
return buf, nil
return buf
}
// Strip the TSIG from the raw message