Commit 4bd95702 authored by Dan Peterson's avatar Dan Peterson Committed by Matthew Dempsky

net: expand nss myhostname fallback detection

Expand myhostname fallback detection to properly detect the local
hostname in addition to other supported special names and suffixes.

Fixes #17967

Change-Id: I1fe141fd9838b25886c08b6f2fd325e58be60457
Reviewed-on: https://go-review.googlesource.com/33550Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent c77e80df
......@@ -179,8 +179,6 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
}
}
hasDot := byteIndex(hostname, '.') != -1
// Canonicalize the hostname by removing any trailing dot.
if stringsHasSuffix(hostname, ".") {
hostname = hostname[:len(hostname)-1]
......@@ -220,10 +218,14 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
var first string
for _, src := range srcs {
if src.source == "myhostname" {
if hostname == "" || hasDot {
continue
if isLocalhost(hostname) || isGateway(hostname) {
return fallbackOrder
}
return fallbackOrder
hn, err := getHostname()
if err != nil || stringsEqualFold(hostname, hn) {
return fallbackOrder
}
continue
}
if src.source == "files" || src.source == "dns" {
if !src.standardCriteria() {
......@@ -306,3 +308,15 @@ func goDebugNetDNS() (dnsMode string, debugLevel int) {
parsePart(goDebug)
return
}
// isLocalhost reports whether h should be considered a "localhost"
// name for the myhostname NSS module.
func isLocalhost(h string) bool {
return stringsEqualFold(h, "localhost") || stringsEqualFold(h, "localhost.localdomain") || stringsHasSuffixFold(h, ".localhost") || stringsHasSuffixFold(h, ".localhost.localdomain")
}
// isGateway reports whether h should be considered a "gateway"
// name for the myhostname NSS module.
func isGateway(h string) bool {
return stringsEqualFold(h, "gateway")
}
......@@ -13,8 +13,9 @@ import (
)
type nssHostTest struct {
host string
want hostLookupOrder
host string
localhost string
want hostLookupOrder
}
func nssStr(s string) *nssConf { return parseNSSConf(strings.NewReader(s)) }
......@@ -42,8 +43,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"foo.local", hostLookupCgo},
{"google.com", hostLookupCgo},
{"foo.local", "myhostname", hostLookupCgo},
{"google.com", "myhostname", hostLookupCgo},
},
},
{
......@@ -54,7 +55,7 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupDNSFiles},
{"x.com", "myhostname", hostLookupDNSFiles},
},
},
{
......@@ -65,7 +66,7 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS},
{"x.com", "myhostname", hostLookupFilesDNS},
},
},
{
......@@ -75,11 +76,11 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"foo.local", hostLookupCgo},
{"foo.local.", hostLookupCgo},
{"foo.LOCAL", hostLookupCgo},
{"foo.LOCAL.", hostLookupCgo},
{"google.com", hostLookupFilesDNS},
{"foo.local", "myhostname", hostLookupCgo},
{"foo.local.", "myhostname", hostLookupCgo},
{"foo.LOCAL", "myhostname", hostLookupCgo},
{"foo.LOCAL.", "myhostname", hostLookupCgo},
{"google.com", "myhostname", hostLookupFilesDNS},
},
},
{
......@@ -89,7 +90,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: nssStr("foo: bar"),
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
},
// On OpenBSD, no resolv.conf means no DNS.
{
......@@ -98,7 +99,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd",
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{{"google.com", hostLookupFiles}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
},
{
name: "solaris_no_nsswitch",
......@@ -107,7 +108,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: &nssConf{err: os.ErrNotExist},
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
},
{
name: "openbsd_lookup_bind_file",
......@@ -116,8 +117,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: &dnsConfig{lookup: []string{"bind", "file"}},
},
hostTests: []nssHostTest{
{"google.com", hostLookupDNSFiles},
{"foo.local", hostLookupDNSFiles},
{"google.com", "myhostname", hostLookupDNSFiles},
{"foo.local", "myhostname", hostLookupDNSFiles},
},
},
{
......@@ -126,7 +127,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file", "bind"}},
},
hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
},
{
name: "openbsd_lookup_bind",
......@@ -134,7 +135,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"bind"}},
},
hostTests: []nssHostTest{{"google.com", hostLookupDNS}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNS}},
},
{
name: "openbsd_lookup_file",
......@@ -142,7 +143,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file"}},
},
hostTests: []nssHostTest{{"google.com", hostLookupFiles}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
},
{
name: "openbsd_lookup_yp",
......@@ -150,7 +151,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}},
},
hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
},
{
name: "openbsd_lookup_two",
......@@ -158,7 +159,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd",
resolv: &dnsConfig{lookup: []string{"file", "foo"}},
},
hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
},
{
name: "openbsd_lookup_empty",
......@@ -166,7 +167,7 @@ func TestConfHostLookupOrder(t *testing.T) {
goos: "openbsd",
resolv: &dnsConfig{lookup: nil},
},
hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}},
},
// glibc lacking an nsswitch.conf, per
// http://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html
......@@ -177,7 +178,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: &nssConf{err: os.ErrNotExist},
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}},
},
{
name: "files_mdns_dns",
......@@ -186,8 +187,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS},
{"x.local", hostLookupCgo},
{"x.com", "myhostname", hostLookupFilesDNS},
{"x.local", "myhostname", hostLookupCgo},
},
},
{
......@@ -197,9 +198,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupDNS},
{"x\\.com", hostLookupCgo}, // punt on weird glibc escape
{"foo.com%en0", hostLookupCgo}, // and IPv6 zones
{"x.com", "myhostname", hostLookupDNS},
{"x\\.com", "myhostname", hostLookupCgo}, // punt on weird glibc escape
{"foo.com%en0", "myhostname", hostLookupCgo}, // and IPv6 zones
},
},
{
......@@ -210,8 +211,8 @@ func TestConfHostLookupOrder(t *testing.T) {
hasMDNSAllow: true,
},
hostTests: []nssHostTest{
{"x.com", hostLookupCgo},
{"x.local", hostLookupCgo},
{"x.com", "myhostname", hostLookupCgo},
{"x.local", "myhostname", hostLookupCgo},
},
},
{
......@@ -221,9 +222,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS},
{"x", hostLookupFilesDNS},
{"x.local", hostLookupCgo},
{"x.com", "myhostname", hostLookupFilesDNS},
{"x", "myhostname", hostLookupFilesDNS},
{"x.local", "myhostname", hostLookupCgo},
},
},
{
......@@ -233,9 +234,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupDNSFiles},
{"x", hostLookupDNSFiles},
{"x.local", hostLookupCgo},
{"x.com", "myhostname", hostLookupDNSFiles},
{"x", "myhostname", hostLookupDNSFiles},
{"x.local", "myhostname", hostLookupCgo},
},
},
{
......@@ -245,7 +246,7 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupCgo},
{"x.com", "myhostname", hostLookupCgo},
},
},
{
......@@ -255,9 +256,23 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS},
{"somehostname", hostLookupCgo},
{"", hostLookupFilesDNS}, // Issue 13623
{"x.com", "myhostname", hostLookupFilesDNS},
{"myhostname", "myhostname", hostLookupCgo},
{"myHostname", "myhostname", hostLookupCgo},
{"myhostname.dot", "myhostname.dot", hostLookupCgo},
{"myHostname.dot", "myhostname.dot", hostLookupCgo},
{"gateway", "myhostname", hostLookupCgo},
{"Gateway", "myhostname", hostLookupCgo},
{"localhost", "myhostname", hostLookupCgo},
{"Localhost", "myhostname", hostLookupCgo},
{"anything.localhost", "myhostname", hostLookupCgo},
{"Anything.localhost", "myhostname", hostLookupCgo},
{"localhost.localdomain", "myhostname", hostLookupCgo},
{"Localhost.Localdomain", "myhostname", hostLookupCgo},
{"anything.localhost.localdomain", "myhostname", hostLookupCgo},
{"Anything.Localhost.Localdomain", "myhostname", hostLookupCgo},
{"somehostname", "myhostname", hostLookupFilesDNS},
{"", "myhostname", hostLookupFilesDNS}, // Issue 13623
},
},
{
......@@ -267,8 +282,9 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS},
{"somehostname", hostLookupCgo},
{"x.com", "myhostname", hostLookupFilesDNS},
{"somehostname", "myhostname", hostLookupFilesDNS},
{"myhostname", "myhostname", hostLookupCgo},
},
},
// Debian Squeeze is just "dns,files", but lists all
......@@ -282,8 +298,8 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupDNSFiles},
{"somehostname", hostLookupDNSFiles},
{"x.com", "myhostname", hostLookupDNSFiles},
{"somehostname", "myhostname", hostLookupDNSFiles},
},
},
{
......@@ -292,7 +308,7 @@ func TestConfHostLookupOrder(t *testing.T) {
nss: nssStr("foo: bar"),
resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true},
},
hostTests: []nssHostTest{{"google.com", hostLookupCgo}},
hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
},
// Android should always use cgo.
{
......@@ -303,12 +319,18 @@ func TestConfHostLookupOrder(t *testing.T) {
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupCgo},
{"x.com", "myhostname", hostLookupCgo},
},
},
}
origGetHostname := getHostname
defer func() { getHostname = origGetHostname }()
for _, tt := range tests {
for _, ht := range tt.hostTests {
getHostname = func() (string, error) { return ht.localhost, nil }
gotOrder := tt.c.hostLookupOrder(ht.host)
if gotOrder != ht.want {
t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want)
......
......@@ -334,22 +334,28 @@ func stringsHasSuffix(s, suffix string) bool {
// stringsHasSuffixFold reports whether s ends in suffix,
// ASCII-case-insensitively.
func stringsHasSuffixFold(s, suffix string) bool {
if len(suffix) > len(s) {
return len(s) >= len(suffix) && stringsEqualFold(s[len(s)-len(suffix):], suffix)
}
// stringsHasPrefix is strings.HasPrefix. It reports whether s begins with prefix.
func stringsHasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
// stringsEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
// are equal, ASCII-case-insensitively.
func stringsEqualFold(s, t string) bool {
if len(s) != len(t) {
return false
}
for i := 0; i < len(suffix); i++ {
if lowerASCII(suffix[i]) != lowerASCII(s[len(s)-len(suffix)+i]) {
for i := 0; i < len(s); i++ {
if lowerASCII(s[i]) != lowerASCII(t[i]) {
return false
}
}
return true
}
// stringsHasPrefix is strings.HasPrefix. It reports whether s begins with prefix.
func stringsHasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
func readFull(r io.Reader) (all []byte, err error) {
buf := make([]byte, 1024)
for {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment