Elegant Tsig handling in the server

Lowlevel, but flexible. i.e. usable when building a server
This commit is contained in:
Miek Gieben 2012-02-26 22:38:15 +01:00
parent acba7a84fc
commit fd6bdd4bba
2 changed files with 18 additions and 15 deletions

View File

@ -7,14 +7,15 @@ package dns
// setup for server - a HANDLER function that gets run
// when the query returns.
// TsigStatus here too? TODO
import (
"io"
"net"
"time"
)
// Check incoming TSIG message. TODO(mg)
// Need a tsigstatus for that too? Don't know yet. TODO(mg)
// Incoming (just as in os.Signal)
type QueryHandler interface {
QueryDNS(w RequestWriter, q *Msg)
@ -38,6 +39,7 @@ type reply struct {
conn net.Conn
tsigRequestMAC string
tsigTimersOnly bool
tsigStatus int
}
// A Request is a incoming message from a Client.
@ -296,7 +298,6 @@ func (w *reply) Receive() (*Msg, error) {
if ok := m.Unpack(p); !ok {
return nil, ErrUnpack
}
// Tsig
if m.IsTsig() {
secret := m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name
if _, ok := w.Client().TsigSecret[secret]; !ok {
@ -386,7 +387,7 @@ func (w *reply) Send(m *Msg) error {
if !ok {
return ErrSecret
}
// Compressie maakt dit stuk
// TODO(mg): compression makes this fail
if err := TsigGenerate(m, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly); err != nil {
return err
}
@ -396,6 +397,7 @@ func (w *reply) Send(m *Msg) error {
if !ok {
return ErrPack
}
// Tsig calculation should happen here
_, err := w.writeClient(out)
if err != nil {
return err

View File

@ -12,12 +12,6 @@ import (
"time"
)
const (
TsigNone = iota // No Tsig attached to the message
TsigVerified // Tisg seen and verified
TsigBad // Tisg seen but failed to verify
)
type Handler interface {
ServeDNS(w ResponseWriter, r *Msg)
// IP based ACL mapping. The contains the string representation
@ -30,7 +24,7 @@ type ResponseWriter interface {
// RemoteAddr returns the net.Addr of the client that sent the current request.
RemoteAddr() net.Addr
// Return the status of the Tsig (TsigNone, TsigVerified or TsigBad)
TsigStatus() int
TsigStatus() error
// Write writes a reply back to the client.
Write([]byte) (int, error)
}
@ -48,7 +42,7 @@ type conn struct {
type response struct {
conn *conn
req *Msg
tsigStatus int
tsigStatus error
}
// ServeMux is an DNS request multiplexer. It matches the
@ -320,10 +314,17 @@ func (c *conn) serve() {
w.Write(buf)
break
}
// Check the tsig here TODO
w.tsigStatus = nil
if req.IsTsig() {
secret := req.Extra[len(req.Extra)-1].(*RR_TSIG).Hdr.Name
if _, ok := w.conn.tsigSecret[secret]; !ok {
w.tsigStatus = ErrKeyAlg
}
w.tsigStatus = TsigVerify(c.request, w.conn.tsigSecret[secret], "", false)
}
w.req = req
c.handler.ServeDNS(w, w.req) // this does the writing back to the client
w.tsigStatus = TsigNone
if c.hijacked {
return
}
@ -375,6 +376,6 @@ func (w *response) Write(data []byte) (n int, err error) {
func (w *response) RemoteAddr() net.Addr { return w.conn.remoteAddr }
// TsigStatus implements the ResponseWriter.TsigStatus method
func (w *response) TsigStatus() int {
func (w *response) TsigStatus() error {
return w.tsigStatus
}