aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--conf/name.go49
-rw-r--r--conf/parser.go3
-rw-r--r--conf/store.go18
-rw-r--r--service/install.go16
-rw-r--r--service/ipc_server.go18
-rw-r--r--service/names.go25
-rw-r--r--service/service_manager.go1
-rw-r--r--service/tunneltracker.go5
8 files changed, 126 insertions, 9 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
diff --git a/service/install.go b/service/install.go
index bb2fb046..4203d066 100644
--- a/service/install.go
+++ b/service/install.go
@@ -122,7 +122,10 @@ func InstallTunnel(configPath string) error {
return err
}
- serviceName := "WireGuard Tunnel: " + name
+ serviceName, err := ServiceNameOfTunnel(name)
+ if err != nil {
+ return err
+ }
service, err := m.OpenService(serviceName)
if err == nil {
status, err := service.Query()
@@ -169,7 +172,10 @@ func UninstallTunnel(name string) error {
if err != nil {
return err
}
- serviceName := "WireGuard Tunnel: " + name
+ serviceName, err := ServiceNameOfTunnel(name)
+ if err != nil {
+ return err
+ }
service, err := m.OpenService(serviceName)
if err != nil {
return err
@@ -188,5 +194,9 @@ func RunTunnel(confPath string) error {
if err != nil {
return err
}
- return svc.Run("WireGuard Tunnel: "+name, &tunnelService{confPath})
+ serviceName, err := ServiceNameOfTunnel(name)
+ if err != nil {
+ return err
+ }
+ return svc.Run(serviceName, &tunnelService{confPath})
}
diff --git a/service/ipc_server.go b/service/ipc_server.go
index ed239d85..5f16eab9 100644
--- a/service/ipc_server.go
+++ b/service/ipc_server.go
@@ -43,14 +43,20 @@ func (s *ManagerService) RuntimeConfig(tunnelName string, config *conf.Config) e
if err != nil {
return err
}
- pipe, err := winio.DialPipe("\\\\.\\pipe\\wireguard\\"+storedConfig.Name, nil)
+ pipePath, err := PipePathOfTunnel(storedConfig.Name)
if err != nil {
return err
}
+ pipe, err := winio.DialPipe(pipePath, nil)
+ if err != nil {
+ return err
+ }
+ pipe.SetWriteDeadline(time.Now().Add(time.Second * 2))
_, err = pipe.Write([]byte("get=1\n\n"))
if err != nil {
return err
}
+ pipe.SetReadDeadline(time.Now().Add(time.Second * 2))
resp, err := ioutil.ReadAll(pipe)
if err != nil {
return err
@@ -88,7 +94,10 @@ func (s *ManagerService) Stop(tunnelName string, unused *uintptr) error {
}
func (s *ManagerService) WaitForStop(tunnelName string, unused *uintptr) error {
- serviceName := "WireGuard Tunnel: " + tunnelName
+ serviceName, err := ServiceNameOfTunnel(tunnelName)
+ if err != nil {
+ return err
+ }
m, err := serviceManager()
if err != nil {
return err
@@ -113,7 +122,10 @@ func (s *ManagerService) Delete(tunnelName string, unused *uintptr) error {
}
func (s *ManagerService) State(tunnelName string, state *TunnelState) error {
- serviceName := "WireGuard Tunnel: " + tunnelName
+ serviceName, err := ServiceNameOfTunnel(tunnelName)
+ if err != nil {
+ return err
+ }
m, err := serviceManager()
if err != nil {
return err
diff --git a/service/names.go b/service/names.go
new file mode 100644
index 00000000..45f590a3
--- /dev/null
+++ b/service/names.go
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
+ */
+
+package service
+
+import (
+ "errors"
+ "golang.zx2c4.com/wireguard/windows/conf"
+)
+
+func ServiceNameOfTunnel(tunnelName string) (string, error) {
+ if !conf.TunnelNameIsValid(tunnelName) {
+ return "", errors.New("Tunnel name is not valid")
+ }
+ return "WireGuard Tunnel: " + tunnelName, nil
+}
+
+func PipePathOfTunnel(tunnelName string) (string, error) {
+ if !conf.TunnelNameIsValid(tunnelName) {
+ return "", errors.New("Tunnel name is not valid")
+ }
+ return "\\\\.\\pipe\\wireguard\\" + tunnelName, nil
+}
diff --git a/service/service_manager.go b/service/service_manager.go
index 1f31521b..9b227592 100644
--- a/service/service_manager.go
+++ b/service/service_manager.go
@@ -266,7 +266,6 @@ loop:
case svc.Interrogate:
changes <- c.CurrentStatus
case svc.SessionChange:
- //TODO: All the logic here depends on https://go-review.googlesource.com/c/sys/+/158698 being merged
if c.EventType != wtsSessionLogon && c.EventType != wtsSessionLogoff {
continue
}
diff --git a/service/tunneltracker.go b/service/tunneltracker.go
index 2545930d..96d0f6e3 100644
--- a/service/tunneltracker.go
+++ b/service/tunneltracker.go
@@ -69,7 +69,10 @@ func trackExistingTunnels() error {
return err
}
for _, name := range names {
- serviceName := "WireGuard Tunnel: " + name
+ serviceName, err := ServiceNameOfTunnel(name)
+ if err != nil {
+ continue
+ }
service, err := m.OpenService(serviceName)
if err != nil {
continue