From 830b2eae29c781624333390aa3f22f7956a6bc76 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Mon, 27 Dec 2010 09:58:45 +0100 Subject: [PATCH] add hex encoding for DS record * some more edns finishing touches --- dnssec.go | 2 +- dnssectest.go | 3 +-- edns.go | 31 ++++++++++++++++++++++++------- msg.go | 12 +++++++++--- resolverEdns_test.go | 13 +++++++------ signature_test.go | 2 +- types.go | 4 ++-- 7 files changed, 45 insertions(+), 22 deletions(-) diff --git a/dnssec.go b/dnssec.go index d73c1bc4..6967e196 100644 --- a/dnssec.go +++ b/dnssec.go @@ -43,7 +43,7 @@ func KeyToDS(k *RR_DNSKEY, hash int) *RR_DS { // signature validate period is NOT checked. Used // ValidSignaturePeriod for that func Valid(rrset []RR, signature *RR_RRSIG, key *RR_DNSKEY) bool { - + return false } // Calculate the keytag of the DNSKEY diff --git a/dnssectest.go b/dnssectest.go index 39941d1a..308c711d 100644 --- a/dnssectest.go +++ b/dnssectest.go @@ -38,7 +38,6 @@ func main() { res := new(dns.Resolver) ch := dns.NewQuerier(res) - // configure the resolver res.Servers = []string{"192.168.1.2"} res.Timeout = 2 @@ -50,7 +49,7 @@ func main() { m.MsgHdr.Recursion_desired = true //only set this bit m.Question = make([]dns.Question, 1) - m.Question[0] = dns.Question{"nlnetlabs.nl", dns.TypeDNSKEY, dns.ClassINET} + m.Question[0] = dns.Question{"miek.nl", dns.TypeDS, dns.ClassINET} ch <- dns.DnsMsg{m, nil} in := <-ch fmt.Printf("%v\n", in.Dns) diff --git a/edns.go b/edns.go index f160781b..974b4847 100644 --- a/edns.go +++ b/edns.go @@ -1,3 +1,5 @@ +// EDNS0 OTP RR implementation. Define the OPT RR and some +// convience functions to operate on it. package dns // EDNS0 option codes @@ -15,9 +17,7 @@ type Option struct { Data string "hex" } -// EDNS extended RR. -// Not used yet -/* +/* EDNS extended RR. This is the EDNS0 Header Name string "domain-name" Opt uint16 // was type, but is always TypeOPT @@ -29,16 +29,21 @@ This is the EDNS0 Header */ type RR_OPT struct { - Hdr RR_Header // this must become a EDNS0_Header + Hdr RR_Header Option []Option "OPT" // Tag is used in pack and unpack } +// A ENDS packet must show differently. TODO +func (h *RR_Header) ednsString() string { + return h.String() +} + func (rr *RR_OPT) Header() *RR_Header { return &rr.Hdr } func (rr *RR_OPT) String() string { - s := rr.Hdr.String() // Hier misschien andere representatie + s := rr.Hdr.ednsString() // Hier misschien andere representatie for _, o := range rr.Option { switch o.Code { case OptionCodeNSID: @@ -50,15 +55,27 @@ func (rr *RR_OPT) String() string { // when set is true, set the size otherwise get it func (rr *RR_OPT) UDPSize(size int, set bool) int { - return 0 + // fiddle in rr.Hdr.Class should be set + if set { + rr.Hdr.Class = uint16(size) + } + return int(rr.Hdr.Class) } // when set is true, set the Do bit, otherwise get it func (rr *RR_OPT) DoBit(do, set bool) bool { - return true + // rr.TTL last 2 bytes, left most bit + if set { + rr.Hdr.Ttl = 1 + return true + } else { + return true + } + return true // dead code, bug in Go } // when set is true, set the nsid, otherwise get it func (rr *RR_OPT) Nsid(nsid string, set bool) string { + // RR.Option[0] to be set return "" } diff --git a/msg.go b/msg.go index 428a0a08..697adff8 100644 --- a/msg.go +++ b/msg.go @@ -21,6 +21,7 @@ import ( "reflect" "net" "strconv" + "strings" "encoding/base64" "encoding/hex" ) @@ -265,8 +266,12 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o return len(msg), false } case "hex": - // TODO need this for DS - println("hex packing not implemented") + // There is no length encoded here, for DS at least + h, e := hex.DecodeString(s) + if e != nil { + return len(msg), false + } + copy(msg[off:off+hex.DecodedLen(len(s))], h) case "": // Counted string: 1 byte length. if len(s) > 255 || off+1+len(s) > len(msg) { @@ -373,7 +378,7 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, fmt.Fprintf(os.Stderr, "net: dns: unknown string tag %v", f.Tag) return len(msg), false case "hex": - // Rest of the RR is hex encoded + // Rest of the RR is hex encoded, network order an issue here? rdlength := int(val.FieldByName("Hdr").(*reflect.StructValue).FieldByName("Rdlength").(*reflect.UintValue).Get()) var consumed int switch val.Type().Name() { @@ -383,6 +388,7 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, consumed = 0 // TODO } s = hex.EncodeToString(msg[off : off+rdlength-consumed]) + s = strings.ToUpper(s) off += rdlength - consumed case "base64": // Rest of the RR is base64 encoded value diff --git a/resolverEdns_test.go b/resolverEdns_test.go index 9f3e3081..4d0dd384 100644 --- a/resolverEdns_test.go +++ b/resolverEdns_test.go @@ -2,6 +2,7 @@ package dns import ( "testing" + "fmt" ) func TestResolverEdns(t *testing.T) { @@ -23,28 +24,28 @@ func TestResolverEdns(t *testing.T) { edns.Hdr.Rrtype = TypeOPT // You can handle an OTP RR as any other, but there // are some convience functions -// edns.UDPSize(4096, true) -// edns.DoBit(true, true) + edns.UDPSize(4096, true) + edns.DoBit(true, true) // edns.Nsid("mieks-server", true) - edns.Hdr.Class = ClassINET - edns.Hdr.Ttl = 3600 +// edns.Hdr.Class = ClassINET +// edns.Hdr.Ttl = 3600 // no options for now // edns.Option = make([]Option, 1) // edns.Option[0].Code = OptionCodeNSID // edns.Option[0].Data = "lalalala" // ask something - m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET} + m.Question[0] = Question{"nlnetlabs.nl", TypeSOA, ClassINET} m.Extra[0] = edns ch <- DnsMsg{m, nil} in := <-ch if in.Dns.Rcode != RcodeSuccess { - t.Logf("Recv: %v\n", in.Dns) t.Log("Failed to get an valid answer") t.Fail() } + fmt.Printf("recv: %v\n", in.Dns) // TODO remove print (MG) ch <- DnsMsg{nil, nil} <-ch // wait for ch to close channel } diff --git a/signature_test.go b/signature_test.go index 118e8809..9fb51793 100644 --- a/signature_test.go +++ b/signature_test.go @@ -21,7 +21,7 @@ func TestSignature(t *testing.T) { sig.Sig = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ" // Should not be valid - if validSignaturePeriod(sig.Inception, sig.Expiration) { + if ValidSignaturePeriod(sig.Inception, sig.Expiration) { t.Log("Should not be valid") t.Fail() } else { diff --git a/types.go b/types.go index 2f43eef9..6d9decc7 100644 --- a/types.go +++ b/types.go @@ -438,7 +438,7 @@ func (rr *RR_DS) Header() *RR_Header { func (rr *RR_DS) String() string { return rr.Hdr.String() + " " + strconv.Itoa(int(rr.KeyTag)) + - " " + alg_str[rr.Algorithm] + + " " + strconv.Itoa(int(rr.Algorithm)) + " " + strconv.Itoa(int(rr.DigestType)) + " " + rr.Digest } @@ -550,7 +550,7 @@ var rr_str = map[uint16]string{ TypeNSEC3PARAM: "NSEC3PARAM", } -// Map for algorithm names. +// Map for algorithm names. var alg_str = map[uint8]string{ AlgRSAMD5: "RSAMD5", AlgDH: "DH",