aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/service
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-14 17:00:10 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-14 17:10:50 +0200
commitbfdb3aa855de75d91c5d191ef116c651feb0fcfc (patch)
treea3050b6130f1eef70baccfe7305a7a7884c4e153 /service
parentservice: drop all privileges for tunnel service (diff)
downloadwireguard-windows-bfdb3aa855de75d91c5d191ef116c651feb0fcfc.tar.xz
wireguard-windows-bfdb3aa855de75d91c5d191ef116c651feb0fcfc.zip
service: clean up token mangling
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'service')
-rw-r--r--service/securityapi.go62
-rw-r--r--service/service_manager.go2
-rw-r--r--service/service_tunnel.go14
-rw-r--r--service/zsyscall_windows.go32
4 files changed, 21 insertions, 89 deletions
diff --git a/service/securityapi.go b/service/securityapi.go
index 989b4ac3..a7e6072c 100644
--- a/service/securityapi.go
+++ b/service/securityapi.go
@@ -55,40 +55,6 @@ type WTS_SESSION_INFO struct {
//sys wtsEnumerateSessions(handle windows.Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
//sys wtsFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory
-// TEMP //
-
-type LUID struct {
- LowPart uint32
- HighPart int32
-}
-
-type LUID_AND_ATTRIBUTES struct {
- Luid LUID
- Attributes uint32
-}
-
-type TOKEN_PRIVILEGES struct {
- PrivilegeCount uint32
- Privileges [1]LUID_AND_ATTRIBUTES
-}
-
-const (
- SE_PRIVILEGE_REMOVED uint32 = 0X00000004
- TOKEN_READ uint32 = 0x00020008
- TOKEN_WRITE uint32 = 0x000200e0
- TokenPrivileges uint32 = 3
-)
-
-//sys adjustTokenPrivileges(token windows.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
-//sys openProcessToken(processHandle windows.Handle, accessFlags uint32, token *windows.Token) (err error) = advapi32.OpenProcessToken
-
-// END TEMP //
-
-const (
- SE_GROUP_ENABLED = 0x00000004
- SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010
-)
-
func tokenIsElevated(token windows.Token) bool {
var isElevated uint32
var outLen uint32
@@ -116,7 +82,7 @@ func getElevatedToken(token windows.Token) (windows.Token, error) {
return windows.Token(0), errors.New("the linked token is not elevated")
}
-func tokenIsMemberOfBuiltInAdministrator(token windows.Token) bool {
+func TokenIsMemberOfBuiltInAdministrator(token windows.Token) bool {
adminSid, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
if err != nil {
return false
@@ -128,7 +94,7 @@ func tokenIsMemberOfBuiltInAdministrator(token windows.Token) bool {
groups := (*[(1 << 28) - 1]windows.SIDAndAttributes)(unsafe.Pointer(&gs.Groups[0]))[:gs.GroupCount]
isAdmin := false
for _, g := range groups {
- if (g.Attributes&SE_GROUP_USE_FOR_DENY_ONLY != 0 || g.Attributes&SE_GROUP_ENABLED != 0) && windows.EqualSid(g.Sid, adminSid) {
+ if (g.Attributes&windows.SE_GROUP_USE_FOR_DENY_ONLY != 0 || g.Attributes&windows.SE_GROUP_ENABLED != 0) && windows.EqualSid(g.Sid, adminSid) {
isAdmin = true
break
}
@@ -143,33 +109,31 @@ func dropAllPrivileges() error {
return err
}
var processToken windows.Token
- err = openProcessToken(processHandle, TOKEN_READ | TOKEN_WRITE, (*windows.Token)(unsafe.Pointer(&processToken)))
+ err = windows.OpenProcessToken(processHandle, windows.TOKEN_READ|windows.TOKEN_WRITE, &processToken)
if err != nil {
return err
}
defer processToken.Close()
+
var bufferSizeRequired uint32
- _ = windows.GetTokenInformation(processToken, TokenPrivileges, nil, 0, (*uint32)(unsafe.Pointer(&bufferSizeRequired)))
- if bufferSizeRequired == 0 {
+ windows.GetTokenInformation(processToken, windows.TokenPrivileges, nil, 0, &bufferSizeRequired)
+ if bufferSizeRequired == 0 || bufferSizeRequired < uint32(unsafe.Sizeof(windows.Tokenprivileges{}.PrivilegeCount)) {
return errors.New("GetTokenInformation failed to provide a buffer size")
}
- buffer := make([]uint8, bufferSizeRequired)
+ buffer := make([]byte, bufferSizeRequired)
var bytesWritten uint32
- err = windows.GetTokenInformation(processToken, TokenPrivileges, (*uint8)(unsafe.Pointer(&buffer[0])), (uint32)(len(buffer)), (*uint32)(unsafe.Pointer(&bytesWritten)))
+ err = windows.GetTokenInformation(processToken, windows.TokenPrivileges, &buffer[0], uint32(len(buffer)), &bytesWritten)
if err != nil {
return err
}
if bytesWritten != bufferSizeRequired {
return errors.New("GetTokenInformation returned incomplete data")
}
- tokenPrivileges := (*TOKEN_PRIVILEGES)(unsafe.Pointer(&buffer[0]))
- privs := (*[1024]LUID_AND_ATTRIBUTES)(unsafe.Pointer(&buffer[unsafe.Sizeof(tokenPrivileges.PrivilegeCount)]))
+ tokenPrivileges := (*windows.Tokenprivileges)(unsafe.Pointer(&buffer[0]))
for i := uint32(0); i < tokenPrivileges.PrivilegeCount; i++ {
- privs[i].Attributes = SE_PRIVILEGE_REMOVED
- }
- err = adjustTokenPrivileges(processToken, false, tokenPrivileges, 0, nil, nil)
- if err != nil {
- return err
+ (*windows.LUIDAndAttributes)(unsafe.Pointer(uintptr(unsafe.Pointer(&tokenPrivileges.Privileges[0])) + unsafe.Sizeof(tokenPrivileges.Privileges[0])*uintptr(i))).Attributes = windows.SE_PRIVILEGE_REMOVED
}
- return nil
+ err = windows.AdjustTokenPrivileges(processToken, false, tokenPrivileges, 0, nil, nil)
+ runtime.KeepAlive(buffer)
+ return err
}
diff --git a/service/service_manager.go b/service/service_manager.go
index fae8800a..b2d93385 100644
--- a/service/service_manager.go
+++ b/service/service_manager.go
@@ -91,7 +91,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
if err != nil {
return
}
- if !tokenIsMemberOfBuiltInAdministrator(userToken) {
+ if !TokenIsMemberOfBuiltInAdministrator(userToken) {
userToken.Close()
return
}
diff --git a/service/service_tunnel.go b/service/service_tunnel.go
index 0af7c733..3c09ed77 100644
--- a/service/service_tunnel.go
+++ b/service/service_tunnel.go
@@ -150,6 +150,13 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest,
return
}
+ logger.Info.Println("Dropping all privileges")
+ err = dropAllPrivileges()
+ if err != nil {
+ serviceError = ErrorDropPrivileges
+ return
+ }
+
logger.Info.Println("Creating interface instance")
dev = device.NewDevice(wintun, logger)
@@ -194,13 +201,6 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest,
}
}()
- logger.Info.Println("Dropping all privileges")
- err = dropAllPrivileges()
- if err != nil {
- serviceError = ErrorDropPrivileges
- return
- }
-
changes <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop}
logger.Info.Println("Startup complete")
diff --git a/service/zsyscall_windows.go b/service/zsyscall_windows.go
index a269d3a8..cc40ddea 100644
--- a/service/zsyscall_windows.go
+++ b/service/zsyscall_windows.go
@@ -44,8 +44,6 @@ var (
procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken")
procWTSEnumerateSessionsW = modwtsapi32.NewProc("WTSEnumerateSessionsW")
procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory")
- procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
- procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken")
procNotifyServiceStatusChangeW = modadvapi32.NewProc("NotifyServiceStatusChangeW")
procSleepEx = modkernel32.NewProc("SleepEx")
)
@@ -79,36 +77,6 @@ func wtsFreeMemory(ptr uintptr) {
return
}
-func adjustTokenPrivileges(token windows.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (err error) {
- var _p0 uint32
- if disableAllPrivileges {
- _p0 = 1
- } else {
- _p0 = 0
- }
- r1, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen)))
- if r1 == 0 {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
-func openProcessToken(processHandle windows.Handle, accessFlags uint32, token *windows.Token) (err error) {
- r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(processHandle), uintptr(accessFlags), uintptr(unsafe.Pointer(token)))
- if r1 == 0 {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return
-}
-
func notifyServiceStatusChange(service windows.Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) {
r0, _, _ := syscall.Syscall(procNotifyServiceStatusChangeW.Addr(), 3, uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier)))
if r0 != 0 {