From 558e9d335a287a0ef985544cd583c0722d943c35 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 28 Aug 2019 08:22:03 -0600 Subject: manager: fix nits in adapter cleanup logic and also handle ‘%s’ uniformly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manager/adaptercleanup.go | 63 +++++++++++++++++++++++++++++++++++++++++++ manager/adapters.go | 69 ----------------------------------------------- manager/ipc_server.go | 3 +++ manager/service.go | 4 +-- 4 files changed, 68 insertions(+), 71 deletions(-) create mode 100644 manager/adaptercleanup.go delete mode 100644 manager/adapters.go (limited to 'manager') diff --git a/manager/adaptercleanup.go b/manager/adaptercleanup.go new file mode 100644 index 00000000..779e4b80 --- /dev/null +++ b/manager/adaptercleanup.go @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + */ + +package manager + +import ( + "log" + "strings" + + "golang.org/x/sys/windows" + "golang.org/x/sys/windows/svc" + "golang.org/x/sys/windows/svc/mgr" + + "golang.zx2c4.com/wireguard/tun/wintun" + "golang.zx2c4.com/wireguard/windows/services" +) + +const unnamedWintunInterface = "Local Area Connection" + +func cleanupStaleAdapters() { + defer printPanic() + + m, err := mgr.Connect() + if err != nil { + return + } + defer m.Disconnect() + + wintun.DeleteMatchingInterfaces(func(wintun *wintun.Wintun) bool { + interfaceName, err := wintun.InterfaceName() + if err != nil { + log.Printf("Removing Wintun interface %s because determining interface name failed: %v", wintun.GUID().String(), err) + return true + } + if strings.HasPrefix(interfaceName, unnamedWintunInterface) { + return false + } + serviceName, err := services.ServiceNameOfTunnel(interfaceName) + if err != nil { + log.Printf("Removing Wintun interface ‘%s’ because determining tunnel service name failed: %v", interfaceName, err) + return true + } + service, err := m.OpenService(serviceName) + if err == windows.ERROR_SERVICE_DOES_NOT_EXIST { + log.Printf("Removing Wintun interface ‘%s’ because no service for it exists", interfaceName) + return true + } else if err != nil { + return false + } + defer service.Close() + status, err := service.Query() + if err != nil { + return false + } + if status.State == svc.Stopped { + log.Printf("Removing Wintun interface ‘%s’ because its service is stopped", interfaceName) + return true + } + return false + }) +} diff --git a/manager/adapters.go b/manager/adapters.go deleted file mode 100644 index 5ac16465..00000000 --- a/manager/adapters.go +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package manager - -import ( - "log" - - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/svc" - "golang.org/x/sys/windows/svc/mgr" - - "golang.zx2c4.com/wireguard/tun/wintun" - "golang.zx2c4.com/wireguard/windows/services" -) - -func cleanStaleAdapters() { - defer printPanic() - - m, err := mgr.Connect() - if err != nil { - log.Printf("Error connecting to Service Control Manager: %v", err) - return - } - defer m.Disconnect() - - wintun.DeleteMatchingInterfaces(func(wintun *wintun.Wintun) bool { - interfaceName, err := wintun.InterfaceName() - if err != nil { - log.Printf("Removing Wintun interface %s because determining interface name failed: %v", wintun.GUID().String(), err) - return true - } - serviceName, err := services.ServiceNameOfTunnel(interfaceName) - if err != nil { - log.Printf("Removing Wintun interface %s because determining tunnel service name failed: %v", interfaceName, err) - return true - } - service, err := m.OpenService(serviceName) - if err == windows.ERROR_SERVICE_DOES_NOT_EXIST { - log.Printf("Removing orphaned Wintun interface %s", interfaceName) - return true - } - if err != nil { - log.Printf("Error opening service %s: %v", serviceName, err) - return false - } - defer service.Close() - config, err := service.Config() - if err != nil { - log.Printf("Error getting service %s configuration: %v", serviceName, err) - return false - } - if config.StartType == mgr.StartAutomatic { - return false - } - status, err := service.Query() - if err != nil { - log.Printf("Error getting service %s status: %v", serviceName, err) - return false - } - if status.State == svc.Stopped { - log.Printf("Removing unused Wintun interface %s", interfaceName) - return true - } - return false - }) -} diff --git a/manager/ipc_server.go b/manager/ipc_server.go index 7691adb8..ed60d6b6 100644 --- a/manager/ipc_server.go +++ b/manager/ipc_server.go @@ -107,6 +107,7 @@ func (s *ManagerService) Start(tunnelName string, unused *uintptr) error { } } }() + go cleanupStaleAdapters() // After that process is started -- it's somewhat asynchronous -- we install the new one. c, err := conf.LoadFromName(tunnelName) @@ -121,6 +122,8 @@ func (s *ManagerService) Start(tunnelName string, unused *uintptr) error { } func (s *ManagerService) Stop(tunnelName string, _ *uintptr) error { + go cleanupStaleAdapters() + err := UninstallTunnel(tunnelName) if err == windows.ERROR_SERVICE_DOES_NOT_EXIST { _, notExistsError := conf.LoadFromName(tunnelName) diff --git a/manager/service.go b/manager/service.go index 7ab3db16..8a525b12 100644 --- a/manager/service.go +++ b/manager/service.go @@ -182,7 +182,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest return } - log.Printf("Starting UI process for user '%s@%s' for session %d", username, domain, session) + log.Printf("Starting UI process for user ‘%s@%s’ for session %d", username, domain, session) attr := &os.ProcAttr{ Sys: &syscall.SysProcAttr{ Token: syscall.Token(elevatedToken), @@ -247,7 +247,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest }() } - go cleanStaleAdapters() + go cleanupStaleAdapters() go checkForUpdates() var sessionsPointer *windows.WTS_SESSION_INFO -- cgit v1.2.3-59-g8ed1b