diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-03-05 02:29:41 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-03-05 05:36:21 +0100 |
commit | 776df7d7249671e5595f5f176fb9160df7694689 (patch) | |
tree | 55d388c2c0b3bfb6164f564740a8b8881ebdc315 /conf | |
parent | build: musl.cc now offers zips (diff) | |
download | wireguard-windows-776df7d7249671e5595f5f176fb9160df7694689.tar.xz wireguard-windows-776df7d7249671e5595f5f176fb9160df7694689.zip |
conf: validate tunnel name
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'conf')
-rw-r--r-- | conf/name.go | 49 | ||||
-rw-r--r-- | conf/parser.go | 3 | ||||
-rw-r--r-- | conf/store.go | 18 |
3 files changed, 69 insertions, 1 deletions
diff --git a/conf/name.go b/conf/name.go new file mode 100644 index 00000000..da9928e0 --- /dev/null +++ b/conf/name.go @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + */ + +package conf + +import ( + "regexp" + "strings" +) + +var reservedNames = []string{ + "CON", "PRN", "AUX", "NUL", + "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", + "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", +} + +const specialChars = "/\\<>:\"|?*\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x00" + +var allowedNameFormat *regexp.Regexp + +func init() { + allowedNameFormat = regexp.MustCompile("^[a-zA-Z0-9_=+.-]{1,32}$") +} + +func isReserved(name string) bool { + if len(name) == 0 { + return false + } + for _, reserved := range reservedNames { + if strings.EqualFold(name, reserved) { + return true + } + } + return false +} + +func hasSpecialChars(name string) bool { + return strings.ContainsAny(name, specialChars) +} + +func TunnelNameIsValid(name string) bool { + // Aside from our own restrictions, let's impose the Windows restrictions first + if isReserved(name) || hasSpecialChars(name) { + return false + } + return allowedNameFormat.MatchString(name) +} diff --git a/conf/parser.go b/conf/parser.go index 3b2ae1b3..b9ceb20e 100644 --- a/conf/parser.go +++ b/conf/parser.go @@ -189,6 +189,9 @@ func (c *Config) maybeAddPeer(p *Peer) { } func FromWgQuick(s string, name string) (*Config, error) { + if !TunnelNameIsValid(name) { + return nil, &ParseError{"Tunnel name is not valid", name} + } lines := strings.Split(s, "\n") parserState := notInASection conf := Config{Name: name} diff --git a/conf/store.go b/conf/store.go index 7c110865..da144a17 100644 --- a/conf/store.go +++ b/conf/store.go @@ -36,7 +36,11 @@ func ListConfigNames() ([]string, error) { if !file.Mode().IsRegular() || file.Mode().Perm()&0444 == 0 { continue } - configs[i] = strings.TrimSuffix(name, configFileSuffix) + name = strings.TrimSuffix(name, configFileSuffix) + if !TunnelNameIsValid(name) { + continue + } + configs[i] = name i++ } return configs[:i], nil @@ -152,10 +156,16 @@ func NameFromPath(path string) (string, error) { } else { name = strings.TrimSuffix(name, configFileUnencryptedSuffix) } + if !TunnelNameIsValid(name) { + return "", errors.New("Tunnel name is not valid") + } return name, nil } func (config *Config) Save() error { + if !TunnelNameIsValid(config.Name) { + return errors.New("Tunnel name is not valid") + } configFileDir, err := resolveConfigFileDir() if err != nil { return err @@ -179,6 +189,9 @@ func (config *Config) Save() error { } func (config *Config) Path() (string, error) { + if !TunnelNameIsValid(config.Name) { + return "", errors.New("Tunnel name is not valid") + } configFileDir, err := resolveConfigFileDir() if err != nil { return "", err @@ -187,6 +200,9 @@ func (config *Config) Path() (string, error) { } func DeleteName(name string) error { + if !TunnelNameIsValid(name) { + return errors.New("Tunnel name is not valid") + } configFileDir, err := resolveConfigFileDir() if err != nil { return err |