mirror of
https://github.com/miekg/dns.git
synced 2025-12-12 15:21:01 +01:00
More TSIG changes. Curious if they amount to something
This commit is contained in:
parent
566b5f7d1a
commit
0059556516
11
msg.go
11
msg.go
@ -770,6 +770,10 @@ func unpackBase64(b []byte) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for packing, mostly used in dnssec.go
|
// Helper function for packing, mostly used in dnssec.go
|
||||||
|
func packUint16(i uint16) (byte, byte) {
|
||||||
|
return byte(i >> 8), byte(i)
|
||||||
|
}
|
||||||
|
|
||||||
func packBase64(s []byte) ([]byte, os.Error) {
|
func packBase64(s []byte) ([]byte, os.Error) {
|
||||||
b64len := base64.StdEncoding.DecodedLen(len(s))
|
b64len := base64.StdEncoding.DecodedLen(len(s))
|
||||||
buf := make([]byte, b64len)
|
buf := make([]byte, b64len)
|
||||||
@ -1022,27 +1026,34 @@ func (dns *Msg) String() string {
|
|||||||
if len(dns.Question) > 0 {
|
if len(dns.Question) > 0 {
|
||||||
s += "\n;; QUESTION SECTION:\n"
|
s += "\n;; QUESTION SECTION:\n"
|
||||||
for i := 0; i < len(dns.Question); i++ {
|
for i := 0; i < len(dns.Question); i++ {
|
||||||
|
// Need check if it exists? TODO(mg)
|
||||||
s += dns.Question[i].String() + "\n"
|
s += dns.Question[i].String() + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(dns.Answer) > 0 {
|
if len(dns.Answer) > 0 {
|
||||||
s += "\n;; ANSWER SECTION:\n"
|
s += "\n;; ANSWER SECTION:\n"
|
||||||
for i := 0; i < len(dns.Answer); i++ {
|
for i := 0; i < len(dns.Answer); i++ {
|
||||||
|
if dns.Answer[i] != nil {
|
||||||
s += dns.Answer[i].String() + "\n"
|
s += dns.Answer[i].String() + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if len(dns.Ns) > 0 {
|
if len(dns.Ns) > 0 {
|
||||||
s += "\n;; AUTHORITY SECTION:\n"
|
s += "\n;; AUTHORITY SECTION:\n"
|
||||||
for i := 0; i < len(dns.Ns); i++ {
|
for i := 0; i < len(dns.Ns); i++ {
|
||||||
|
if dns.Ns[i] != nil {
|
||||||
s += dns.Ns[i].String() + "\n"
|
s += dns.Ns[i].String() + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if len(dns.Extra) > 0 {
|
if len(dns.Extra) > 0 {
|
||||||
s += "\n;; ADDITIONAL SECTION:\n"
|
s += "\n;; ADDITIONAL SECTION:\n"
|
||||||
for i := 0; i < len(dns.Extra); i++ {
|
for i := 0; i < len(dns.Extra); i++ {
|
||||||
|
if dns.Extra[i] != nil {
|
||||||
s += dns.Extra[i].String() + "\n"
|
s += dns.Extra[i].String() + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
94
resolver.go
94
resolver.go
@ -45,9 +45,10 @@ func (res *Resolver) Query(q *Msg) (d *Msg, err os.Error) {
|
|||||||
// Check if there is a TSIG appended, if so, check it
|
// Check if there is a TSIG appended, if so, check it
|
||||||
var (
|
var (
|
||||||
c net.Conn
|
c net.Conn
|
||||||
in *Msg
|
|
||||||
port string
|
port string
|
||||||
|
inb []byte
|
||||||
)
|
)
|
||||||
|
in := new(Msg)
|
||||||
if len(res.Servers) == 0 {
|
if len(res.Servers) == 0 {
|
||||||
return nil, &Error{Error: "No servers defined"}
|
return nil, &Error{Error: "No servers defined"}
|
||||||
}
|
}
|
||||||
@ -81,9 +82,12 @@ func (res *Resolver) Query(q *Msg) (d *Msg, err os.Error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if res.Tcp {
|
if res.Tcp {
|
||||||
in, err = exchangeTCP(c, sending, res, true)
|
inb, err = exchangeTCP(c, sending, res, true)
|
||||||
|
in.Unpack(inb)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
in, err = exchangeUDP(c, sending, res, true)
|
inb, err = exchangeUDP(c, sending, res, true)
|
||||||
|
in.Unpack(inb)
|
||||||
}
|
}
|
||||||
res.Rtt[server] = time.Nanoseconds() - t
|
res.Rtt[server] = time.Nanoseconds() - t
|
||||||
|
|
||||||
@ -114,9 +118,12 @@ type Xfr struct {
|
|||||||
// Channel m is closed when the IXFR ends.
|
// Channel m is closed when the IXFR ends.
|
||||||
func (res *Resolver) Ixfr(q *Msg, m chan Xfr) {
|
func (res *Resolver) Ixfr(q *Msg, m chan Xfr) {
|
||||||
// TSIG
|
// TSIG
|
||||||
var port string
|
var (
|
||||||
var in *Msg
|
port string
|
||||||
var x Xfr
|
x Xfr
|
||||||
|
inb []byte
|
||||||
|
)
|
||||||
|
in := new(Msg)
|
||||||
if res.Port == "" {
|
if res.Port == "" {
|
||||||
port = "53"
|
port = "53"
|
||||||
} else {
|
} else {
|
||||||
@ -149,9 +156,11 @@ Server:
|
|||||||
defer c.Close()
|
defer c.Close()
|
||||||
for {
|
for {
|
||||||
if first {
|
if first {
|
||||||
in, err = exchangeTCP(c, sending, res, true)
|
inb, err = exchangeTCP(c, sending, res, true)
|
||||||
|
in.Unpack(inb)
|
||||||
} else {
|
} else {
|
||||||
in, err = exchangeTCP(c, sending, res, false)
|
inb, err = exchangeTCP(c, sending, res, false)
|
||||||
|
in.Unpack(inb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -220,8 +229,11 @@ Server:
|
|||||||
// the zone as-is. Xfr.Add is always true.
|
// the zone as-is. Xfr.Add is always true.
|
||||||
// The channel is closed to signal the end of the AXFR.
|
// The channel is closed to signal the end of the AXFR.
|
||||||
func (res *Resolver) AxfrTSIG(q *Msg, m chan Xfr, secret string) {
|
func (res *Resolver) AxfrTSIG(q *Msg, m chan Xfr, secret string) {
|
||||||
var port string
|
var (
|
||||||
var in *Msg
|
port string
|
||||||
|
inb []byte
|
||||||
|
)
|
||||||
|
in := new(Msg)
|
||||||
if res.Port == "" {
|
if res.Port == "" {
|
||||||
port = "53"
|
port = "53"
|
||||||
} else {
|
} else {
|
||||||
@ -263,9 +275,17 @@ Server:
|
|||||||
defer c.Close() // TODO(mg): if not open?
|
defer c.Close() // TODO(mg): if not open?
|
||||||
for {
|
for {
|
||||||
if first {
|
if first {
|
||||||
in, err = exchangeTCP(c, sending, res, true)
|
inb, err = exchangeTCP(c, sending, res, true)
|
||||||
|
stripTSIG(inb)
|
||||||
|
/*
|
||||||
|
pt2 := new(Msg)
|
||||||
|
pt2.Unpack(t2)
|
||||||
|
//println("P", pt2.String())
|
||||||
|
*/
|
||||||
|
in.Unpack(inb)
|
||||||
} else {
|
} else {
|
||||||
in, err = exchangeTCP(c, sending, res, false)
|
inb, err = exchangeTCP(c, sending, res, false)
|
||||||
|
in.Unpack(inb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -282,7 +302,7 @@ Server:
|
|||||||
t := in.Extra[len(in.Extra)-1]
|
t := in.Extra[len(in.Extra)-1]
|
||||||
switch t.(type) {
|
switch t.(type) {
|
||||||
case *RR_TSIG:
|
case *RR_TSIG:
|
||||||
if t.(*RR_TSIG).Verify(in, secret, reqmac) {
|
if t.(*RR_TSIG).Verify(inb, secret, reqmac) {
|
||||||
println("Validates")
|
println("Validates")
|
||||||
} else {
|
} else {
|
||||||
println("DOES NOT validate")
|
println("DOES NOT validate")
|
||||||
@ -322,8 +342,11 @@ Server:
|
|||||||
// the zone as-is. Xfr.Add is always true.
|
// the zone as-is. Xfr.Add is always true.
|
||||||
// The channel is closed to signal the end of the AXFR.
|
// The channel is closed to signal the end of the AXFR.
|
||||||
func (res *Resolver) Axfr(q *Msg, m chan Xfr) {
|
func (res *Resolver) Axfr(q *Msg, m chan Xfr) {
|
||||||
var port string
|
var (
|
||||||
var in *Msg
|
port string
|
||||||
|
inb []byte
|
||||||
|
)
|
||||||
|
in := new(Msg)
|
||||||
if res.Port == "" {
|
if res.Port == "" {
|
||||||
port = "53"
|
port = "53"
|
||||||
} else {
|
} else {
|
||||||
@ -343,17 +366,6 @@ func (res *Resolver) Axfr(q *Msg, m chan Xfr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Need the secret!
|
|
||||||
var tsig *RR_TSIG
|
|
||||||
// Check if there is a TSIG added
|
|
||||||
if len(q.Extra) > 0 {
|
|
||||||
lastrr := q.Extra[len(q.Extra)-1]
|
|
||||||
if lastrr.Header().Rrtype == TypeTSIG {
|
|
||||||
tsig = lastrr.(*RR_TSIG)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
Server:
|
Server:
|
||||||
for i := 0; i < len(res.Servers); i++ {
|
for i := 0; i < len(res.Servers); i++ {
|
||||||
server := res.Servers[i] + ":" + port
|
server := res.Servers[i] + ":" + port
|
||||||
@ -365,9 +377,11 @@ Server:
|
|||||||
defer c.Close() // TODO(mg): if not open?
|
defer c.Close() // TODO(mg): if not open?
|
||||||
for {
|
for {
|
||||||
if first {
|
if first {
|
||||||
in, err = exchangeTCP(c, sending, res, true)
|
inb, err = exchangeTCP(c, sending, res, true)
|
||||||
|
in.Unpack(inb)
|
||||||
} else {
|
} else {
|
||||||
in, err = exchangeTCP(c, sending, res, false)
|
inb, err = exchangeTCP(c, sending, res, false)
|
||||||
|
in.Unpack(inb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -408,7 +422,7 @@ Server:
|
|||||||
// Send a request on the connection and hope for a reply.
|
// Send a request on the connection and hope for a reply.
|
||||||
// Up to res.Attempts attempts. If send is false, nothing
|
// Up to res.Attempts attempts. If send is false, nothing
|
||||||
// is send.
|
// is send.
|
||||||
func exchangeUDP(c net.Conn, m []byte, r *Resolver, send bool) (*Msg, os.Error) {
|
func exchangeUDP(c net.Conn, m []byte, r *Resolver, send bool) ([]byte, os.Error) {
|
||||||
var timeout int64
|
var timeout int64
|
||||||
var attempts int
|
var attempts int
|
||||||
if r.Mangle != nil {
|
if r.Mangle != nil {
|
||||||
@ -443,18 +457,13 @@ func exchangeUDP(c net.Conn, m []byte, r *Resolver, send bool) (*Msg, os.Error)
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return buf, nil
|
||||||
in := new(Msg)
|
|
||||||
if !in.Unpack(buf) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return in, nil
|
|
||||||
}
|
}
|
||||||
return nil, &Error{Error: servErr}
|
return nil, &Error{Error: servErr}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Up to res.Attempts attempts.
|
// Up to res.Attempts attempts.
|
||||||
func exchangeTCP(c net.Conn, m []byte, r *Resolver, send bool) (*Msg, os.Error) {
|
func exchangeTCP(c net.Conn, m []byte, r *Resolver, send bool) ([]byte, os.Error) {
|
||||||
var timeout int64
|
var timeout int64
|
||||||
var attempts int
|
var attempts int
|
||||||
if r.Mangle != nil {
|
if r.Mangle != nil {
|
||||||
@ -484,7 +493,7 @@ func exchangeTCP(c net.Conn, m []byte, r *Resolver, send bool) (*Msg, os.Error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetReadTimeout(timeout * 1e9) // nanoseconds
|
c.SetReadTimeout(timeout * 1e9) // nanoseconds
|
||||||
// The server replies with two bytes length
|
// The server replies with two bytes length.
|
||||||
buf, err := recvTCP(c)
|
buf, err := recvTCP(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(net.Error); ok && e.Timeout() {
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
@ -492,11 +501,7 @@ func exchangeTCP(c net.Conn, m []byte, r *Resolver, send bool) (*Msg, os.Error)
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
in := new(Msg)
|
return buf, nil
|
||||||
if !in.Unpack(buf) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return in, nil
|
|
||||||
}
|
}
|
||||||
return nil, &Error{Error: servErr}
|
return nil, &Error{Error: servErr}
|
||||||
}
|
}
|
||||||
@ -510,7 +515,7 @@ func sendUDP(m []byte, c net.Conn) os.Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func recvUDP(c net.Conn) ([]byte, os.Error) {
|
func recvUDP(c net.Conn) ([]byte, os.Error) {
|
||||||
m := make([]byte, DefaultMsgSize) // More than enough???
|
m := make([]byte, DefaultMsgSize)
|
||||||
n, err := c.Read(m)
|
n, err := c.Read(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -537,8 +542,7 @@ func sendTCP(m []byte, c net.Conn) os.Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func recvTCP(c net.Conn) ([]byte, os.Error) {
|
func recvTCP(c net.Conn) ([]byte, os.Error) {
|
||||||
l := make([]byte, 2) // receiver length
|
l := make([]byte, 2) // The server replies with two bytes length.
|
||||||
// The server replies with two bytes length
|
|
||||||
_, err := c.Read(l)
|
_, err := c.Read(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
55
tsig.go
55
tsig.go
@ -107,7 +107,7 @@ func (t *RR_TSIG) Generate(m *Msg, secret string) bool {
|
|||||||
// the TSIG record still attached (as the last rr in the Additional
|
// the TSIG record still attached (as the last rr in the Additional
|
||||||
// section). Return true on success.
|
// section). Return true on success.
|
||||||
// The secret is a base64 encoded string with the secret.
|
// The secret is a base64 encoded string with the secret.
|
||||||
func (t *RR_TSIG) Verify(m *Msg, secret, reqmac string) bool {
|
func (t *RR_TSIG) Verify(m []byte, secret, reqmac string) bool {
|
||||||
rawsecret, err := packBase64([]byte(secret))
|
rawsecret, err := packBase64([]byte(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@ -121,9 +121,8 @@ func (t *RR_TSIG) Verify(m *Msg, secret, reqmac string) bool {
|
|||||||
if t.Header().Rrtype != TypeTSIG {
|
if t.Header().Rrtype != TypeTSIG {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
println(msg2.String())
|
|
||||||
msg2.MsgHdr.Id = t.OrigId
|
msg2.MsgHdr.Id = t.OrigId
|
||||||
println(msg2.String())
|
|
||||||
msg2.Extra = msg2.Extra[:len(msg2.Extra)-1] // Strip off the TSIG
|
msg2.Extra = msg2.Extra[:len(msg2.Extra)-1] // Strip off the TSIG
|
||||||
buf, ok := tsigToBuf(t, msg2, reqmac)
|
buf, ok := tsigToBuf(t, msg2, reqmac)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -182,3 +181,53 @@ func tsigToBuf(rr *RR_TSIG, msg *Msg, reqmac string) ([]byte, bool) {
|
|||||||
}
|
}
|
||||||
return buf, true
|
return buf, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strip the TSIG from the pkt.
|
||||||
|
func stripTSIG(orig []byte) ([]byte, bool) {
|
||||||
|
// Copied from msg.go's Unpack()
|
||||||
|
// Header.
|
||||||
|
var dh Header
|
||||||
|
dns := new(Msg)
|
||||||
|
msg := make([]byte, len(orig))
|
||||||
|
copy(msg, orig) // fhhh.. another copy
|
||||||
|
off := 0
|
||||||
|
tsigoff := 0
|
||||||
|
var ok bool
|
||||||
|
if off, ok = unpackStruct(&dh, msg, off); !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if dh.Arcount == 0 {
|
||||||
|
// No records at all in the additional.
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrays.
|
||||||
|
dns.Question = make([]Question, dh.Qdcount)
|
||||||
|
dns.Answer = make([]RR, dh.Ancount)
|
||||||
|
dns.Ns = make([]RR, dh.Nscount)
|
||||||
|
dns.Extra = make([]RR, dh.Arcount)
|
||||||
|
|
||||||
|
for i := 0; i < len(dns.Question); i++ {
|
||||||
|
off, ok = unpackStruct(&dns.Question[i], msg, off)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(dns.Answer); i++ {
|
||||||
|
dns.Answer[i], off, ok = unpackRR(msg, off)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(dns.Ns); i++ {
|
||||||
|
dns.Ns[i], off, ok = unpackRR(msg, off)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(dns.Extra); i++ {
|
||||||
|
tsigoff = off
|
||||||
|
dns.Extra[i], off, ok = unpackRR(msg, off)
|
||||||
|
if dns.Extra[i].Header().Rrtype == TypeTSIG {
|
||||||
|
// Adjust Arcount.
|
||||||
|
arcount, _ := unpackUint16(msg, 10)
|
||||||
|
msg[10], msg[11] = packUint16(arcount-1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return msg[:tsigoff], true
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user