]> Cypherpunks repositories - gostls13.git/commitdiff
net: don't do DNS for onion and local addresses
authorBrad Fitzpatrick <bradfitz@golang.org>
Thu, 31 Mar 2016 06:08:44 +0000 (23:08 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sat, 2 Apr 2016 20:32:36 +0000 (20:32 +0000)
Fixes #13705

Change-Id: I86c60c78ce0394f830f904c9cba83ebbf3efc046
Reviewed-on: https://go-review.googlesource.com/21328
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/dnsclient_unix.go
src/net/dnsclient_unix_test.go

index 736e57322cc7c7571e6f407f380bb80cea07c973..cf0b2680dbcdec5d6f8f99e5afb0c62e458600e6 100644 (file)
@@ -319,8 +319,25 @@ func lookup(name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
        return
 }
 
+// avoidDNS reports whether this is a hostname for which we should not
+// use DNS. Currently this includes only .onion and .local names,
+// per RFC 7686 and RFC 6762, respectively. See golang.org/issue/13705.
+func avoidDNS(name string) bool {
+       if name == "" {
+               return true
+       }
+       if name[len(name)-1] == '.' {
+               name = name[:len(name)-1]
+       }
+       return stringsHasSuffixFold(name, ".onion") || stringsHasSuffixFold(name, ".local")
+}
+
 // nameList returns a list of names for sequential DNS queries.
 func (conf *dnsConfig) nameList(name string) []string {
+       if avoidDNS(name) {
+               return nil
+       }
+
        // If name is rooted (trailing dot), try only that name.
        rooted := len(name) > 0 && name[len(name)-1] == '.'
        if rooted {
index 4a5c438e46905845e3835c23c489a6f7eadfa6d0..6845481e17d722236d380f7c4add102c8a46783d 100644 (file)
@@ -94,6 +94,57 @@ func TestSpecialDomainName(t *testing.T) {
        }
 }
 
+// Issue 13705: don't try to resolve onion addresses, etc
+func TestAvoidDNSName(t *testing.T) {
+       tests := []struct {
+               name  string
+               avoid bool
+       }{
+               {"foo.com", false},
+               {"foo.com.", false},
+
+               {"foo.onion.", true},
+               {"foo.onion", true},
+               {"foo.ONION", true},
+               {"foo.ONION.", true},
+
+               {"foo.local.", true},
+               {"foo.local", true},
+               {"foo.LOCAL", true},
+               {"foo.LOCAL.", true},
+
+               {"", true}, // will be rejected earlier too
+
+               // Without stuff before onion/local, they're fine to
+               // use DNS. With a search path,
+               // "onion.vegegtables.com" can use DNS. Without a
+               // search path (or with a trailing dot), the queries
+               // are just kinda useless, but don't reveal anything
+               // private.
+               {"local", false},
+               {"onion", false},
+               {"local.", false},
+               {"onion.", false},
+       }
+       for _, tt := range tests {
+               got := avoidDNS(tt.name)
+               if got != tt.avoid {
+                       t.Errorf("avoidDNS(%q) = %v; want %v", tt.name, got, tt.avoid)
+               }
+       }
+}
+
+// Issue 13705: don't try to resolve onion addresses, etc
+func TestLookupTorOnion(t *testing.T) {
+       addrs, err := goLookupIP("foo.onion")
+       if len(addrs) > 0 {
+               t.Errorf("unexpected addresses: %v", addrs)
+       }
+       if err != nil {
+               t.Fatalf("lookup = %v; want nil", err)
+       }
+}
+
 type resolvConfTest struct {
        dir  string
        path string