From 6f66c7697d3bb6a259bf8d0261490cdee0ef8986 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 16 Sep 2019 23:36:49 -0600 Subject: global: use SECURITY_DESCRIPTOR apis from x/sys/windows Signed-off-by: Jason A. Donenfeld --- tunnel/firewall/helpers.go | 36 ++++++++++++++------- tunnel/firewall/rules.go | 3 +- tunnel/firewall/syscall_windows.go | 3 -- tunnel/firewall/types_windows.go | 44 -------------------------- tunnel/firewall/zsyscall_windows.go | 10 ------ tunnel/ipcpermissions.go | 62 +++++++++++++++++++++---------------- tunnel/winipcfg/winipcfg_test.go | 3 +- 7 files changed, 62 insertions(+), 99 deletions(-) (limited to 'tunnel') diff --git a/tunnel/firewall/helpers.go b/tunnel/firewall/helpers.go index abb2684c..04e5c664 100644 --- a/tunnel/firewall/helpers.go +++ b/tunnel/firewall/helpers.go @@ -71,8 +71,9 @@ func wrapErr(err error) error { return fmt.Errorf("Firewall error at %s:%d: %v", file, line, err) } -func getCurrentProcessSecurityDescriptor() (*wtFwpByteBlob, error) { - processToken, err := windows.OpenCurrentProcessToken() +func getCurrentProcessSecurityDescriptor() (*windows.SECURITY_DESCRIPTOR, error) { + var processToken windows.Token + err := windows.OpenProcessToken(windows.GetCurrentProcess(), windows.TOKEN_QUERY, &processToken) if err != nil { return nil, wrapErr(err) } @@ -99,21 +100,32 @@ func getCurrentProcessSecurityDescriptor() (*wtFwpByteBlob, error) { return nil, wrapErr(windows.ERROR_NO_SUCH_GROUP) } - access := &wtExplicitAccess{ - accessPermissions: cFWP_ACTRL_MATCH_FILTER, - accessMode: cGRANT_ACCESS, - trustee: wtTrustee{ - trusteeForm: cTRUSTEE_IS_SID, - trusteeType: cTRUSTEE_IS_GROUP, - sid: sid, + access := []windows.EXPLICIT_ACCESS{{ + AccessPermissions: cFWP_ACTRL_MATCH_FILTER, + AccessMode: windows.GRANT_ACCESS, + Trustee: windows.TRUSTEE{ + TrusteeForm: windows.TRUSTEE_IS_SID, + TrusteeType: windows.TRUSTEE_IS_GROUP, + TrusteeValue: windows.TrusteeValueFromSID(sid), }, + }} + dacl, err := windows.ACLFromEntries(access, nil) + if err != nil { + return nil, wrapErr(err) + } + sd, err := windows.NewSecurityDescriptor() + if err != nil { + return nil, wrapErr(err) + } + err = sd.SetDACL(dacl, true, false) + if err != nil { + return nil, wrapErr(err) } - blob := &wtFwpByteBlob{} - err = buildSecurityDescriptor(nil, nil, 1, access, 0, nil, nil, &blob.size, &blob.data) + sd, err = sd.ToSelfRelative() if err != nil { return nil, wrapErr(err) } - return blob, nil + return sd, nil } func getCurrentProcessAppID() (*wtFwpByteBlob, error) { diff --git a/tunnel/firewall/rules.go b/tunnel/firewall/rules.go index 0ef64692..7bca508b 100644 --- a/tunnel/firewall/rules.go +++ b/tunnel/firewall/rules.go @@ -154,14 +154,13 @@ func permitWireGuardService(session uintptr, baseObjects *baseObjects, weight ui if err != nil { return wrapErr(err) } - defer windows.LocalFree(windows.Handle(unsafe.Pointer(sd.data))) conditions[1] = wtFwpmFilterCondition0{ fieldKey: cFWPM_CONDITION_ALE_USER_ID, matchType: cFWP_MATCH_EQUAL, conditionValue: wtFwpConditionValue0{ _type: cFWP_SECURITY_DESCRIPTOR_TYPE, - value: uintptr(unsafe.Pointer(sd)), + value: uintptr(unsafe.Pointer(&wtFwpByteBlob{sd.Length(), (*byte)(unsafe.Pointer(sd))})), }, } diff --git a/tunnel/firewall/syscall_windows.go b/tunnel/firewall/syscall_windows.go index ac705b41..1d2696a1 100644 --- a/tunnel/firewall/syscall_windows.go +++ b/tunnel/firewall/syscall_windows.go @@ -34,6 +34,3 @@ package firewall // https://docs.microsoft.com/en-us/windows/desktop/api/fwpmu/nf-fwpmu-fwpmprovideradd0 //sys fwpmProviderAdd0(engineHandle uintptr, provider *wtFwpmProvider0, sd uintptr) (err error) [failretval!=0] = fwpuclnt.FwpmProviderAdd0 - -// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildsecuritydescriptorw -//sys buildSecurityDescriptor(owner *wtTrustee, group *wtTrustee, countAccessEntries uint32, accessEntries *wtExplicitAccess, countAuditEntries uint32, auditEntries *wtExplicitAccess, oldSd **byte, sizeNewSd *uint32, newSd **byte) (ret error) = advapi32.BuildSecurityDescriptorW diff --git a/tunnel/firewall/types_windows.go b/tunnel/firewall/types_windows.go index fd313993..d61c6480 100644 --- a/tunnel/firewall/types_windows.go +++ b/tunnel/firewall/types_windows.go @@ -405,50 +405,6 @@ const ( cIPPROTO_UDP wtIPProto = 17 ) -type wtExplicitAccess struct { - accessPermissions uint32 - accessMode uint32 - inheritance uint32 - trustee wtTrustee -} - -type wtTrustee struct { - multipleTrustee *wtTrustee - multipleTrusteeOperation uint32 - trusteeForm uint32 - trusteeType uint32 - sid *windows.SID -} - -const ( - cTRUSTEE_IS_UNKNOWN = iota - cTRUSTEE_IS_USER - cTRUSTEE_IS_GROUP - cTRUSTEE_IS_DOMAIN - cTRUSTEE_IS_ALIAS - cTRUSTEE_IS_WELL_KNOWN_GROUP - cTRUSTEE_IS_DELETED - cTRUSTEE_IS_INVALID - cTRUSTEE_IS_COMPUTER -) -const ( - cTRUSTEE_IS_SID = iota - cTRUSTEE_IS_NAME - cTRUSTEE_BAD_FORM - cTRUSTEE_IS_OBJECTS_AND_SID - cTRUSTEE_IS_OBJECTS_AND_NAME -) - -const ( - cNOT_USED_ACCESS = iota - cGRANT_ACCESS - cSET_ACCESS - cDENY_ACCESS - cREVOKE_ACCESS - cSET_AUDIT_SUCCESS - cSET_AUDIT_FAILURE -) - const ( cFWP_ACTRL_MATCH_FILTER = 1 ) diff --git a/tunnel/firewall/zsyscall_windows.go b/tunnel/firewall/zsyscall_windows.go index 8e83d6e3..846d4ae8 100644 --- a/tunnel/firewall/zsyscall_windows.go +++ b/tunnel/firewall/zsyscall_windows.go @@ -38,7 +38,6 @@ func errnoErr(e syscall.Errno) error { var ( modfwpuclnt = windows.NewLazySystemDLL("fwpuclnt.dll") - modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") procFwpmEngineOpen0 = modfwpuclnt.NewProc("FwpmEngineOpen0") procFwpmEngineClose0 = modfwpuclnt.NewProc("FwpmEngineClose0") @@ -50,7 +49,6 @@ var ( procFwpmTransactionCommit0 = modfwpuclnt.NewProc("FwpmTransactionCommit0") procFwpmTransactionAbort0 = modfwpuclnt.NewProc("FwpmTransactionAbort0") procFwpmProviderAdd0 = modfwpuclnt.NewProc("FwpmProviderAdd0") - procBuildSecurityDescriptorW = modadvapi32.NewProc("BuildSecurityDescriptorW") ) func fwpmEngineOpen0(serverName *uint16, authnService wtRpcCAuthN, authIdentity *uintptr, session *wtFwpmSession0, engineHandle unsafe.Pointer) (err error) { @@ -165,11 +163,3 @@ func fwpmProviderAdd0(engineHandle uintptr, provider *wtFwpmProvider0, sd uintpt } return } - -func buildSecurityDescriptor(owner *wtTrustee, group *wtTrustee, countAccessEntries uint32, accessEntries *wtExplicitAccess, countAuditEntries uint32, auditEntries *wtExplicitAccess, oldSd **byte, sizeNewSd *uint32, newSd **byte) (ret error) { - r0, _, _ := syscall.Syscall9(procBuildSecurityDescriptorW.Addr(), 9, uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSd)), uintptr(unsafe.Pointer(sizeNewSd)), uintptr(unsafe.Pointer(newSd))) - if r0 != 0 { - ret = syscall.Errno(r0) - } - return -} diff --git a/tunnel/ipcpermissions.go b/tunnel/ipcpermissions.go index 20af4257..613d0283 100644 --- a/tunnel/ipcpermissions.go +++ b/tunnel/ipcpermissions.go @@ -6,10 +6,8 @@ package tunnel import ( - "fmt" - "unsafe" - "golang.org/x/sys/windows" + "golang.zx2c4.com/wireguard/ipc" "golang.zx2c4.com/wireguard/windows/conf" @@ -19,37 +17,47 @@ func CopyConfigOwnerToIPCSecurityDescriptor(filename string) error { if conf.PathIsEncrypted(filename) { return nil } - handle, err := windows.CreateFile(windows.StringToUTF16Ptr(filename), windows.STANDARD_RIGHTS_READ, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE, nil, windows.OPEN_EXISTING, 0, 0) + + fileSd, err := windows.GetNamedSecurityInfo(filename, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION) if err != nil { return err } - defer windows.CloseHandle(handle) - var sid *windows.SID - var sd windows.Handle - //TODO: Move into x/sys/windows - const SE_FILE_OBJECT = 1 - const OWNER_SECURITY_INFORMATION = 1 - r, _, _ := windows.NewLazySystemDLL("advapi32.dll").NewProc("GetSecurityInfo").Call( - uintptr(handle), - SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION, - uintptr(unsafe.Pointer(&sid)), - 0, - 0, - 0, - uintptr(unsafe.Pointer(&sd)), - ) - if r != uintptr(windows.ERROR_SUCCESS) { - return windows.Errno(r) - } - defer windows.LocalFree(sd) - if sid.IsWellKnown(windows.WinLocalSystemSid) { + fileOwner, _, err := fileSd.Owner() + if err != nil { + return err + } + if fileOwner.IsWellKnown(windows.WinLocalSystemSid) { return nil } - sidString, err := sid.String() + additionalEntries := []windows.EXPLICIT_ACCESS{{ + AccessPermissions: windows.GENERIC_ALL, + AccessMode: windows.GRANT_ACCESS, + Trustee: windows.TRUSTEE{ + TrusteeForm: windows.TRUSTEE_IS_SID, + TrusteeType: windows.TRUSTEE_IS_USER, + TrusteeValue: windows.TrusteeValueFromSID(fileOwner), + }, + }} + + sd, err := ipc.UAPISecurityDescriptor.ToAbsolute() + if err != nil { + return err + } + dacl, defaulted, _ := sd.DACL() + + newDacl, err := windows.ACLFromEntries(additionalEntries, dacl) + if err != nil { + return err + } + err = sd.SetDACL(newDacl, true, defaulted) if err != nil { return err } - ipc.UAPISecurityDescriptor += fmt.Sprintf("(A;;GA;;;%s)", sidString) + sd, err = sd.ToSelfRelative() + if err != nil { + return err + } + ipc.UAPISecurityDescriptor = sd + return nil } diff --git a/tunnel/winipcfg/winipcfg_test.go b/tunnel/winipcfg/winipcfg_test.go index 36ef2849..2b0c5ff5 100644 --- a/tunnel/winipcfg/winipcfg_test.go +++ b/tunnel/winipcfg/winipcfg_test.go @@ -56,7 +56,8 @@ var ( ) func runningElevated() bool { - process, err := windows.OpenCurrentProcessToken() + var process windows.Token + err := windows.OpenProcessToken(windows.GetCurrentProcess(), windows.TOKEN_QUERY, &process) if err != nil { return false } -- cgit v1.2.3-59-g8ed1b