Simplify tsig

Add a couple of errors, and make the function signature
of the tis function more inline with the dnssec ones.
This commit is contained in:
Miek Gieben 2011-09-10 16:50:27 +02:00
parent caf69b662c
commit 6e72207318
4 changed files with 30 additions and 21 deletions

View File

@ -266,7 +266,7 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, err os.Error) {
return r, nil
}
// Dial connects to the address addr for the networks c.Net
// Dial connects to the address addr for the network set in c.Net
func (w *reply) Dial() os.Error {
conn, err := net.Dial(w.Client().Net, w.addr)
if err != nil {
@ -311,10 +311,12 @@ func (w *reply) Receive() (*Msg, os.Error) {
secret := m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name
_, ok := w.Client().TsigSecret[secret]
if !ok {
return m, ErrNoSig
return m, ErrSecret
}
ok, err := TsigVerify(p, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly)
if !ok {
// Need to work on the original message p, as that was used
// to calculate the tsig.
err := TsigVerify(p, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly)
if err != nil {
return m, err
}
}
@ -371,10 +373,10 @@ func (w *reply) Send(m *Msg) os.Error {
secret := m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name
_, ok := w.Client().TsigSecret[secret]
if !ok {
return ErrNoSig
return ErrSecret
}
m, _ = TsigGenerate(m, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly)
w.tsigRequestMAC = m.Extra[len(m.Extra)-1].(*RR_TSIG).MAC // Safe the requestMAC
w.tsigRequestMAC = m.Extra[len(m.Extra)-1].(*RR_TSIG).MAC // Save the requestMAC
}
out, ok := m.Pack()
if !ok {

View File

@ -60,7 +60,7 @@ func (dns *Msg) SetUpdate(z string) {
dns.Question[0] = Question{z, TypeSOA, ClassINET}
}
// Create a dns msg suitable for requesting an ixfr.
// SetIxfr creates dns msg suitable for requesting an ixfr.
func (dns *Msg) SetIxfr(z string, serial uint32) {
dns.MsgHdr.Id = Id()
dns.Question = make([]Question, 1)
@ -73,14 +73,14 @@ func (dns *Msg) SetIxfr(z string, serial uint32) {
dns.Ns[0] = s
}
// Create a dns msg suitable for requesting an axfr.
// SetAxfr creates dns msg suitable for requesting an ixfr.
func (dns *Msg) SetAxfr(z string) {
dns.MsgHdr.Id = Id()
dns.Question = make([]Question, 1)
dns.Question[0] = Question{z, TypeAXFR, ClassINET}
}
// SetTsig Calculates and appends a TSIG RR on the message.
// SetTsig Calculates and appends a TSIG RR to the message.
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64) {
t := new(RR_TSIG)
t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
@ -90,7 +90,6 @@ func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64) {
dns.Extra = append(dns.Extra, t)
}
// IsRcode checks if the header of the packet has rcode set.
func (dns *Msg) IsRcode(rcode int) (ok bool) {
if len(dns.Question) == 0 {
@ -164,7 +163,7 @@ func (dns *Msg) IsIxfr() (ok bool) {
// IsTsig checks if the message has a TSIG record as the last record.
func (dns *Msg) IsTsig() (ok bool) {
if len(dns.Extra) > 0 {
return dns.Extra[0].Header().Rrtype == TypeTSIG
return dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG
}
return
}

2
msg.go
View File

@ -43,9 +43,11 @@ var (
ErrTime os.Error = &Error{Error: "bad time"}
ErrNoSig os.Error = &Error{Error: "no signature found"}
ErrSig os.Error = &Error{Error: "bad signature"}
ErrSecret os.Error = &Error{Error: "no secret defined"}
ErrSigGen os.Error = &Error{Error: "bad signature generation"}
ErrAuth os.Error = &Error{Error: "bad authentication"}
ErrXfrSoa os.Error = &Error{Error: "no SOA seen"}
ErrXfrLast os.Error = &Error{Error: "last SOA"}
ErrHandle os.Error = &Error{Error: "handle is nil"}
ErrChan os.Error = &Error{Error: "channel is nil"}
ErrName os.Error = &Error{Error: "type not found for name"}

26
tsig.go
View File

@ -52,7 +52,10 @@ type timerWireFmt struct {
Fudge uint16
}
// Add a Tsig to an message. // Must return the mac
// 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) {
if !m.IsTsig() {
panic("TSIG not last RR in additional")
@ -75,8 +78,8 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) (*Msg, os.
h := hmac.NewMD5([]byte(rawsecret))
io.WriteString(h, string(buf))
t.MAC = hex.EncodeToString(h.Sum()) // Size is half!
t.MACSize = uint16(len(t.MAC) / 2)
t.MAC = hex.EncodeToString(h.Sum())
t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
t.Fudge = rr.Fudge
@ -88,23 +91,23 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) (*Msg, os.
return m, nil
}
// Verify the TSIG on a message.
// TsigVerify verifies the TSIG on a message.
// If the signature does not validate err contains the
// error. If it validates err is nil.
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) (bool, os.Error) {
// error, otherwise it is nil.
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) os.Error {
rawsecret, err := packBase64([]byte(secret))
if err != nil {
return false, err
return err
}
// Srtip the TSIG from the incoming msg
stripped, tsig, err := stripTsig(msg)
if err != nil {
return false, err
return err
}
buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
if err != nil {
return false, err
return err
}
/*
if t.Name != "" {
@ -127,7 +130,10 @@ func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) (bool, o
h := hmac.NewMD5([]byte(rawsecret))
io.WriteString(h, string(buf))
return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(tsig.MAC), nil
if (strings.ToUpper(hex.EncodeToString(h.Sum())) != strings.ToUpper(tsig.MAC)) {
return ErrSig
}
return nil
}
// Create a wiredata buffer for the MAC calculation.