fix: fix permission on windows

This commit is contained in:
fengcaiwen
2023-01-27 16:06:37 +08:00
parent b387a1d55e
commit 577088460e
8 changed files with 268 additions and 41 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
cmd/.DS_Store vendored Normal file

Binary file not shown.

BIN
cmd/kubevpn/.DS_Store vendored Normal file

Binary file not shown.

BIN
pkg/.DS_Store vendored Normal file

Binary file not shown.

BIN
pkg/util/.DS_Store vendored Normal file

Binary file not shown.

150
pkg/util/a_test.go Executable file
View File

@@ -0,0 +1,150 @@
package util
import (
"context"
"fmt"
"github.com/wencaiwulue/kubevpn/pkg/util/wintoken"
"golang.org/x/sys/windows"
"os"
"os/exec"
"syscall"
"testing"
"unsafe"
)
func TestName112399(t *testing.T) {
verb := "runas"
//exe, _ := os.Executable()
exe := "C:\\Users\\naison\\Desktop\\kubevpn-windows-amd64.exe"
cwd, _ := os.Getwd()
args := /* strings.Join(os.Args[:], " ")*/ ""
verbPtr, _ := windows.UTF16PtrFromString(verb)
exePtr, _ := syscall.UTF16PtrFromString(exe)
cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
argPtr, _ := syscall.UTF16PtrFromString(args)
//https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
var showCmd int32 = 1 //SW_NORMAL
//
var modshell32 = windows.NewLazySystemDLL("shell32.dll")
var procShellExecuteW = modshell32.NewProc("ShellExecuteW")
r1, r2, e1 := syscall.Syscall6(procShellExecuteW.Addr(), 6, uintptr(0), uintptr(unsafe.Pointer(verbPtr)), uintptr(unsafe.Pointer(exePtr)), uintptr(unsafe.Pointer(argPtr)), uintptr(unsafe.Pointer(cwdPtr)), uintptr(showCmd))
if r1 <= 32 {
panic(e1)
}
println(r1)
println(r2)
token, err := wintoken.OpenProcessToken(0, wintoken.TokenPrimary)
if err == nil {
println(token.Token().IsElevated())
} else {
println(err.Error())
}
token, err = wintoken.OpenProcessToken(0, wintoken.TokenPrimary)
if err == nil {
println(token.Token().IsElevated())
} else {
println(err.Error())
}
//err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd)
//if e1 != nil {
// logrus.Warn(e1)
//}
}
func TestName112399Exec(t *testing.T) {
verb := "runas"
//exe, _ := os.Executable()
//cwd, _ := os.Getwd()
//args := /* strings.Join(os.Args[:], " ")*/ ""
//
//verbPtr, _ := windows.UTF16PtrFromString(verb)
//exePtr, _ := syscall.UTF16PtrFromString(exe)
//cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
//argPtr, _ := syscall.UTF16PtrFromString(args)
strings := []string{"/env", "/user:administrator", fmt.Sprintf(`"%s version"`, "C:\\Users\\naison\\Desktop\\kubevpn-windows-amd64.exe")}
cmd := exec.Command(verb, strings...)
cancel, cancelFunc := context.WithCancel(context.Background())
err := cmd.Start()
if err != nil {
panic(err)
}
go func() {
_ = cmd.Wait()
cancelFunc()
}()
var to *windows.Token
for {
select {
case <-cancel.Done():
if to != nil {
print(to.IsElevated())
return
} else {
panic("not found")
}
default:
token, err := wintoken.OpenProcessToken(cmd.Process.Pid, wintoken.TokenPrimary)
if err == nil {
ttt := token.Token()
to = &ttt
}
}
}
}
func TestName112399CreateProcess(t *testing.T) {
//verb := "runas"
//exe, _ := os.Executable()
cwd, _ := os.Getwd()
//args := /* strings.Join(os.Args[:], " ")*/ ""
//
//verbPtr, _ := windows.UTF16PtrFromString(verb)
//exePtr, _ := syscall.UTF16PtrFromString(exe)
cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
//argPtr, _ := syscall.UTF16PtrFromString(args)
windows.Setenv("KUBECONFIG", os.Getenv("KUBECONFIG"))
v, _ := syscall.UTF16PtrFromString("KUBECONFIG=" + os.Getenv("KUBECONFIG"))
// func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
var si windows.StartupInfo
var pi windows.ProcessInformation
a, _ := syscall.UTF16PtrFromString("runas")
//c, _ := syscall.UTF16PtrFromString("C:\\Users\\naison\\Desktop\\kubevpn-windows-amd64.exe")
//strings := []string{"/env", "/user:administrator", fmt.Sprintf(`"%s version"`, "C:\\Users\\naison\\Desktop\\kubevpn-windows-amd64.exe")}
cancel, cancelFunc := context.WithCancel(context.Background())
go func() {
err2 := windows.CreateProcess(nil, a, nil, nil, true, windows.NORMAL_PRIORITY_CLASS, v, cwdPtr, &si, &pi)
if err2 != nil {
panic(err2)
}
cancelFunc()
}()
var to *windows.Token
for {
select {
case <-cancel.Done():
if to != nil {
print(to.IsElevated())
//print(to.IsMember())
return
} else {
panic("not found")
}
default:
if pi.ProcessId != 0 {
token, err := wintoken.OpenProcessToken(int(pi.ProcessId), wintoken.TokenPrimary)
if err == nil {
ttt := token.Token()
to = &ttt
}
}
}
}
}

