diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-05-02 16:26:20 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-05-02 16:34:37 +0200 |
commit | 0c141ea9ef2bf5719e1f6999270d96268fc58934 (patch) | |
tree | 1f80ab3763e7f6698f5a53ec500c4ad27b7e2a7f /service | |
parent | service: correct sid bounds (diff) | |
download | wireguard-windows-0c141ea9ef2bf5719e1f6999270d96268fc58934.tar.xz wireguard-windows-0c141ea9ef2bf5719e1f6999270d96268fc58934.zip |
service: set security attributes on new process
Diffstat (limited to '')
-rw-r--r-- | service/errors.go | 3 | ||||
-rw-r--r-- | service/service_manager.go | 30 | ||||
-rw-r--r-- | service/zsyscall_windows.go | 36 |
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 { |