Scert/backend/internal/admin/code_protection_windows.go

101 lines
2.8 KiB
Go

//go:build windows
package admin
import (
"fmt"
"runtime"
"golang.org/x/sys/windows"
)
func protectCodeFile(path string) error {
currentSID, err := currentProcessUserSID()
if err != nil {
return err
}
systemSID, err := windows.CreateWellKnownSid(windows.WinLocalSystemSid)
if err != nil {
return fmt.Errorf("创建系统账户安全标识失败:%w", err)
}
adminSID, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
if err != nil {
return fmt.Errorf("创建本地管理员组安全标识失败:%w", err)
}
var pinner runtime.Pinner
pinner.Pin(currentSID)
pinner.Pin(systemSID)
pinner.Pin(adminSID)
defer pinner.Unpin()
readDelete := windows.ACCESS_MASK(windows.FILE_GENERIC_READ | windows.DELETE | windows.READ_CONTROL | windows.SYNCHRONIZE)
fullControl := windows.ACCESS_MASK(windows.FILE_GENERIC_READ |
windows.FILE_GENERIC_WRITE |
windows.FILE_GENERIC_EXECUTE |
windows.DELETE |
windows.READ_CONTROL |
windows.WRITE_DAC |
windows.WRITE_OWNER |
windows.SYNCHRONIZE)
entries := []windows.EXPLICIT_ACCESS{
{
AccessPermissions: readDelete,
AccessMode: windows.SET_ACCESS,
Inheritance: windows.NO_INHERITANCE,
Trustee: windows.TRUSTEE{
TrusteeForm: windows.TRUSTEE_IS_SID,
TrusteeType: windows.TRUSTEE_IS_USER,
TrusteeValue: windows.TrusteeValueFromSID(currentSID),
},
},
{
AccessPermissions: fullControl,
AccessMode: windows.SET_ACCESS,
Inheritance: windows.NO_INHERITANCE,
Trustee: windows.TRUSTEE{
TrusteeForm: windows.TRUSTEE_IS_SID,
TrusteeType: windows.TRUSTEE_IS_WELL_KNOWN_GROUP,
TrusteeValue: windows.TrusteeValueFromSID(systemSID),
},
},
{
AccessPermissions: fullControl,
AccessMode: windows.SET_ACCESS,
Inheritance: windows.NO_INHERITANCE,
Trustee: windows.TRUSTEE{
TrusteeForm: windows.TRUSTEE_IS_SID,
TrusteeType: windows.TRUSTEE_IS_ALIAS,
TrusteeValue: windows.TrusteeValueFromSID(adminSID),
},
},
}
acl, err := windows.ACLFromEntries(entries, nil)
if err != nil {
return fmt.Errorf("创建校验码文件访问控制列表失败:%w", err)
}
if err := windows.SetNamedSecurityInfo(
path,
windows.SE_FILE_OBJECT,
windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION,
nil,
nil,
acl,
nil,
); err != nil {
return fmt.Errorf("应用校验码文件访问控制列表失败:%w", err)
}
return nil
}
func currentProcessUserSID() (*windows.SID, error) {
user, err := windows.GetCurrentProcessToken().GetTokenUser()
if err != nil {
return nil, fmt.Errorf("读取当前服务账户安全标识失败:%w", err)
}
if user == nil || user.User.Sid == nil {
return nil, fmt.Errorf("当前服务账户没有有效的安全标识")
}
return user.User.Sid, nil
}