aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/service
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-02 16:26:20 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-02 16:34:37 +0200
commit0c141ea9ef2bf5719e1f6999270d96268fc58934 (patch)
tree1f80ab3763e7f6698f5a53ec500c4ad27b7e2a7f /service
parentservice: correct sid bounds (diff)
downloadwireguard-windows-0c141ea9ef2bf5719e1f6999270d96268fc58934.tar.xz
wireguard-windows-0c141ea9ef2bf5719e1f6999270d96268fc58934.zip
service: set security attributes on new process
Diffstat (limited to '')
-rw-r--r--service/errors.go3
-rw-r--r--service/service_manager.go30
-rw-r--r--service/zsyscall_windows.go36
3 files changed, 60 insertions, 9 deletions
diff --git a/service/errors.go b/service/errors.go
index d3f02f54..e456818b 100644
--- a/service/errors.go
+++ b/service/errors.go
@@ -26,6 +26,7 @@ const (
ErrorSetNetConfig
ErrorDetermineExecutablePath
ErrorFindAdministratorsSID
+ ErrorCreateSecurityDescriptor
ErrorOpenNULFile
ErrorTrackTunnels
ErrorEnumerateSessions
@@ -58,6 +59,8 @@ func (e Error) Error() string {
return "Unable to set interface addresses, routes, dns, and/or adapter settings"
case ErrorFindAdministratorsSID:
return "Unable to find Administrators SID"
+ case ErrorCreateSecurityDescriptor:
+ return "Unable to determine security descriptor"
case ErrorOpenNULFile:
return "Unable to open NUL file"
case ErrorTrackTunnels:
diff --git a/service/service_manager.go b/service/service_manager.go
index 4d287c6f..9596671b 100644
--- a/service/service_manager.go
+++ b/service/service_manager.go
@@ -56,6 +56,15 @@ type wellKnownSidType uint32
//sys wtsEnumerateSessions(handle windows.Handle, reserved uint32, version uint32, sessions **wtsSessionInfo, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
//sys wtsFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory
+const (
+ SE_KERNEL_OBJECT = 6
+ DACL_SECURITY_INFORMATION = 4
+ ATTRIBUTE_SECURITY_INFORMATION = 16
+)
+
+//sys getSecurityInfo(handle windows.Handle, objectType uint32, si uint32, sidOwner *windows.SID, sidGroup *windows.SID, dacl *uintptr, sacl *uintptr, securityDescriptor *uintptr) (err error) [failretval!=0] = advapi32.GetSecurityInfo
+//sys getSecurityDescriptorLength(securityDescriptor uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
+
//sys createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
//sys destroyEnvironmentBlock(block uintptr) (err error) = userenv.DestroyEnvironmentBlock
@@ -125,6 +134,23 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
return
}
+ currentProcess, err := windows.GetCurrentProcess()
+ if err != nil {
+ panic(err)
+ }
+ var securityAttributes syscall.SecurityAttributes
+ err = getSecurityInfo(currentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, nil, nil, &securityAttributes.SecurityDescriptor)
+ if err != nil {
+ serviceError = ErrorCreateSecurityDescriptor
+ return
+ }
+ defer windows.LocalFree(windows.Handle(securityAttributes.SecurityDescriptor))
+ securityAttributes.Length = getSecurityDescriptorLength(securityAttributes.SecurityDescriptor)
+ if securityAttributes.Length == 0 {
+ serviceError = ErrorCreateSecurityDescriptor
+ return
+ }
+
devNull, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
if err != nil {
serviceError = ErrorOpenNULFile
@@ -216,7 +242,9 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
log.Printf("Starting UI process for user: '%s@%s'", username, domain)
attr := &os.ProcAttr{
Sys: &syscall.SysProcAttr{
- Token: syscall.Token(userToken),
+ Token: syscall.Token(userToken),
+ ProcessAttributes: &securityAttributes,
+ ThreadAttributes: &securityAttributes,
},
Files: []*os.File{devNull, devNull, devNull},
Env: env,
diff --git a/service/zsyscall_windows.go b/service/zsyscall_windows.go
index 40bac8ff..caa7c91d 100644
--- a/service/zsyscall_windows.go
+++ b/service/zsyscall_windows.go
@@ -38,17 +38,19 @@ func errnoErr(e syscall.Errno) error {
var (
modwtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
- moduserenv = windows.NewLazySystemDLL("userenv.dll")
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
+ moduserenv = windows.NewLazySystemDLL("userenv.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")
+ procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken")
+ procWTSEnumerateSessionsW = modwtsapi32.NewProc("WTSEnumerateSessionsW")
+ procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory")
+ procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo")
+ procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
+ procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
+ procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
+ procNotifyServiceStatusChangeW = modadvapi32.NewProc("NotifyServiceStatusChangeW")
+ procSleepEx = modkernel32.NewProc("SleepEx")
)
func wtfQueryUserToken(session uint32, token *windows.Token) (err error) {
@@ -80,6 +82,24 @@ func wtsFreeMemory(ptr uintptr) {
return
}
+func getSecurityInfo(handle windows.Handle, objectType uint32, si uint32, sidOwner *windows.SID, sidGroup *windows.SID, dacl *uintptr, sacl *uintptr, securityDescriptor *uintptr) (err error) {
+ r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(sidOwner)), uintptr(unsafe.Pointer(sidGroup)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(securityDescriptor)), 0)
+ if r1 != 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func getSecurityDescriptorLength(securityDescriptor uintptr) (len uint32) {
+ r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(securityDescriptor), 0, 0)
+ len = uint32(r0)
+ return
+}
+
func createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) {
var _p0 uint32
if inheritExisting {