3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-29 07:29:31 +01:00

more permissive hostname validation

In particular, allow hostnames without periods (like on a LAN).
This shouldn't be a client compability concern since we allow
vhosts without periods.
This commit is contained in:
Shivaram Lingamneni 2019-12-18 09:21:45 -05:00
parent 4b37b5dd3e
commit f1e2bbc0e4
3 changed files with 28 additions and 12 deletions

View File

@ -593,7 +593,7 @@ func LoadConfig(filename string) (config *Config, err error) {
if config.Server.Name == "" { if config.Server.Name == "" {
return nil, ErrServerNameMissing return nil, ErrServerNameMissing
} }
if !utils.IsHostname(config.Server.Name) { if !utils.IsServerName(config.Server.Name) {
return nil, ErrServerNameNotHostname return nil, ErrServerNameNotHostname
} }
if config.Datastore.Path == "" { if config.Datastore.Path == "" {

View File

@ -6,6 +6,7 @@ package utils
import ( import (
"net" "net"
"regexp"
"strings" "strings"
) )
@ -13,6 +14,8 @@ var (
// subnet mask for an ipv6 /128: // subnet mask for an ipv6 /128:
mask128 = net.CIDRMask(128, 128) mask128 = net.CIDRMask(128, 128)
IPv4LoopbackAddress = net.ParseIP("127.0.0.1").To16() IPv4LoopbackAddress = net.ParseIP("127.0.0.1").To16()
validHostnameLabelRegexp = regexp.MustCompile(`^[0-9A-Za-z.\-]+$`)
) )
// AddrIsLocal returns whether the address is from a trusted local connection (loopback or unix). // AddrIsLocal returns whether the address is from a trusted local connection (loopback or unix).
@ -49,12 +52,10 @@ func IPStringToHostname(ipStr string) string {
return ipStr return ipStr
} }
var allowedHostnameChars = "abcdefghijklmnopqrstuvwxyz1234567890-."
// IsHostname returns whether we consider `name` a valid hostname. // IsHostname returns whether we consider `name` a valid hostname.
func IsHostname(name string) bool { func IsHostname(name string) bool {
// IRC hostnames specifically require a period name = strings.TrimSuffix(name, ".")
if !strings.Contains(name, ".") || len(name) < 1 || len(name) > 253 { if len(name) < 1 || len(name) > 253 {
return false return false
} }
@ -63,11 +64,7 @@ func IsHostname(name string) bool {
if len(part) < 1 || len(part) > 63 || strings.HasPrefix(part, "-") || strings.HasSuffix(part, "-") { if len(part) < 1 || len(part) > 63 || strings.HasPrefix(part, "-") || strings.HasSuffix(part, "-") {
return false return false
} }
} if !validHostnameLabelRegexp.MatchString(part) {
// ensure all chars of hostname are valid
for _, char := range strings.Split(strings.ToLower(name), "") {
if !strings.Contains(allowedHostnameChars, char) {
return false return false
} }
} }
@ -75,6 +72,12 @@ func IsHostname(name string) bool {
return true return true
} }
// IsServerName returns whether we consider `name` a valid IRC server name.
func IsServerName(name string) bool {
// IRC server names specifically require a period
return IsHostname(name) && strings.IndexByte(name, '.') != -1
}
// Convenience to test whether `ip` is contained in any of `nets`. // Convenience to test whether `ip` is contained in any of `nets`.
func IPInNets(ip net.IP, nets []net.IPNet) bool { func IPInNets(ip net.IP, nets []net.IPNet) bool {
for _, network := range nets { for _, network := range nets {

View File

@ -24,14 +24,18 @@ var (
"gsf.ds342.co.uk", "gsf.ds342.co.uk",
"324.net.uk", "324.net.uk",
"xn--bcher-kva.ch", "xn--bcher-kva.ch",
"pentos",
"pentos.",
"www.google.com.",
} }
badHostnames = []string{ badHostnames = []string{
"-lol-.net.uk", "-lol-.net.uk",
"-lol.net.uk", "-lol.net.uk",
"_irc._sctp.lol.net.uk", "_irc._sctp.lol.net.uk",
"irc", "irc.l%l.net.uk",
"com", "irc..net.uk",
".",
"", "",
} }
) )
@ -56,6 +60,15 @@ func TestIsHostname(t *testing.T) {
} }
} }
func TestIsServerName(t *testing.T) {
if IsServerName("pentos") {
t.Error("irc server names must contain a period")
}
if !IsServerName("darwin.network") {
t.Error("failed to validate a perfectly good server name")
}
}
func TestNormalizeToNet(t *testing.T) { func TestNormalizeToNet(t *testing.T) {
a := net.ParseIP("8.8.8.8") a := net.ParseIP("8.8.8.8")
b := net.ParseIP("8.8.4.4") b := net.ParseIP("8.8.4.4")