aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/service
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-13 09:01:49 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-13 13:28:00 +0200
commitcdb3701c95cbe6379288c486231e71e42dca0601 (patch)
tree710f0442ce9e89bc7832c9db56bfa8cdef00bb64 /service
parentui: lock runtime thread as early as possible (diff)
downloadwireguard-windows-cdb3701c95cbe6379288c486231e71e42dca0601.tar.xz
wireguard-windows-cdb3701c95cbe6379288c486231e71e42dca0601.zip
service: allow go to create correct environment block
Diffstat (limited to 'service')
-rw-r--r--service/ipc_server.go13
-rw-r--r--service/securityapi.go29
-rw-r--r--service/service_manager.go18
-rw-r--r--service/zsyscall_windows.go33
4 files changed, 10 insertions, 83 deletions
diff --git a/service/ipc_server.go b/service/ipc_server.go
index becad3ee..12e01ce2 100644
--- a/service/ipc_server.go
+++ b/service/ipc_server.go
@@ -29,14 +29,9 @@ var managerServicesLock sync.RWMutex
var haveQuit uint32
var quitManagersChan = make(chan struct{}, 1)
-type UserTokenInfo struct {
- elevatedToken windows.Token
- elevatedEnvironment []string
-}
-
type ManagerService struct {
events *os.File
- userTokenInfo *UserTokenInfo
+ elevatedToken windows.Token
}
func (s *ManagerService) StoredConfig(tunnelName string, config *conf.Config) error {
@@ -258,7 +253,7 @@ func (s *ManagerService) UpdateState(_ uintptr, state *UpdateState) error {
}
func (s *ManagerService) Update(_ uintptr, _ *uintptr) error {
- progress := updater.DownloadVerifyAndExecute(uintptr(s.userTokenInfo.elevatedToken), s.userTokenInfo.elevatedEnvironment)
+ progress := updater.DownloadVerifyAndExecute(uintptr(s.elevatedToken))
go func() {
for {
dp := <-progress
@@ -271,10 +266,10 @@ func (s *ManagerService) Update(_ uintptr, _ *uintptr) error {
return nil
}
-func IPCServerListen(reader *os.File, writer *os.File, events *os.File, userTokenInfo *UserTokenInfo) error {
+func IPCServerListen(reader *os.File, writer *os.File, events *os.File, elevatedToken windows.Token) error {
service := &ManagerService{
events: events,
- userTokenInfo: userTokenInfo,
+ elevatedToken: elevatedToken,
}
server := rpc.NewServer()
diff --git a/service/securityapi.go b/service/securityapi.go
index 37713b32..d89d9404 100644
--- a/service/securityapi.go
+++ b/service/securityapi.go
@@ -9,7 +9,6 @@ import (
"errors"
"golang.org/x/sys/windows"
"runtime"
- "unicode/utf16"
"unsafe"
)
@@ -53,34 +52,6 @@ const (
SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010
)
-//sys createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
-//sys destroyEnvironmentBlock(block uintptr) (err error) = userenv.DestroyEnvironmentBlock
-
-func userEnviron(token windows.Token) (env []string, err error) {
- var block uintptr
- err = createEnvironmentBlock(&block, token, false)
- if err != nil {
- return
- }
- offset := uintptr(0)
- for {
- entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(block + offset))[:]
- for i, v := range entry {
- if v == 0 {
- entry = entry[:i]
- break
- }
- }
- if len(entry) == 0 {
- break
- }
- env = append(env, string(utf16.Decode(entry)))
- offset += 2 * (uintptr(len(entry)) + 1)
- }
- destroyEnvironmentBlock(block)
- return
-}
-
func tokenIsElevated(token windows.Token) bool {
var isElevated uint32
var outLen uint32
diff --git a/service/service_manager.go b/service/service_manager.go
index c61bd517..92508215 100644
--- a/service/service_manager.go
+++ b/service/service_manager.go
@@ -110,22 +110,17 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
userToken.Close()
return
}
- userTokenInfo := &UserTokenInfo{}
- userTokenInfo.elevatedToken, err = getElevatedToken(userToken)
+ //TODO: The environment that Go gets from CreateEnvironmentBlock seems to have the same PATH as the userToken. Aren't there attacks?
+ elevatedToken, err := getElevatedToken(userToken)
if err != nil {
log.Printf("Unable to elevate token: %v", err)
return
}
- if userTokenInfo.elevatedToken != userToken {
+ if elevatedToken != userToken {
userToken.Close()
}
- defer userTokenInfo.elevatedToken.Close()
+ defer elevatedToken.Close()
userToken = 0
- userTokenInfo.elevatedEnvironment, err = userEnviron(userTokenInfo.elevatedToken) //TODO: This seems to have the same PATH as the userToken. Aren't there attacks?
- if err != nil {
- log.Printf("Unable to determine elevated environment: %v", err)
- return
- }
first := true
for {
if stoppingManager {
@@ -155,7 +150,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
return
}
ourEvents, theirEvents, theirEventStr, err := inheritableEvents()
- err = IPCServerListen(ourReader, ourWriter, ourEvents, userTokenInfo)
+ err = IPCServerListen(ourReader, ourWriter, ourEvents, elevatedToken)
if err != nil {
log.Printf("Unable to listen on IPC pipes: %v", err)
return
@@ -169,10 +164,9 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
log.Printf("Starting UI process for user '%s@%s' for session %d", username, domain, session)
attr := &os.ProcAttr{
Sys: &syscall.SysProcAttr{
- Token: syscall.Token(userTokenInfo.elevatedToken),
+ Token: syscall.Token(elevatedToken),
},
Files: []*os.File{devNull, devNull, devNull},
- Env: userTokenInfo.elevatedEnvironment,
}
procsLock.Lock()
var proc *os.Process
diff --git a/service/zsyscall_windows.go b/service/zsyscall_windows.go
index 20f9753b..bb8d89d4 100644
--- a/service/zsyscall_windows.go
+++ b/service/zsyscall_windows.go
@@ -38,15 +38,12 @@ func errnoErr(e syscall.Errno) error {
var (
modwtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
- moduserenv = windows.NewLazySystemDLL("userenv.dll")
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken")
procWTSEnumerateSessionsW = modwtsapi32.NewProc("WTSEnumerateSessionsW")
procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory")
- procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
- procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
procNotifyServiceStatusChangeW = modadvapi32.NewProc("NotifyServiceStatusChangeW")
procSleepEx = modkernel32.NewProc("SleepEx")
)
@@ -80,36 +77,6 @@ func wtsFreeMemory(ptr uintptr) {
return
}
-func createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) {
- var _p0 uint32
- if inheritExisting {
- _p0 = 1
- } else {
- _p0 = 0
- }
- r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0))
- if r1 == 0 {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func destroyEnvironmentBlock(block uintptr) (err error) {
- r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(block), 0, 0)
- if r1 == 0 {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
func notifyServiceStatusChange(service windows.Handle, notifyMask uint32, notifyBuffer uintptr) (status uint32) {
r0, _, _ := syscall.Syscall(procNotifyServiceStatusChangeW.Addr(), 3, uintptr(service), uintptr(notifyMask), uintptr(notifyBuffer))
status = uint32(r0)