mirror of
https://github.com/miekg/dns.git
synced 2025-11-04 20:51:02 +01:00
Add tsig stuff
This commit is contained in:
parent
ab035e636f
commit
2c5184ff11
6
dns.go
6
dns.go
@ -59,7 +59,7 @@ type Conn struct {
|
|||||||
Addr net.Addr
|
Addr net.Addr
|
||||||
|
|
||||||
// If TSIG is used, this holds all the information
|
// If TSIG is used, this holds all the information
|
||||||
Signature *Tsig
|
Tsig *Tsig
|
||||||
|
|
||||||
// Timeout in sec
|
// Timeout in sec
|
||||||
Timeout int
|
Timeout int
|
||||||
@ -108,6 +108,10 @@ func (d *Conn) Read(p []byte) (n int, err os.Error) {
|
|||||||
i += n
|
i += n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if d.Tsig != nil {
|
||||||
|
// Check the TSIG that we should be read
|
||||||
|
d.Tsig.Verify(p)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
112
tsig.go
112
tsig.go
@ -10,6 +10,8 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Structure used in Read/Write lowlevel functions
|
||||||
|
// for TSIG generation and verification.
|
||||||
type Tsig struct {
|
type Tsig struct {
|
||||||
// The name of the key.
|
// The name of the key.
|
||||||
Name string
|
Name string
|
||||||
@ -20,9 +22,12 @@ type Tsig struct {
|
|||||||
Secret string
|
Secret string
|
||||||
// MAC (if known)
|
// MAC (if known)
|
||||||
MAC string
|
MAC string
|
||||||
|
// Request MAC
|
||||||
|
RequestMAC string
|
||||||
|
// Include the timers if true
|
||||||
|
Timers bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// HMAC hashing codes. These are transmitted as domain names.
|
// HMAC hashing codes. These are transmitted as domain names.
|
||||||
const (
|
const (
|
||||||
HmacMD5 = "hmac-md5.sig-alg.reg.int."
|
HmacMD5 = "hmac-md5.sig-alg.reg.int."
|
||||||
@ -99,6 +104,29 @@ type timerWireFmt struct {
|
|||||||
Fudge uint16
|
Fudge uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In a message and out a new message with the tsig
|
||||||
|
// added
|
||||||
|
func (t *Tsig) Generate(msg []byte) ([]byte, bool) {
|
||||||
|
rawsecret, err := packBase64([]byte(t.Secret))
|
||||||
|
if err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
buf, ok := t.Buffer(msg)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
h := hmac.NewMD5([]byte(rawsecret))
|
||||||
|
io.WriteString(h, string(buf))
|
||||||
|
|
||||||
|
t.MAC = hex.EncodeToString(h.Sum()) // Size is half!
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
// okay, create TSIG, add to message
|
||||||
|
return nil, true
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@ -130,6 +158,29 @@ func (t *RR_TSIG) Generate(m *Msg, secret string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify a TSIG on a message. All relevant data should
|
||||||
|
// be set in the Tsig structure.
|
||||||
|
func (t *Tsig) Verify(msg []byte) bool {
|
||||||
|
rawsecret, err := packBase64([]byte(t.Secret))
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Stipped the TSIG from the incoming msg
|
||||||
|
stripped, ok := stripTsig(msg)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, ok := t.Buffer(stripped)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
h := hmac.NewMD5([]byte(rawsecret))
|
||||||
|
io.WriteString(h, string(buf))
|
||||||
|
return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(t.MAC)
|
||||||
|
}
|
||||||
|
|
||||||
// Verify a TSIG. The message should be the complete with
|
// Verify a TSIG. The message should be the complete with
|
||||||
// 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.
|
||||||
@ -145,7 +196,7 @@ func (t *RR_TSIG) Verify(msg []byte, secret, reqmac string, timers bool) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// t.OrigId -- need to check
|
// t.OrigId -- need to check
|
||||||
stripped, ok := stripTSIG(msg)
|
stripped, ok := stripTsig(msg)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -159,6 +210,61 @@ func (t *RR_TSIG) Verify(msg []byte, secret, reqmac string, timers bool) bool {
|
|||||||
return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(t.MAC)
|
return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(t.MAC)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a wiredata buffer for the MAC calculation
|
||||||
|
func (t *Tsig) Buffer(msg []byte) ([]byte, bool) {
|
||||||
|
var (
|
||||||
|
macbuf []byte
|
||||||
|
buf []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
if t.RequestMAC != "" {
|
||||||
|
m := new(macWireFmt)
|
||||||
|
m.MACSize = uint16(len(t.RequestMAC) / 2)
|
||||||
|
m.MAC = t.RequestMAC
|
||||||
|
macbuf = make([]byte, len(t.RequestMAC)) // reqmac should be twice as long
|
||||||
|
n, ok := packStruct(m, macbuf, 0)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
macbuf = macbuf[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
tsigvar := make([]byte, DefaultMsgSize)
|
||||||
|
if t.Timers {
|
||||||
|
tsig := new(tsigWireFmt)
|
||||||
|
tsig.Name = strings.ToLower(t.Name)
|
||||||
|
tsig.Class = ClassANY
|
||||||
|
tsig.Ttl = 0
|
||||||
|
tsig.Algorithm = strings.ToLower(t.Algorithm)
|
||||||
|
tsig.TimeSigned = t.TimeSigned
|
||||||
|
tsig.Fudge = t.Fudge
|
||||||
|
tsig.Error = 0
|
||||||
|
tsig.OtherLen = 0
|
||||||
|
tsig.OtherData = ""
|
||||||
|
n, ok1 := packStruct(tsig, tsigvar, 0)
|
||||||
|
if !ok1 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
tsigvar = tsigvar[:n]
|
||||||
|
} else {
|
||||||
|
tsig := new(timerWireFmt)
|
||||||
|
tsig.TimeSigned = t.TimeSigned
|
||||||
|
tsig.Fudge = t.Fudge
|
||||||
|
n, ok1 := packStruct(tsig, tsigvar, 0)
|
||||||
|
if !ok1 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
tsigvar = tsigvar[:n]
|
||||||
|
}
|
||||||
|
if t.RequestMAC != "" {
|
||||||
|
x := append(macbuf, msg...)
|
||||||
|
buf = append(x, tsigvar...)
|
||||||
|
} else {
|
||||||
|
buf = append(msg, tsigvar...)
|
||||||
|
}
|
||||||
|
return buf, true
|
||||||
|
}
|
||||||
|
|
||||||
// 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, timers bool) ([]byte, bool) {
|
func tsigToBuf(rr *RR_TSIG, msg []byte, reqmac string, timers bool) ([]byte, bool) {
|
||||||
var (
|
var (
|
||||||
@ -215,7 +321,7 @@ func tsigToBuf(rr *RR_TSIG, msg []byte, reqmac string, timers bool) ([]byte, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strip the TSIG from the pkt.
|
// Strip the TSIG from the pkt.
|
||||||
func stripTSIG(orig []byte) ([]byte, bool) {
|
func stripTsig(orig []byte) ([]byte, bool) {
|
||||||
// Copied from msg.go's Unpack()
|
// Copied from msg.go's Unpack()
|
||||||
// Header.
|
// Header.
|
||||||
var dh Header
|
var dh Header
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user