aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-11-27 11:57:19 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2020-11-27 13:15:38 +0100
commit2bdcbc5f2be24c494ebaab63f47c71bad79b126c (patch)
treefc4ac2f1bf6ad8c5cecc5977e6d9b1912cbf08c8
parentmain: restrict dll search path (diff)
downloadwireguard-windows-2bdcbc5f2be24c494ebaab63f47c71bad79b126c.tar.xz
wireguard-windows-2bdcbc5f2be24c494ebaab63f47c71bad79b126c.zip
conf: separate out migration and print errors
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--conf/migration.go89
-rw-r--r--conf/store.go76
-rw-r--r--manager/service.go2
3 files changed, 90 insertions, 77 deletions
diff --git a/conf/migration.go b/conf/migration.go
new file mode 100644
index 00000000..4b68763f
--- /dev/null
+++ b/conf/migration.go
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2019-2020 WireGuard LLC. All Rights Reserved.
+ */
+
+package conf
+
+import (
+ "errors"
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/sys/windows"
+)
+
+var migrating sync.Mutex
+var lastMigrationTimer *time.Timer
+
+func MigrateUnencryptedConfigs() { migrateUnencryptedConfigs(3) }
+
+func migrateUnencryptedConfigs(sharingBase int) {
+ migrating.Lock()
+ defer migrating.Unlock()
+ configFileDir, err := tunnelConfigurationsDirectory()
+ if err != nil {
+ return
+ }
+ files, err := ioutil.ReadDir(configFileDir)
+ if err != nil {
+ return
+ }
+ ignoreSharingViolations := false
+ for _, file := range files {
+ path := filepath.Join(configFileDir, file.Name())
+ name := filepath.Base(file.Name())
+ if len(name) <= len(configFileUnencryptedSuffix) || !strings.HasSuffix(name, configFileUnencryptedSuffix) {
+ continue
+ }
+ if !file.Mode().IsRegular() || file.Mode().Perm()&0444 == 0 {
+ continue
+ }
+
+ var bytes []byte
+ var config *Config
+ // We don't use ioutil's ReadFile, because we actually want RDWR, so that we can take advantage
+ // of Windows file locking for ensuring the file is finished being written.
+ f, err := os.OpenFile(path, os.O_RDWR, 0)
+ if err != nil {
+ if errors.Is(err, windows.ERROR_SHARING_VIOLATION) {
+ if ignoreSharingViolations {
+ continue
+ } else if sharingBase > 0 {
+ if lastMigrationTimer != nil {
+ lastMigrationTimer.Stop()
+ }
+ lastMigrationTimer = time.AfterFunc(time.Second/time.Duration(sharingBase*sharingBase), func() { migrateUnencryptedConfigs(sharingBase - 1) })
+ ignoreSharingViolations = true
+ continue
+ }
+ }
+ goto error
+ }
+ bytes, err = ioutil.ReadAll(f)
+ f.Close()
+ if err != nil {
+ goto error
+ }
+ config, err = FromWgQuickWithUnknownEncoding(string(bytes), strings.TrimSuffix(name, configFileUnencryptedSuffix))
+ if err != nil {
+ goto error
+ }
+ err = config.Save(false)
+ if err != nil {
+ goto error
+ }
+ err = os.Remove(path)
+ if err != nil {
+ log.Printf("Unable to remove old path %#q: %v", path, err)
+ }
+ continue
+ error:
+ log.Printf("Unable to ingest and encrypt %#q: %v", path, err)
+ }
+}
diff --git a/conf/store.go b/conf/store.go
index 5cc2ce46..18f99f66 100644
--- a/conf/store.go
+++ b/conf/store.go
@@ -11,10 +11,6 @@ import (
"os"
"path/filepath"
"strings"
- "sync"
- "time"
-
- "golang.org/x/sys/windows"
"golang.zx2c4.com/wireguard/windows/conf/dpapi"
)
@@ -51,78 +47,6 @@ func ListConfigNames() ([]string, error) {
return configs[:i], nil
}
-var migrating sync.Mutex
-var lastMigrationTimer *time.Timer
-
-func MigrateUnencryptedConfigs(sharingBase int) (int, []error) {
- migrating.Lock()
- defer migrating.Unlock()
- configFileDir, err := tunnelConfigurationsDirectory()
- if err != nil {
- return 0, []error{err}
- }
- files, err := ioutil.ReadDir(configFileDir)
- if err != nil {
- return 0, []error{err}
- }
- errs := make([]error, len(files))
- i := 0
- e := 0
- for _, file := range files {
- path := filepath.Join(configFileDir, file.Name())
- name := filepath.Base(file.Name())
- if len(name) <= len(configFileUnencryptedSuffix) || !strings.HasSuffix(name, configFileUnencryptedSuffix) {
- continue
- }
- if !file.Mode().IsRegular() || file.Mode().Perm()&0444 == 0 {
- continue
- }
-
- // We don't use ioutil's ReadFile, because we actually want RDWR, so that we can take advantage
- // of Windows file locking for ensuring the file is finished being written.
- f, err := os.OpenFile(path, os.O_RDWR, 0)
- if err != nil {
- if sharingBase > 0 && errors.Is(err, windows.ERROR_SHARING_VIOLATION) {
- if lastMigrationTimer != nil {
- lastMigrationTimer.Stop()
- }
- lastMigrationTimer = time.AfterFunc(time.Second/time.Duration(sharingBase*sharingBase), func() { MigrateUnencryptedConfigs(sharingBase - 1) })
- sharingBase = 0
- }
- errs[e] = err
- e++
- continue
- }
- bytes, err := ioutil.ReadAll(f)
- f.Close()
- if err != nil {
- errs[e] = err
- e++
- continue
- }
- config, err := FromWgQuickWithUnknownEncoding(string(bytes), strings.TrimSuffix(name, configFileUnencryptedSuffix))
- if err != nil {
- errs[e] = err
- e++
- continue
- }
- err = config.Save(false)
- if err != nil {
- errs[e] = err
- e++
- continue
- }
- err = os.Remove(path)
- if err != nil {
- errs[e] = err
- e++
- continue
- }
- i++
- }
- return i, errs[:e]
-}
-
func LoadFromName(name string) (*Config, error) {
configFileDir, err := tunnelConfigurationsDirectory()
if err != nil {
diff --git a/manager/service.go b/manager/service.go
index 9044d9fb..2afd796f 100644
--- a/manager/service.go
+++ b/manager/service.go
@@ -85,7 +85,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
return
}
- conf.RegisterStoreChangeCallback(func() { conf.MigrateUnencryptedConfigs(3) })
+ conf.RegisterStoreChangeCallback(conf.MigrateUnencryptedConfigs)
conf.RegisterStoreChangeCallback(IPCServerNotifyTunnelsChange)
procs := make(map[uint32]*os.Process)