mirror of
https://github.com/golang/go
synced 2024-10-14 03:43:28 +00:00
net: set AD bit in DNS queries when trust-ad in resolv.conf
Fixes #51152
Change-Id: Ib366e733434b4bb60ac93e6e622d9ba50bfe4e26
GitHub-Last-Rev: e98220d62f
GitHub-Pull-Request: golang/go#54921
Reviewed-on: https://go-review.googlesource.com/c/go/+/428955
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
a84f46a28a
commit
2d89bec2de
|
@ -51,9 +51,9 @@ var (
|
|||
errServerTemporarilyMisbehaving = errors.New("server misbehaving")
|
||||
)
|
||||
|
||||
func newRequest(q dnsmessage.Question) (id uint16, udpReq, tcpReq []byte, err error) {
|
||||
func newRequest(q dnsmessage.Question, ad bool) (id uint16, udpReq, tcpReq []byte, err error) {
|
||||
id = uint16(randInt())
|
||||
b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true})
|
||||
b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true, AuthenticData: ad})
|
||||
if err := b.StartQuestions(); err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
|
@ -157,9 +157,9 @@ func dnsStreamRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte)
|
|||
}
|
||||
|
||||
// exchange sends a query on the connection and hopes for a response.
|
||||
func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, useTCP bool) (dnsmessage.Parser, dnsmessage.Header, error) {
|
||||
func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, useTCP, ad bool) (dnsmessage.Parser, dnsmessage.Header, error) {
|
||||
q.Class = dnsmessage.ClassINET
|
||||
id, udpReq, tcpReq, err := newRequest(q)
|
||||
id, udpReq, tcpReq, err := newRequest(q, ad)
|
||||
if err != nil {
|
||||
return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string,
|
|||
for j := uint32(0); j < sLen; j++ {
|
||||
server := cfg.servers[(serverOffset+j)%sLen]
|
||||
|
||||
p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.useTCP)
|
||||
p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.useTCP, cfg.trustAD)
|
||||
if err != nil {
|
||||
dnsErr := &DNSError{
|
||||
Err: err.Error(),
|
||||
|
|
|
@ -79,7 +79,7 @@ func TestDNSTransportFallback(t *testing.T) {
|
|||
for _, tt := range dnsTransportFallbackTests {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, h, err := r.exchange(ctx, tt.server, tt.question, time.Second, useUDPOrTCP)
|
||||
_, h, err := r.exchange(ctx, tt.server, tt.question, time.Second, useUDPOrTCP, false)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
|
@ -135,7 +135,7 @@ func TestSpecialDomainName(t *testing.T) {
|
|||
for _, tt := range specialDomainNameTests {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, h, err := r.exchange(ctx, server, tt.question, 3*time.Second, useUDPOrTCP)
|
||||
_, h, err := r.exchange(ctx, server, tt.question, 3*time.Second, useUDPOrTCP, false)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
|
@ -1593,7 +1593,7 @@ func TestDNSDialTCP(t *testing.T) {
|
|||
}
|
||||
r := Resolver{PreferGo: true, Dial: fake.DialContext}
|
||||
ctx := context.Background()
|
||||
_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useUDPOrTCP)
|
||||
_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useUDPOrTCP, false)
|
||||
if err != nil {
|
||||
t.Fatal("exhange failed:", err)
|
||||
}
|
||||
|
@ -1746,7 +1746,7 @@ func TestDNSUseTCP(t *testing.T) {
|
|||
r := Resolver{PreferGo: true, Dial: fake.DialContext}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useTCPOnly)
|
||||
_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useTCPOnly, false)
|
||||
if err != nil {
|
||||
t.Fatal("exchange failed:", err)
|
||||
}
|
||||
|
@ -2344,3 +2344,68 @@ func TestLongDNSNames(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSTrustAD(t *testing.T) {
|
||||
fake := fakeDNSServer{
|
||||
rh: func(_, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
|
||||
if q.Questions[0].Name.String() == "notrustad.go.dev." && q.Header.AuthenticData {
|
||||
t.Error("unexpected AD bit")
|
||||
}
|
||||
|
||||
if q.Questions[0].Name.String() == "trustad.go.dev." && !q.Header.AuthenticData {
|
||||
t.Error("expected AD bit")
|
||||
}
|
||||
|
||||
r := dnsmessage.Message{
|
||||
Header: dnsmessage.Header{
|
||||
ID: q.Header.ID,
|
||||
Response: true,
|
||||
RCode: dnsmessage.RCodeSuccess,
|
||||
},
|
||||
Questions: q.Questions,
|
||||
}
|
||||
if q.Questions[0].Type == dnsmessage.TypeA {
|
||||
r.Answers = []dnsmessage.Resource{
|
||||
{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: q.Questions[0].Name,
|
||||
Type: dnsmessage.TypeA,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.AResource{
|
||||
A: TestAddr,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}}
|
||||
|
||||
r := &Resolver{PreferGo: true, Dial: fake.DialContext}
|
||||
|
||||
conf, err := newResolvConfTest()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer conf.teardown()
|
||||
|
||||
err = conf.writeAndUpdate([]string{"nameserver 127.0.0.1"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := r.LookupIPAddr(context.Background(), "notrustad.go.dev"); err != nil {
|
||||
t.Errorf("lookup failed: %v", err)
|
||||
}
|
||||
|
||||
err = conf.writeAndUpdate([]string{"nameserver 127.0.0.1", "options trust-ad"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := r.LookupIPAddr(context.Background(), "trustad.go.dev"); err != nil {
|
||||
t.Errorf("lookup failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ type dnsConfig struct {
|
|||
soffset uint32 // used by serverOffset
|
||||
singleRequest bool // use sequential A and AAAA queries instead of parallel queries
|
||||
useTCP bool // force usage of TCP for DNS resolutions
|
||||
trustAD bool // add AD flag to queries
|
||||
}
|
||||
|
||||
// serverOffset returns an offset that can be used to determine
|
||||
|
|
|
@ -113,6 +113,8 @@ func dnsReadConfig(filename string) *dnsConfig {
|
|||
// https://www.freebsd.org/cgi/man.cgi?query=resolv.conf&sektion=5&manpath=freebsd-release-ports
|
||||
// https://man.openbsd.org/resolv.conf.5
|
||||
conf.useTCP = true
|
||||
case s == "trust-ad":
|
||||
conf.trustAD = true
|
||||
case s == "edns0":
|
||||
// We use EDNS by default.
|
||||
// Ignore this option.
|
||||
|
|
Loading…
Reference in a new issue