]> Cypherpunks repositories - gostls13.git/commitdiff
net: set AD bit in DNS queries when trust-ad in resolv.conf
authorMateusz Poliwczak <mpoliwczak34@gmail.com>
Fri, 9 Sep 2022 06:40:57 +0000 (06:40 +0000)
committerGopher Robot <gobot@golang.org>
Fri, 16 Sep 2022 20:39:46 +0000 (20:39 +0000)
Fixes #51152

Change-Id: Ib366e733434b4bb60ac93e6e622d9ba50bfe4e26
GitHub-Last-Rev: e98220d62fc4f5b60aa3e4839f46ecf8f8f75485
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>

src/net/dnsclient_unix.go
src/net/dnsclient_unix_test.go
src/net/dnsconfig.go
src/net/dnsconfig_unix.go

index 2bf01b314cdeeaf50e68c07e24b9f7e6bc3a4815..74029d2311b785f7ef19265bc4ad6e62b5ee7ebb 100644 (file)
@@ -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(),
index 17798e434b146f70b8aeb080796a799cbf8d2523..553b220cbe295c537581fa6d54772a01fef40f74 100644 (file)
@@ -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)
+       }
+}
index 091b5483013f5acc4584b9bc018ffba27720f935..37252b5a0b5855e206d53dfc7ee65bad48296195 100644 (file)
@@ -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
index 65098f68275e4b38376dccb194d0a2c151e3ee94..962314b4b609192c1e9d8eb64cb84dbe75939bae 100644 (file)
@@ -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.