View File

@@ -4,9 +4,11 @@
package util
import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/wencaiwulue/kubevpn/pkg/util/wintoken"
"golang.org/x/sys/windows"
"os"
"os/exec"
"os/signal"
@@ -23,22 +25,23 @@ func RunWithElevated() {
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Env = append(os.Environ(), "KUBECONFIG="+os.Getenv("KUBECONFIG"))
//token, err := wintoken.GetInteractiveToken(wintoken.TokenLinked)
//token, err := wintoken.OpenProcessToken(1234, wintoken.TokenPrimary)
//if err != nil {
// panic(err)
//}
token, err := wintoken.OpenProcessToken(0, wintoken.TokenPrimary)
if err != nil {
panic(err)
}
err = token.EnableAllPrivileges()
if err != nil {
panic(err)
inner := RunWithElevatedInner()
if inner == 0 {
panic(inner)
}
//err = token.EnableAllPrivileges()
//if err != nil {
// panic(err)
//}
defer token.Close()
//defer token.Close()
cmd.SysProcAttr = &syscall.SysProcAttr{
Token: syscall.Token(token.Token()),
Token: syscall.Token(inner),
}
// while send single CTRL+C, command will quit immediately, but output will cut off and print util quit final
// so, mute single CTRL+C, let inner command handle single only
@@ -47,42 +50,62 @@ func RunWithElevated() {
signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGKILL)
<-signals
}()
err = cmd.Run()
err := cmd.Run()
if err != nil {
log.Warn(err)
}
}
//func RunWithElevated() {
// verb := "runas"
// //exe, _ := os.Executable()
// cwd, _ := os.Getwd()
// args := strings.Join(os.Args[:], " ")
//
// //verbPtr, _ := windows.UTF16PtrFromString(verb)
// //exePtr, _ := syscall.UTF16PtrFromString(exe)
// cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
// argPtr, _ := syscall.UTF16PtrFromString(args)
//
// // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
// //var showCmd int32 = 1 //SW_NORMAL
// //process := windows.CurrentProcess()
// //process := windows.GetDesktopWindow()
// //windows.Setenv("KUBECONFIG", os.Getenv("KUBECONFIG"))
// v, _ := syscall.UTF16PtrFromString("KUBECONFIG=" + os.Getenv("KUBECONFIG"))
//
// var si windows.StartupInfo
// var pi windows.ProcessInformation
////windows.TokenElevation
// // CreateProcess(NULL,"cleanmgr",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); //调用系统的清理磁盘程序
// err := windows.CreateProcessAsUser(nil,nil, argPtr, nil, nil, true, windows.NORMAL_PRIORITY_CLASS, v, cwdPtr, &si, &pi)
// //r1, _, e1 := syscall.Syscall6(procShellExecuteW.Addr(), 6, uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd))
// //r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
// //err := windows.ShellExecute(windows.Handle(process), verbPtr, exePtr, argPtr, cwdPtr, showCmd)
// if err != nil {
// logrus.Warn(err)
// }
//}
func RunWithElevatedInner() windows.Token {
verb := "runas"
exe, _ := os.Executable()
//cwd, _ := os.Getwd()
//args := /* strings.Join(os.Args[:], " ")*/ ""
//verbPtr, _ := windows.UTF16PtrFromString(verb)
//exePtr, _ := syscall.UTF16PtrFromString(exe)
//cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
//argPtr, _ := syscall.UTF16PtrFromString(args)
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
//var showCmd int32 = 1 //SW_NORMAL
//process := windows.CurrentProcess()
//process := windows.GetDesktopWindow()
//windows.Setenv("KUBECONFIG", os.Getenv("KUBECONFIG"))
//v, _ := syscall.UTF16PtrFromString("KUBECONFIG=" + os.Getenv("KUBECONFIG"))
//err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd)
//if err != nil {
// logrus.Warn(err)
//}
// runas /env /user:administrator "kubevpn-windows-amd64.exe"
strings := []string{"/env", "/user:administrator", fmt.Sprintf(`"%s version"`, exe)}
cmd := exec.Command(verb, strings...)
cancel, cancelFunc := context.WithCancel(context.Background())
err := cmd.Start()
if err != nil {
panic(err)
}
go func() {
_ = cmd.Wait()
cancelFunc()
}()
var tt *windows.Token
for {
select {
case <-cancel.Done():
if tt != nil {
return *tt
}
return 0
default:
token, err := wintoken.OpenProcessToken(cmd.Process.Pid, wintoken.TokenPrimary)
if err == nil {
ttt := token.Token()
tt = &ttt
}
}
}
}
func IsAdmin() bool {
_, err := os.Open("\\\\.\\PHYSICALDRIVE0")

54
pkg/util/wintoken/get.go Executable file
View File

@@ -0,0 +1,54 @@
package wintoken
import (
"golang.org/x/sys/windows"
"syscall"
"unsafe"
)
func GetIntegrityLevelToken(wns string) (windows.Token, error) {
var procToken syscall.Token
var token windows.Token
proc, err := syscall.GetCurrentProcess()
if err != nil {
return 0, err
}
defer syscall.CloseHandle(proc)
err = syscall.OpenProcessToken(proc,
syscall.TOKEN_DUPLICATE|
syscall.TOKEN_ADJUST_DEFAULT|
syscall.TOKEN_QUERY|
syscall.TOKEN_ASSIGN_PRIMARY,
&procToken)
if err != nil {
return 0, err
}
defer procToken.Close()
sid, err := syscall.StringToSid(wns)
if err != nil {
return 0, err
}
tml := &windows.Tokenmandatorylabel{}
tml.Label.Attributes = windows.SE_GROUP_INTEGRITY
tml.Label.Sid = (*windows.SID)(sid)
err = windows.DuplicateTokenEx(windows.Token(procToken), 0, nil, windows.SecurityImpersonation,
windows.TokenPrimary, &token)
if err != nil {
return 0, err
}
err = windows.SetTokenInformation(token,
syscall.TokenIntegrityLevel,
(*byte)(unsafe.Pointer(tml)),
tml.Size())
if err != nil {
token.Close()
return 0, err
}
return token, nil
}