diff options
| author | David Anderson <danderson@tailscale.com> | 2021-05-31 19:31:29 -0700 |
|---|---|---|
| committer | Dave Anderson <dave@natulte.net> | 2021-05-31 21:13:50 -0700 |
| commit | caaefa00a0605834279bc01ec43b9e48e8588d72 (patch) | |
| tree | 91566288b3ea2306ffa0d3d3fba52a744fa8b6b6 | |
| parent | 2802a01b8199a10c41241eb2699ab158be276df7 (diff) | |
| download | tailscale-caaefa00a0605834279bc01ec43b9e48e8588d72.tar.xz tailscale-caaefa00a0605834279bc01ec43b9e48e8588d72.zip | |
util/dnsname: don't validate the contents of DNS labels.
DNS names consist of labels, but outside of length limits, DNS
itself permits any content within the labels. Some records require
labels to conform to hostname limitations (which is what we implemented
before), but not all.
Fixes #2024.
Signed-off-by: David Anderson <danderson@tailscale.com>
| -rw-r--r-- | util/dnsname/dnsname.go | 40 | ||||
| -rw-r--r-- | util/dnsname/dnsname_test.go | 1 |
2 files changed, 17 insertions, 24 deletions
diff --git a/util/dnsname/dnsname.go b/util/dnsname/dnsname.go index 905e90f5f..6ed85c84f 100644 --- a/util/dnsname/dnsname.go +++ b/util/dnsname/dnsname.go @@ -48,21 +48,6 @@ func ToFQDN(s string) (FQDN, error) { return FQDN(s + "."), nil } -func validLabel(s string) bool { - if len(s) == 0 || len(s) > maxLabelLength { - return false - } - if !isalphanum(s[0]) || !isalphanum(s[len(s)-1]) { - return false - } - for i := 1; i < len(s)-1; i++ { - if !isalphanum(s[i]) && s[i] != '-' { - return false - } - } - return true -} - // WithTrailingDot returns f as a string, with a trailing dot. func (f FQDN) WithTrailingDot() string { return string(f) @@ -120,23 +105,30 @@ func isValidFQDN(s string) bool { continue } label := s[st:i] - if len(label) == 0 || len(label) > maxLabelLength { - return false - } - if !isalphanum(label[0]) || !isalphanum(label[len(label)-1]) { + if !validLabel(label) { return false } - for j := 1; j < len(label)-1; j++ { - if !isalphanum(label[j]) && label[j] != '-' { - return false - } - } st = i + 1 } return true } +func validLabel(s string) bool { + // You might be tempted to do further validation of the + // contents of labels here, based on the hostname rules in RFC + // 1123. However, DNS labels are not always subject to + // hostname rules. In general, they can contain any non-zero + // byte sequence, even though in practice a more restricted + // set is used. + // + // See https://github.com/tailscale/tailscale/issues/2024 for more. + if len(s) == 0 || len(s) > maxLabelLength { + return false + } + return true +} + // SanitizeLabel takes a string intended to be a DNS name label // and turns it into a valid name label according to RFC 1035. func SanitizeLabel(label string) string { diff --git a/util/dnsname/dnsname_test.go b/util/dnsname/dnsname_test.go index df3ea30b6..4867df2ac 100644 --- a/util/dnsname/dnsname_test.go +++ b/util/dnsname/dnsname_test.go @@ -24,6 +24,7 @@ func TestFQDN(t *testing.T) { {".foo.com", "foo.com.", false, 2}, {"com", "com.", false, 1}, {"www.tailscale.com", "www.tailscale.com.", false, 3}, + {"_ssh._tcp.tailscale.com", "_ssh._tcp.tailscale.com.", false, 4}, {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", "", true, 0}, {strings.Repeat("aaaaa.", 60) + "com", "", true, 0}, {"foo..com", "", true, 0}, |
