From 6e72207318bf3dd311d6ea5f5228b0e2a8ccf542 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sat, 10 Sep 2011 16:50:27 +0200 Subject: [PATCH] Simplify tsig Add a couple of errors, and make the function signature of the tis function more inline with the dnssec ones. --- client.go | 14 ++++++++------ defaults.go | 9 ++++----- msg.go | 2 ++ tsig.go | 26 ++++++++++++++++---------- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/client.go b/client.go index 7a84030d..5935d2fb 100644 --- a/client.go +++ b/client.go @@ -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 { diff --git a/defaults.go b/defaults.go index c8e634f1..4d2e7a1d 100644 --- a/defaults.go +++ b/defaults.go @@ -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 } diff --git a/msg.go b/msg.go index 9fccca80..d7881057 100644 --- a/msg.go +++ b/msg.go @@ -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"} diff --git a/tsig.go b/tsig.go index c02525e9..42378924 100644 --- a/tsig.go +++ b/tsig.go @@ -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.