mirror of
https://github.com/safing/portmaster
synced 2025-09-01 10:09:11 +00:00
Fix FQDN validation and add tests
This commit is contained in:
parent
75d7a91843
commit
ca8b36cbc7
2 changed files with 89 additions and 2 deletions
|
@ -2,13 +2,57 @@ package netutils
|
|||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
var (
|
||||
cleanDomainRegex = regexp.MustCompile(`^((xn--)?[a-z0-9-_]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,}\.)$`)
|
||||
cleanDomainRegex = regexp.MustCompile(
|
||||
`^` + // match beginning
|
||||
`(` + // start subdomain group
|
||||
`(xn--)?` + // idn prefix
|
||||
`[a-z0-9_-]{1,63}` + // main chunk
|
||||
`\.` + // ending with a dot
|
||||
`)*` + // end subdomain group, allow any number of subdomains
|
||||
`(xn--)?` + // TLD idn prefix
|
||||
`[a-z0-9_-]{2,63}` + // TLD main chunk with at least two characters
|
||||
`\.` + // ending with a dot
|
||||
`$`, // match end
|
||||
)
|
||||
)
|
||||
|
||||
// IsValidFqdn returns whether the given string is a valid fqdn.
|
||||
func IsValidFqdn(fqdn string) bool {
|
||||
return cleanDomainRegex.MatchString(fqdn)
|
||||
// root zone
|
||||
if fqdn == "." {
|
||||
return true
|
||||
}
|
||||
|
||||
// check max length
|
||||
if len(fqdn) > 256 {
|
||||
return false
|
||||
}
|
||||
|
||||
// check with regex
|
||||
if !cleanDomainRegex.MatchString(fqdn) {
|
||||
return false
|
||||
}
|
||||
|
||||
// check with miegk/dns
|
||||
|
||||
// IsFqdn checks if a domain name is fully qualified.
|
||||
if !dns.IsFqdn(fqdn) {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsDomainName checks if s is a valid domain name, it returns the number of
|
||||
// labels and true, when a domain name is valid. Note that non fully qualified
|
||||
// domain name is considered valid, in this case the last label is counted in
|
||||
// the number of labels. When false is returned the number of labels is not
|
||||
// defined. Also note that this function is extremely liberal; almost any
|
||||
// string is a valid domain name as the DNS is 8 bit protocol. It checks if each
|
||||
// label fits in 63 characters and that the entire name will fit into the 255
|
||||
// octet wire format limit.
|
||||
_, ok := dns.IsDomainName(fqdn)
|
||||
return ok
|
||||
}
|
||||
|
|
43
network/netutils/cleandns_test.go
Normal file
43
network/netutils/cleandns_test.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package netutils
|
||||
|
||||
import "testing"
|
||||
|
||||
func testDomainValidity(t *testing.T, domain string, isValid bool) {
|
||||
if IsValidFqdn(domain) != isValid {
|
||||
t.Errorf("domain %s failed check: was valid=%v, expected valid=%v", domain, IsValidFqdn(domain), isValid)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNSValidation(t *testing.T) {
|
||||
// valid
|
||||
testDomainValidity(t, ".", true)
|
||||
testDomainValidity(t, "at.", true)
|
||||
testDomainValidity(t, "orf.at.", true)
|
||||
testDomainValidity(t, "www.orf.at.", true)
|
||||
testDomainValidity(t, "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.x.y.z.example.org.", true)
|
||||
testDomainValidity(t, "a_a.com.", true)
|
||||
testDomainValidity(t, "a-a.com.", true)
|
||||
testDomainValidity(t, "a_a.com.", true)
|
||||
testDomainValidity(t, "a-a.com.", true)
|
||||
testDomainValidity(t, "xn--a.com.", true)
|
||||
testDomainValidity(t, "xn--asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd.com.", true)
|
||||
|
||||
// maybe valid
|
||||
testDomainValidity(t, "-.com.", true)
|
||||
testDomainValidity(t, "_.com.", true)
|
||||
testDomainValidity(t, "a_.com.", true)
|
||||
testDomainValidity(t, "a-.com.", true)
|
||||
testDomainValidity(t, "_a.com.", true)
|
||||
testDomainValidity(t, "-a.com.", true)
|
||||
|
||||
// invalid
|
||||
testDomainValidity(t, ".com.", false)
|
||||
testDomainValidity(t, ".com.", false)
|
||||
testDomainValidity(t, "xn--asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf.com.", false)
|
||||
testDomainValidity(t, "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf.com.", false)
|
||||
testDomainValidity(t, "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf.com.", false)
|
||||
testDomainValidity(t, "asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.asdf.as.com.", false)
|
||||
|
||||
// real world examples
|
||||
testDomainValidity(t, "iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com.", true)
|
||||
}
|
Loading…
Add table
Reference in a new issue