From 2fc00f550ad98c301363a0ef947925e31d2a5406 Mon Sep 17 00:00:00 2001 From: "Matthew Horsfall (alh)" Date: Sun, 13 Jan 2013 14:28:08 -0500 Subject: [PATCH] Playing with Go - porting Net::RNDC::Packet logic to learn. This is probably not idiomatic Go by any means, and everything needs to be re-implemented as proper "packages". Also, encoding the packet doesn't yet generate an HMAC for the encoded packet or fully generate it correctly. --- README.md | 4 +- golang/rndc/gen.pl | 23 ++++ golang/rndc/pkt.pkt | Bin 0 -> 236 bytes golang/rndc/rndc.go | 258 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 284 insertions(+), 1 deletion(-) create mode 100755 golang/rndc/gen.pl create mode 100644 golang/rndc/pkt.pkt create mode 100644 golang/rndc/rndc.go diff --git a/README.md b/README.md index e7ae736..33bbe6a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ playground ========== -A place for my head \ No newline at end of file +A place for my head + +Just random hacking/learning. diff --git a/golang/rndc/gen.pl b/golang/rndc/gen.pl new file mode 100755 index 0000000..48b30cc --- /dev/null +++ b/golang/rndc/gen.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Net::RNDC::Packet; + +my $pkt = Net::RNDC::Packet->new(key => 'abcd'); + +$pkt->{data}{somelist} = [ {cat => 'dog', small => ['thing'], }, 1, "hi", ['bird', 'mouse'] ]; + +open(my $o, '>', 'pkt.pkt') or die "Failed to write pkt.pkt: $!\n"; + +print $o $pkt->data; + +close($o); + +print <u6rwt<>flopjg_A}(MxxAd*bMg>E zUxZLVxM+Mi=x~ZlE0dt3Nq#!-^7n17X?tw<+3T4twsb@I)z=2nHRkH`fHb1ZgvE@} zlws~v-EXUyCMk{SGQ-?!``5*ca4EciHzVxZhXRf7jWI)4S!J~IVYeJ0n1xs2!H2Rc hh_k{Na1l(zm-=1+1r+X})ZoUz_@ZmsN49F5`T?U$E`R_4 literal 0 HcmV?d00001 diff --git a/golang/rndc/rndc.go b/golang/rndc/rndc.go new file mode 100644 index 0000000..ea9145c --- /dev/null +++ b/golang/rndc/rndc.go @@ -0,0 +1,258 @@ +package main + +import ( + "fmt" + "encoding/binary" + "bytes" + "os" + "io/ioutil" + "crypto/md5" + "crypto/hmac" + "encoding/base64" +) + +func main() { + fmt.Println("Opening pkt.pkt (an RNDC packet)") + f, err := os.Open("pkt.pkt") + if err != nil { + fmt.Println(err) + return + } + + var pkt []byte + pkt, _ = ioutil.ReadAll(f) + + var length int32 + var version int32 + + buf := bytes.NewBuffer(pkt) + + copy := buf.Bytes() + buf = bytes.NewBuffer(copy) + + binary.Read(buf, binary.BigEndian, &length) + binary.Read(buf, binary.BigEndian, &version) + var x value + + mkey := "abcd" + ekey, _ := base64.StdEncoding.DecodeString(mkey) + + copy = copy[51:] + h := hmac.New(md5.New, ekey) + h.Write(copy) + sum := h.Sum(nil) + enc := base64.StdEncoding.EncodeToString(sum) + enc = enc[:22] + + x = table_fromwire(buf) + fmt.Println("Decoding packet from disk") + display(&x, "") + + got := (* (*x.subt)["_auth"].subt)["hmd5"] + + if (got.subv != enc) { + fmt.Println("Failed to validate packet") + } else { + fmt.Println("Packet validated!") + } + + fmt.Println("Encoding decoded packet") + + // Todo: Properly encode a packet + zing := table_towire(&x, 0) + + dbytes := zing.Bytes() + + buf2 := bytes.NewBuffer(dbytes) + var typex int8 + var length2 int32 + + binary.Read(buf2, binary.BigEndian, &typex) + binary.Read(buf2, binary.BigEndian, &length2) + + var y value + + fmt.Println("Decoding re-encoded packet") + y = table_fromwire(buf2) + display(&y, "") +} + +const ISCCC_CCMSGTYPE_STRING int8 = 0 +const ISCCC_CCMSGTYPE_BINARYDATA int8 = 1 +const ISCCC_CCMSGTYPE_TABLE int8 = 2 +const ISCCC_CCMSGTYPE_LIST int8 = 3 + +type table_head map[string] value +type list_head []value + +type value struct { + xtype int8 + subt *table_head + suba *list_head + subv string +} + +func value_fromwire (buf *bytes.Buffer) value { + var typex int8 + var length int32 + + binary.Read(buf, binary.BigEndian, &typex) + binary.Read(buf, binary.BigEndian, &length) + + d := make([]byte, length) + buf.Read(d) + + nbuf := bytes.NewBuffer(d) + + switch typex { + case ISCCC_CCMSGTYPE_TABLE: + return table_fromwire(nbuf) + case ISCCC_CCMSGTYPE_LIST: + return list_fromwire(nbuf) + case ISCCC_CCMSGTYPE_BINARYDATA: + return binary_fromwire(nbuf) + } + var wah value + return wah +} + +func value_towire (val *value) *bytes.Buffer { + switch val.xtype { + case ISCCC_CCMSGTYPE_TABLE: + return table_towire(val,0) + case ISCCC_CCMSGTYPE_LIST: + return list_towire(val) + case ISCCC_CCMSGTYPE_BINARYDATA: + return binary_towire(val) + } + + what := new(bytes.Buffer) + return what +} + +func binary_fromwire (buf *bytes.Buffer) value { + db := make([]byte, buf.Len()) + buf.Read(db) + + var ret value + ret.xtype = ISCCC_CCMSGTYPE_BINARYDATA + ret.subv = string(db) + return ret +} + +func binary_towire (val *value) *bytes.Buffer { + var length int32 = int32(len(val.subv)) + var buf = new(bytes.Buffer) + binary.Write(buf, binary.BigEndian, int8(ISCCC_CCMSGTYPE_BINARYDATA)) + + if length == 0 { + binary.Write(buf, binary.BigEndian, int32(4)) + buf.WriteString("null") + } else { + binary.Write(buf, binary.BigEndian, length) + buf.WriteString(val.subv) + } + + return buf +} + +func list_fromwire (buf *bytes.Buffer) value { + var data list_head + for ; buf.Len() > 0; { + data = append(data, value_fromwire(buf)) + } + var ret value + ret.xtype = ISCCC_CCMSGTYPE_LIST + ret.suba = &data + return ret +} + +func list_towire (val *value) *bytes.Buffer { + var header = new(bytes.Buffer) + binary.Write(header, binary.BigEndian, int8(ISCCC_CCMSGTYPE_LIST)) + var buf = new(bytes.Buffer) + + for _, d := range *val.suba { + buf.Write(value_towire(&d).Bytes()) + } + + binary.Write(header, binary.BigEndian, int32(buf.Len())) + var newbuf = new(bytes.Buffer) + newbuf.Write(header.Bytes()) + newbuf.Write(buf.Bytes()) + + return newbuf +} + +func table_fromwire (buf *bytes.Buffer) value { + data := make(table_head) + + for ; buf.Len() > 0; { + var length int8 + var key string + + binary.Read(buf, binary.BigEndian, &length) + d := make([]byte, length) + + buf.Read(d) + + key = string(d) + + data[key] = value_fromwire(buf) + } + + + var ret value + ret.xtype = ISCCC_CCMSGTYPE_TABLE + ret.subt = &data + return ret +} + +func table_towire (val *value, no_header int) *bytes.Buffer { + var header = new(bytes.Buffer) + binary.Write(header, binary.BigEndian, int8(ISCCC_CCMSGTYPE_TABLE)) + var buf = new(bytes.Buffer) + + for k, d := range *val.subt { + binary.Write(buf, binary.BigEndian, int8(len(k))) + buf.WriteString(k) + buf.Write(value_towire(&d).Bytes()) + } + + if (no_header > 0) { + return buf + } else { + var newbuf = new(bytes.Buffer) + binary.Write(header, binary.BigEndian, int32(buf.Len())) + newbuf.Write(header.Bytes()) + newbuf.Write(buf.Bytes()) + return newbuf + } + + return buf +} + +func display(v *value, indent string) { + switch v.xtype { + case ISCCC_CCMSGTYPE_BINARYDATA: + fmt.Print("\"", v.subv, "\"\n") + case ISCCC_CCMSGTYPE_LIST: + fmt.Print(indent, "(\n"); + cindent := indent + indent = indent + " " + for _, val := range *v.suba { + display(&val, indent) + } + fmt.Print(cindent, ")\n"); + + case ISCCC_CCMSGTYPE_TABLE: + fmt.Print(indent, "{\n"); + cindent := indent + indent := indent + " " + for key, val := range *v.subt { + fmt.Print(indent, "\"", key, "\":"); + display(&val, indent) + } + fmt.Print(cindent, "}\n"); + } +}