remove config.go
This commit is contained in:
parent
bce6b62bc0
commit
19bfc93c5a
1
Makefile
1
Makefile
|
@ -9,7 +9,6 @@ TARG=dns
|
||||||
GOFILES=\
|
GOFILES=\
|
||||||
clientconfig.go\
|
clientconfig.go\
|
||||||
client.go\
|
client.go\
|
||||||
config.go\
|
|
||||||
defaults.go\
|
defaults.go\
|
||||||
dns.go\
|
dns.go\
|
||||||
dnssec.go\
|
dnssec.go\
|
||||||
|
|
104
client.go
104
client.go
|
@ -28,10 +28,11 @@ type RequestWriter interface {
|
||||||
|
|
||||||
// hijacked connections...?
|
// hijacked connections...?
|
||||||
type reply struct {
|
type reply struct {
|
||||||
client *Client
|
client *Client
|
||||||
addr string
|
addr string
|
||||||
req *Msg
|
req *Msg
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
|
tsigTimersOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
|
@ -118,14 +119,15 @@ func (mux *QueryMux) QueryDNS(w RequestWriter, r *Msg) {
|
||||||
|
|
||||||
// TODO add: LocalAddr
|
// TODO add: LocalAddr
|
||||||
type Client struct {
|
type Client struct {
|
||||||
Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one
|
Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one
|
||||||
Addr string // address to call
|
Addr string // address to call
|
||||||
Attempts int // number of attempts
|
Attempts int // number of attempts
|
||||||
Retry bool // retry with TCP
|
Retry bool // retry with TCP
|
||||||
ChannelQuery chan *Request // read DNS request from this channel
|
ChannelQuery chan *Request // read DNS request from this channel
|
||||||
ChannelReply chan []*Msg // read DNS request from this channel
|
ChannelReply chan []*Msg // read DNS request from this channel
|
||||||
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
|
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
|
||||||
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
|
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
|
||||||
|
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient() *Client {
|
func NewClient() *Client {
|
||||||
|
@ -234,15 +236,15 @@ func (w *reply) Receive() (*Msg, os.Error) {
|
||||||
p = make([]byte, MaxMsgSize)
|
p = make([]byte, MaxMsgSize)
|
||||||
case "udp":
|
case "udp":
|
||||||
p = make([]byte, DefaultMsgSize)
|
p = make([]byte, DefaultMsgSize)
|
||||||
}
|
}
|
||||||
n, err := w.readClient(p)
|
n, err := w.readClient(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p = p[:n]
|
p = p[:n]
|
||||||
if ok := m.Unpack(p); !ok {
|
if ok := m.Unpack(p); !ok {
|
||||||
return nil, ErrUnpack
|
return nil, ErrUnpack
|
||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,32 +255,32 @@ func (w *reply) readClient(p []byte) (n int, err os.Error) {
|
||||||
switch w.Client().Net {
|
switch w.Client().Net {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
if len(p) < 1 {
|
if len(p) < 1 {
|
||||||
return 0, io.ErrShortBuffer
|
return 0, io.ErrShortBuffer
|
||||||
}
|
}
|
||||||
n, err = w.conn.(*net.TCPConn).Read(p[0:2])
|
n, err = w.conn.(*net.TCPConn).Read(p[0:2])
|
||||||
if err != nil || n != 2 {
|
if err != nil || n != 2 {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
l, _ := unpackUint16(p[0:2], 0)
|
l, _ := unpackUint16(p[0:2], 0)
|
||||||
if l == 0 {
|
if l == 0 {
|
||||||
return 0, ErrShortRead
|
return 0, ErrShortRead
|
||||||
}
|
}
|
||||||
if int(l) > len(p) {
|
if int(l) > len(p) {
|
||||||
return int(l), io.ErrShortBuffer
|
return int(l), io.ErrShortBuffer
|
||||||
}
|
}
|
||||||
n, err = w.conn.(*net.TCPConn).Read(p[:l])
|
n, err = w.conn.(*net.TCPConn).Read(p[:l])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
i := n
|
i := n
|
||||||
for i < int(l) {
|
for i < int(l) {
|
||||||
j, err := w.conn.(*net.TCPConn).Read(p[i:int(l)])
|
j, err := w.conn.(*net.TCPConn).Read(p[i:int(l)])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
i += j
|
i += j
|
||||||
}
|
}
|
||||||
n = i
|
n = i
|
||||||
case "udp":
|
case "udp":
|
||||||
n, _, err = w.conn.(*net.UDPConn).ReadFromUDP(p)
|
n, _, err = w.conn.(*net.UDPConn).ReadFromUDP(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -288,7 +290,15 @@ func (w *reply) readClient(p []byte) (n int, err os.Error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send a msg to the address specified in w.
|
||||||
|
// If the message m contains a TSIG record the transaction
|
||||||
|
// signature is calculated.
|
||||||
func (w *reply) Send(m *Msg) os.Error {
|
func (w *reply) Send(m *Msg) os.Error {
|
||||||
|
if m.IsTsig() {
|
||||||
|
// Do tsig
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
out, ok := m.Pack()
|
out, ok := m.Pack()
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrPack
|
return ErrPack
|
||||||
|
|
13
config.go
13
config.go
|
@ -1,13 +0,0 @@
|
||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Generic configuration that is used for nameserver.
|
|
||||||
// It is meant to be as generic as possible.
|
|
||||||
|
|
||||||
package dns
|
|
||||||
|
|
||||||
type Config interface {
|
|
||||||
// Returns any Tsig information.
|
|
||||||
Tsig() *Tsig
|
|
||||||
}
|
|
23
defaults.go
23
defaults.go
|
@ -47,7 +47,7 @@ func (dns *Msg) IsNotify() (ok bool) {
|
||||||
ok = dns.MsgHdr.Opcode == OpcodeNotify
|
ok = dns.MsgHdr.Opcode == OpcodeNotify
|
||||||
ok = ok && dns.Question[0].Qclass == ClassINET
|
ok = ok && dns.Question[0].Qclass == ClassINET
|
||||||
ok = ok && dns.Question[0].Qtype == TypeSOA
|
ok = ok && dns.Question[0].Qtype == TypeSOA
|
||||||
return ok
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a dns msg suitable for requesting an ixfr.
|
// Create a dns msg suitable for requesting an ixfr.
|
||||||
|
@ -78,7 +78,7 @@ func (dns *Msg) IsAxfr() (ok bool) {
|
||||||
ok = dns.MsgHdr.Opcode == OpcodeQuery
|
ok = dns.MsgHdr.Opcode == OpcodeQuery
|
||||||
ok = ok && dns.Question[0].Qclass == ClassINET
|
ok = ok && dns.Question[0].Qclass == ClassINET
|
||||||
ok = ok && dns.Question[0].Qtype == TypeAXFR
|
ok = ok && dns.Question[0].Qtype == TypeAXFR
|
||||||
return ok
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the message a valid ixfr request packet?
|
// Is the message a valid ixfr request packet?
|
||||||
|
@ -89,5 +89,22 @@ func (dns *Msg) IsIxfr() (ok bool) {
|
||||||
ok = dns.MsgHdr.Opcode == OpcodeQuery
|
ok = dns.MsgHdr.Opcode == OpcodeQuery
|
||||||
ok = ok && dns.Question[0].Qclass == ClassINET
|
ok = ok && dns.Question[0].Qclass == ClassINET
|
||||||
ok = ok && dns.Question[0].Qtype == TypeIXFR
|
ok = ok && dns.Question[0].Qtype == TypeIXFR
|
||||||
return ok
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has a message 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64) {
|
||||||
|
t := new(RR_TSIG)
|
||||||
|
t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
|
||||||
|
t.Algorithm = algo
|
||||||
|
t.Fudge = fudge
|
||||||
|
t.TimeSigned = timesigned
|
||||||
|
dns.Extra = append(dns.Extra, t)
|
||||||
}
|
}
|
||||||
|
|
154
server.go
154
server.go
|
@ -70,19 +70,19 @@ func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
|
||||||
// Helper handlers
|
// Helper handlers
|
||||||
|
|
||||||
func Refused(w ResponseWriter, r *Msg) {
|
func Refused(w ResponseWriter, r *Msg) {
|
||||||
m := new(Msg)
|
m := new(Msg)
|
||||||
m.SetReply(r)
|
m.SetReply(r)
|
||||||
m.MsgHdr.Rcode = RcodeRefused
|
m.MsgHdr.Rcode = RcodeRefused
|
||||||
m.MsgHdr.Authoritative = false
|
m.MsgHdr.Authoritative = false
|
||||||
buf, _ := m.Pack()
|
buf, _ := m.Pack()
|
||||||
w.Write(buf)
|
w.Write(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefusedHandler return a REFUSED answer
|
// RefusedHandler return a REFUSED answer
|
||||||
func RefusedHandler() Handler { return HandlerFunc(Refused) }
|
func RefusedHandler() Handler { return HandlerFunc(Refused) }
|
||||||
|
|
||||||
func ListenAndServe(addr string, network string, handler Handler) os.Error {
|
func ListenAndServe(addr string, network string, handler Handler) os.Error {
|
||||||
server := &Server{Addr: addr, Network: network, Handler: handler}
|
server := &Server{Addr: addr, Net: network, Handler: handler}
|
||||||
return server.ListenAndServe()
|
return server.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,19 +90,19 @@ func zoneMatch(pattern, zone string) (ok bool) {
|
||||||
if len(pattern) == 0 {
|
if len(pattern) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
i:=0
|
i := 0
|
||||||
for {
|
for {
|
||||||
ok = pattern[len(pattern)-1-i] == zone[len(zone)-1-i]
|
ok = pattern[len(pattern)-1-i] == zone[len(zone)-1-i]
|
||||||
i++
|
i++
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if len(pattern)-1-i < 0 || len(zone)-1-i < 0{
|
if len(pattern)-1-i < 0 || len(zone)-1-i < 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,11 +125,11 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
|
||||||
if pattern == "" {
|
if pattern == "" {
|
||||||
panic("dns: invalid pattern " + pattern)
|
panic("dns: invalid pattern " + pattern)
|
||||||
}
|
}
|
||||||
if pattern[len(pattern)-1] != '.' { // no ending .
|
if pattern[len(pattern)-1] != '.' { // no ending .
|
||||||
mux.m[pattern + "."] = handler
|
mux.m[pattern+"."] = handler
|
||||||
} else {
|
} else {
|
||||||
mux.m[pattern]= handler
|
mux.m[pattern] = handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
|
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
|
||||||
|
@ -158,7 +158,7 @@ func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
|
||||||
// A Server defines parameters for running an DNS server.
|
// A Server defines parameters for running an DNS server.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Addr string // address to listen on, ":dns" if empty
|
Addr string // address to listen on, ":dns" if empty
|
||||||
Network string // if "tcp" it will invoke a TCP listener, otherwise an UDP one
|
Net string // if "tcp" it will invoke a TCP listener, otherwise an UDP one
|
||||||
Handler Handler // handler to invoke, dns.DefaultServeMux if nil
|
Handler Handler // handler to invoke, dns.DefaultServeMux if nil
|
||||||
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
|
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
|
||||||
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
|
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
|
||||||
|
@ -169,7 +169,7 @@ type Server struct {
|
||||||
// read requests and then call handler to reply to them.
|
// read requests and then call handler to reply to them.
|
||||||
// Handler is typically nil, in which case the DefaultServeMux is used.
|
// Handler is typically nil, in which case the DefaultServeMux is used.
|
||||||
func ServeTCP(l *net.TCPListener, handler Handler) os.Error {
|
func ServeTCP(l *net.TCPListener, handler Handler) os.Error {
|
||||||
srv := &Server{Handler: handler, Network: "tcp"}
|
srv := &Server{Handler: handler, Net: "tcp"}
|
||||||
return srv.ServeTCP(l)
|
return srv.ServeTCP(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ func ServeTCP(l *net.TCPListener, handler Handler) os.Error {
|
||||||
// read requests and then call handler to reply to them.
|
// read requests and then call handler to reply to them.
|
||||||
// Handler is typically nil, in which case the DefaultServeMux is used.
|
// Handler is typically nil, in which case the DefaultServeMux is used.
|
||||||
func ServeUDP(l *net.UDPConn, handler Handler) os.Error {
|
func ServeUDP(l *net.UDPConn, handler Handler) os.Error {
|
||||||
srv := &Server{Handler: handler, Network: "udp"}
|
srv := &Server{Handler: handler, Net: "udp"}
|
||||||
return srv.ServeUDP(l)
|
return srv.ServeUDP(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ func (srv *Server) ListenAndServe() os.Error {
|
||||||
if addr == "" {
|
if addr == "" {
|
||||||
addr = ":domain"
|
addr = ":domain"
|
||||||
}
|
}
|
||||||
switch srv.Network {
|
switch srv.Net {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
a, e := net.ResolveTCPAddr(addr)
|
a, e := net.ResolveTCPAddr(addr)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -323,60 +323,60 @@ func (c *conn) close() {
|
||||||
|
|
||||||
// Serve a new connection.
|
// Serve a new connection.
|
||||||
func (c *conn) serve() {
|
func (c *conn) serve() {
|
||||||
for {
|
for {
|
||||||
// Request has been read in ServeUDP or ServeTCP
|
// Request has been read in ServeUDP or ServeTCP
|
||||||
w := new(response)
|
w := new(response)
|
||||||
w.conn = c
|
w.conn = c
|
||||||
req := new(Msg)
|
req := new(Msg)
|
||||||
if !req.Unpack(c.request) {
|
if !req.Unpack(c.request) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w.req = req
|
w.req = req
|
||||||
c.handler.ServeDNS(w, w.req) // this does the writing back to the client
|
c.handler.ServeDNS(w, w.req) // this does the writing back to the client
|
||||||
if c.hijacked {
|
if c.hijacked {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
break // TODO(mg) Why is this a loop anyway
|
break // TODO(mg) Why is this a loop anyway
|
||||||
}
|
}
|
||||||
if c._TCP != nil {
|
if c._TCP != nil {
|
||||||
c.close() // Listen and Serve is closed then
|
c.close() // Listen and Serve is closed then
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (w *response) Write(data []byte) (n int, err os.Error) {
|
func (w *response) Write(data []byte) (n int, err os.Error) {
|
||||||
switch {
|
switch {
|
||||||
case w.conn._UDP != nil:
|
case w.conn._UDP != nil:
|
||||||
n, err = w.conn._UDP.WriteTo(data, w.conn.remoteAddr)
|
n, err = w.conn._UDP.WriteTo(data, w.conn.remoteAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
case w.conn._TCP != nil:
|
case w.conn._TCP != nil:
|
||||||
// TODO(mg) len(data) > 64K
|
// TODO(mg) len(data) > 64K
|
||||||
l := make([]byte, 2)
|
l := make([]byte, 2)
|
||||||
l[0], l[1] = packUint16(uint16(len(data)))
|
l[0], l[1] = packUint16(uint16(len(data)))
|
||||||
n, err = w.conn._TCP.Write(l)
|
n, err = w.conn._TCP.Write(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if n != 2 {
|
if n != 2 {
|
||||||
return n, io.ErrShortWrite
|
return n, io.ErrShortWrite
|
||||||
}
|
}
|
||||||
n, err = w.conn._TCP.Write(data)
|
n, err = w.conn._TCP.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
i := n
|
i := n
|
||||||
if i < len(data) {
|
if i < len(data) {
|
||||||
j, err := w.conn._TCP.Write(data[i:len(data)])
|
j, err := w.conn._TCP.Write(data[i:len(data)])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
i += j
|
i += j
|
||||||
}
|
}
|
||||||
n = i
|
n = i
|
||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteAddr implements the ResponseWriter.RemoteAddr method
|
// RemoteAddr implements the ResponseWriter.RemoteAddr method
|
||||||
|
|
139
tsig.go
139
tsig.go
|
@ -21,49 +21,6 @@ import (
|
||||||
// tsig.TimeSigned = uint64(time.Seconds())
|
// tsig.TimeSigned = uint64(time.Seconds())
|
||||||
// tsig.Secret = "so6ZGir4GPAqINNh9U5c3A==" // Secret encoded in base64.
|
// tsig.Secret = "so6ZGir4GPAqINNh9U5c3A==" // Secret encoded in base64.
|
||||||
|
|
||||||
type TsigWriter struct {
|
|
||||||
secrets map[string]string
|
|
||||||
w io.Writer
|
|
||||||
name string
|
|
||||||
fudge uint16
|
|
||||||
algorithm string
|
|
||||||
timersOnly bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTsigWriter creates a new writer that implements TSIG, secrets
|
|
||||||
// should contain a mapping from key names to secrets. A message
|
|
||||||
// should be written with the TSIG record appends. Tsig
|
|
||||||
func NewTsigWriter(w io.Writer, secrets map[string]string) *TsigWriter {
|
|
||||||
t := new(TsigWriter)
|
|
||||||
t.secrets = secrets
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TsigWriter) Write(p []byte) (int, os.Error) {
|
|
||||||
return 0, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Tsig struct {
|
|
||||||
// The name of the key.
|
|
||||||
Name string
|
|
||||||
// Fudge to take into account.
|
|
||||||
Fudge uint16
|
|
||||||
// When is the TSIG created
|
|
||||||
TimeSigned uint64
|
|
||||||
// Which algorithm is used.
|
|
||||||
Algorithm string
|
|
||||||
// Tsig secret encoded in base64.
|
|
||||||
Secret string
|
|
||||||
// MAC (if known)
|
|
||||||
MAC string
|
|
||||||
// Request MAC
|
|
||||||
RequestMAC string
|
|
||||||
// Only include the timers in the MAC if set to true.
|
|
||||||
TimersOnly 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."
|
||||||
|
@ -101,50 +58,42 @@ type timerWireFmt struct {
|
||||||
Fudge uint16
|
Fudge uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a Tsig to add message.
|
// Add a Tsig to an message. // Must return the mac
|
||||||
func (t *Tsig) Generate(msg []byte) ([]byte, os.Error) {
|
func TsigGenerate(m *Msg, secret string, timersOnly bool) (*Msg, os.Error) {
|
||||||
rawsecret, err := packBase64([]byte(t.Secret))
|
if !m.IsTsig() {
|
||||||
|
panic("TSIG not last RR in additional")
|
||||||
|
}
|
||||||
|
rawsecret, err := packBase64([]byte(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if t.Fudge == 0 {
|
|
||||||
t.Fudge = 300
|
|
||||||
}
|
|
||||||
if t.TimeSigned == 0 {
|
|
||||||
t.TimeSigned = uint64(time.Seconds())
|
|
||||||
}
|
|
||||||
|
|
||||||
buf, err := t.Buffer(msg)
|
rr := m.Extra[len(m.Extra)-1].(*RR_TSIG)
|
||||||
|
m.Extra = m.Extra[0:len(m.Extra)-1] // kill the TSIG from the msg
|
||||||
|
buf, err := tsigBuffer(m, rr, timersOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t := new(RR_TSIG)
|
||||||
|
|
||||||
h := hmac.NewMD5([]byte(rawsecret))
|
h := hmac.NewMD5([]byte(rawsecret))
|
||||||
io.WriteString(h, string(buf))
|
io.WriteString(h, string(buf))
|
||||||
t.MAC = hex.EncodeToString(h.Sum()) // Size is half!
|
t.MAC = hex.EncodeToString(h.Sum()) // Size is half!
|
||||||
|
|
||||||
// Create TSIG and add it to the message.
|
t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
|
||||||
q := new(Msg)
|
t.Fudge = t.Fudge
|
||||||
if !q.Unpack(msg) {
|
t.TimeSigned = t.TimeSigned
|
||||||
return nil, ErrUnpack
|
t.Algorithm = t.Algorithm
|
||||||
}
|
t.OrigId = m.MsgHdr.Id
|
||||||
|
t.MAC = t.MAC
|
||||||
|
t.MACSize = uint16(len(t.MAC) / 2)
|
||||||
|
|
||||||
rr := new(RR_TSIG)
|
m.Extra = append(m.Extra, t)
|
||||||
rr.Hdr = RR_Header{Name: t.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
|
return m, nil
|
||||||
rr.Fudge = t.Fudge
|
|
||||||
rr.TimeSigned = t.TimeSigned
|
|
||||||
rr.Algorithm = t.Algorithm
|
|
||||||
rr.OrigId = q.Id
|
|
||||||
rr.MAC = t.MAC
|
|
||||||
rr.MACSize = uint16(len(t.MAC) / 2)
|
|
||||||
|
|
||||||
q.Extra = append(q.Extra, rr)
|
|
||||||
send, ok := q.Pack()
|
|
||||||
if !ok {
|
|
||||||
return send, ErrPack
|
|
||||||
}
|
|
||||||
return send, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Verify a TSIG on a message.
|
// Verify a TSIG on a message.
|
||||||
// If the signature does not validate err contains the
|
// If the signature does not validate err contains the
|
||||||
// error. If the it validates err is nil
|
// error. If the it validates err is nil
|
||||||
|
@ -164,25 +113,32 @@ func (t *Tsig) Verify(msg []byte) (bool, os.Error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time needs to be checked */
|
// Time needs to be checked
|
||||||
|
|
||||||
h := hmac.NewMD5([]byte(rawsecret))
|
h := hmac.NewMD5([]byte(rawsecret))
|
||||||
io.WriteString(h, string(buf))
|
io.WriteString(h, string(buf))
|
||||||
return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(t.MAC), nil
|
return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(t.MAC), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Create a wiredata buffer for the MAC calculation.
|
// Create a wiredata buffer for the MAC calculation.
|
||||||
func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
|
func tsigBuffer(msg *Msg, rr *RR_TSIG, timersOnly bool) ([]byte, os.Error) {
|
||||||
var (
|
var (
|
||||||
macbuf []byte
|
macbuf []byte
|
||||||
buf []byte
|
buf []byte
|
||||||
)
|
)
|
||||||
|
if rr.TimeSigned == 0 {
|
||||||
|
rr.TimeSigned = uint64(time.Seconds())
|
||||||
|
}
|
||||||
|
if rr.Fudge == 0 {
|
||||||
|
rr.Fudge = 300
|
||||||
|
}
|
||||||
|
|
||||||
if t.RequestMAC != "" {
|
if rr.MAC != "" {
|
||||||
m := new(macWireFmt)
|
m := new(macWireFmt)
|
||||||
m.MACSize = uint16(len(t.RequestMAC) / 2)
|
m.MACSize = uint16(len(rr.MAC) / 2)
|
||||||
m.MAC = t.RequestMAC
|
m.MAC = rr.MAC
|
||||||
macbuf = make([]byte, len(t.RequestMAC)) // reqmac should be twice as long
|
macbuf = make([]byte, len(rr.MAC)) // reqmac should be twice as long
|
||||||
n, ok := packStruct(m, macbuf, 0)
|
n, ok := packStruct(m, macbuf, 0)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrSigGen
|
return nil, ErrSigGen
|
||||||
|
@ -191,10 +147,10 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tsigvar := make([]byte, DefaultMsgSize)
|
tsigvar := make([]byte, DefaultMsgSize)
|
||||||
if t.TimersOnly {
|
if timersOnly {
|
||||||
tsig := new(timerWireFmt)
|
tsig := new(timerWireFmt)
|
||||||
tsig.TimeSigned = t.TimeSigned
|
tsig.TimeSigned = rr.TimeSigned
|
||||||
tsig.Fudge = t.Fudge
|
tsig.Fudge = rr.Fudge
|
||||||
n, ok1 := packStruct(tsig, tsigvar, 0)
|
n, ok1 := packStruct(tsig, tsigvar, 0)
|
||||||
if !ok1 {
|
if !ok1 {
|
||||||
return nil, ErrSigGen
|
return nil, ErrSigGen
|
||||||
|
@ -202,12 +158,12 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
|
||||||
tsigvar = tsigvar[:n]
|
tsigvar = tsigvar[:n]
|
||||||
} else {
|
} else {
|
||||||
tsig := new(tsigWireFmt)
|
tsig := new(tsigWireFmt)
|
||||||
tsig.Name = strings.ToLower(t.Name)
|
tsig.Name = strings.ToLower(rr.Hdr.Name)
|
||||||
tsig.Class = ClassANY
|
tsig.Class = ClassANY
|
||||||
tsig.Ttl = 0
|
tsig.Ttl = 0
|
||||||
tsig.Algorithm = strings.ToLower(t.Algorithm)
|
tsig.Algorithm = strings.ToLower(rr.Algorithm)
|
||||||
tsig.TimeSigned = t.TimeSigned
|
tsig.TimeSigned = rr.TimeSigned
|
||||||
tsig.Fudge = t.Fudge
|
tsig.Fudge = rr.Fudge
|
||||||
tsig.Error = 0
|
tsig.Error = 0
|
||||||
tsig.OtherLen = 0
|
tsig.OtherLen = 0
|
||||||
tsig.OtherData = ""
|
tsig.OtherData = ""
|
||||||
|
@ -217,15 +173,17 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
|
||||||
}
|
}
|
||||||
tsigvar = tsigvar[:n]
|
tsigvar = tsigvar[:n]
|
||||||
}
|
}
|
||||||
if t.RequestMAC != "" {
|
if rr.MAC != "" {
|
||||||
x := append(macbuf, msg...)
|
msgbuf, _ := msg.Pack()
|
||||||
|
x := append(macbuf, msgbuf...)
|
||||||
buf = append(x, tsigvar...)
|
buf = append(x, tsigvar...)
|
||||||
} else {
|
} else {
|
||||||
buf = append(msg, tsigvar...)
|
msgbuf, _ := msg.Pack()
|
||||||
|
buf = append(msgbuf, tsigvar...)
|
||||||
}
|
}
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// Strip the TSIG from the pkt.
|
// Strip the TSIG from the pkt.
|
||||||
func (t *Tsig) stripTsig(orig []byte) ([]byte, os.Error) {
|
func (t *Tsig) stripTsig(orig []byte) ([]byte, os.Error) {
|
||||||
// Copied from msg.go's Unpack()
|
// Copied from msg.go's Unpack()
|
||||||
|
@ -292,3 +250,4 @@ func (t *Tsig) stripTsig(orig []byte) ([]byte, os.Error) {
|
||||||
}
|
}
|
||||||
return msg[:tsigoff], nil
|
return msg[:tsigoff], nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
30
xfr.go
30
xfr.go
|
@ -8,31 +8,31 @@ import (
|
||||||
// section contains an AXFR type an Axfr is performed. If q's question
|
// section contains an AXFR type an Axfr is performed. If q's question
|
||||||
// section contains an IXFR type an Ixfr is performed.
|
// section contains an IXFR type an Ixfr is performed.
|
||||||
func (c *Client) XfrReceive(q *Msg, a string) ([]*Msg, os.Error) {
|
func (c *Client) XfrReceive(q *Msg, a string) ([]*Msg, os.Error) {
|
||||||
w := new(reply)
|
w := new(reply)
|
||||||
w.client = c
|
w.client = c
|
||||||
w.addr = a
|
w.addr = a
|
||||||
w.req = q // is this needed??
|
w.req = q // is this needed TODO(mg)
|
||||||
|
|
||||||
if err := w.Send(q); err != nil {
|
if err := w.Send(q); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// conn should be set now
|
// conn should be set now
|
||||||
switch q.Question[0].Qtype {
|
switch q.Question[0].Qtype {
|
||||||
case TypeAXFR:
|
case TypeAXFR:
|
||||||
return w.axfrReceive()
|
return w.axfrReceive()
|
||||||
case TypeIXFR:
|
case TypeIXFR:
|
||||||
// return w.ixfrReceive()
|
// return w.ixfrReceive()
|
||||||
}
|
}
|
||||||
panic("not reached")
|
panic("not reached")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *reply) axfrReceive() ([]*Msg, os.Error) {
|
func (w *reply) axfrReceive() ([]*Msg, os.Error) {
|
||||||
axfr := make([]*Msg, 0) // use append ALL the time?
|
axfr := make([]*Msg, 0) // use append ALL the time?
|
||||||
first := true
|
first := true
|
||||||
for {
|
for {
|
||||||
in, err := w.Receive()
|
in, err := w.Receive()
|
||||||
axfr = append(axfr, in)
|
axfr = append(axfr, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return axfr, err
|
return axfr, err
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,7 @@ func (w *reply) axfrReceive() ([]*Msg, os.Error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
//if d.Tsig != nil {
|
w.tsigTimersOnly = true // Subsequent envelopes use this.
|
||||||
// d.Tsig.TimersOnly = true // Subsequent envelopes use this.
|
|
||||||
//}
|
|
||||||
if !checkXfrSOA(in, false) {
|
if !checkXfrSOA(in, false) {
|
||||||
// Soa record not the last one
|
// Soa record not the last one
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue