From a6fee19f4cb6c20f87bf865106d817f49a89c610 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 9 Jan 2011 15:30:45 +0100 Subject: [PATCH] Fix tsig by making timeSigned a 64 bit int only use the lower 48 bits to make it all work --- msg.go | 46 ++++++++++++++++++++++------------------------ tsig.go | 19 +++++++++++-------- types.go | 7 +++++++ 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/msg.go b/msg.go index 9cc50bfc..02b9ae65 100644 --- a/msg.go +++ b/msg.go @@ -244,22 +244,6 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o BadType: fmt.Fprintf(os.Stderr, "dns: unknown packing type %v\n", f.Type) return len(msg), false - case *reflect.ArrayValue: - switch f.Tag { - default: - fmt.Fprintf(os.Stderr, "dns: unknown IP tag %v", f.Tag) - return len(msg), false - case "TSIG": - // has a 3 byte inception time (check len?) - // need to do some shifting here - msg[off] = byte(fv.Elem(0).(*reflect.UintValue).Get() >> 8) - msg[off+1] = byte(fv.Elem(0).(*reflect.UintValue).Get()) - msg[off+2] = byte(fv.Elem(1).(*reflect.UintValue).Get() >> 8) - msg[off+3] = byte(fv.Elem(1).(*reflect.UintValue).Get()) - msg[off+4] = byte(fv.Elem(2).(*reflect.UintValue).Get() >> 8) - msg[off+5] = byte(fv.Elem(2).(*reflect.UintValue).Get()) - off += 6 - } case *reflect.SliceValue: switch f.Tag { default: @@ -335,6 +319,18 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o msg[off+2] = byte(i >> 8) msg[off+3] = byte(i) off += 4 + case reflect.Uint64: + // Only used in TSIG, where it stops as 48 bits, discard the upper 16 + if off+6 > len(msg) { + return len(msg), false + } + msg[off] = byte(i >> 40) + msg[off+1] = byte(i >> 32) + msg[off+2] = byte(i >> 24) + msg[off+3] = byte(i >> 16) + msg[off+4] = byte(i >> 8) + msg[off+5] = byte(i) + off += 6 } case *reflect.StringValue: // There are multiple string encodings. @@ -398,14 +394,6 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, BadType: fmt.Fprintf(os.Stderr, "dns: unknown packing type %v", f.Type) return len(msg), false - case *reflect.ArrayValue: - switch f.Tag { - default: - fmt.Fprintf(os.Stderr, "dns: unknown IP tag %v", f.Tag) - return len(msg), false - case "TSIG": - println("TODO") - } case *reflect.SliceValue: switch f.Tag { default: @@ -469,6 +457,16 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, i := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3]) fv.Set(uint64(i)) off += 4 + case reflect.Uint64: + // This is *only* used in TSIG where the last 48 bits are occupied + // So for now, assume a uint48 (6 bytes) + if off+6 > len(msg) { + return len(msg), false + } + i := uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 | + uint64(msg[off+4])<<8 | uint64(msg[off+4]) + fv.Set(uint64(i)) + off += 6 } case *reflect.StringValue: var s string diff --git a/tsig.go b/tsig.go index bbdd7d7c..bd8f0d8d 100644 --- a/tsig.go +++ b/tsig.go @@ -17,12 +17,12 @@ const ( type RR_TSIG struct { Hdr RR_Header - Algorithm string "domain-name" - TimeSigned [3]uint16 "TSIG" + Algorithm string "domain-name" + TimeSigned uint64 Fudge uint16 MACSize uint16 MAC string - OrigId uint16 // msg id + OrigId uint16 // msg id Error uint16 OtherLen uint16 OtherData string @@ -33,12 +33,12 @@ func (rr *RR_TSIG) Header() *RR_Header { } func (rr *RR_TSIG) String() string { - // It has no presentation format + // It has no presentation format return rr.Hdr.String() + - " " + rr.Algorithm + + " " + rr.Algorithm + " " + "" + " " + strconv.Itoa(int(rr.Fudge)) + - " " + "" + + " " + "" + " " + strconv.Itoa(int(rr.OrigId)) + " " + strconv.Itoa(int(rr.Error)) + " " + rr.OtherData @@ -53,8 +53,8 @@ type tsig_generation_fmt struct { Class uint16 Ttl uint32 // Rdata of the TSIG - Algorithm string "domain-name" - TimeSigned [3]uint16 "TSIG" + Algorithm string "domain-name" + TimeSigned uint64 Fudge uint16 // MACSize, MAC and OrigId excluded Error uint16 @@ -103,5 +103,8 @@ func (rr *RR_TSIG) Generate(msg *Msg, secret string) bool { // the TSIG record still attached (as the last rr in the Additional // section) func (rr *RR_TSIG) Verify(msg *Msg, secret string) bool { + // copy the mesg, strip (and check) the tsig rr + // perform the opposite of Generate() and then + // verify the mac return false } diff --git a/types.go b/types.go index 3b055706..1777f94f 100644 --- a/types.go +++ b/types.go @@ -535,6 +535,13 @@ func timeToDate(t uint32) string { return ti.Format("20060102030405") } +// Translate the TSIG time signed into a date. There is no +// need for RFC1982 calculations as this date is 48 bits +func tsigTimeToDate(t uint64) string { + // only use the lower 48 bits + return "TODO" +} + // Map of constructors for each RR wire type. var rr_mk = map[int]func() RR{ TypeCNAME: func() RR { return new(RR_CNAME) },