Compare commits
2
Commits
0ee10a64c1
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
373359116c | ||
|
|
1cb2296480 |
Binary file not shown.
@@ -47,8 +47,17 @@ func main() {
|
|||||||
Repo: envOrDefault("GITEA_REPO", defaultRepo),
|
Repo: envOrDefault("GITEA_REPO", defaultRepo),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := platformEnsureElevated(); err != nil {
|
||||||
|
printError(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
args := os.Args[1:]
|
args := os.Args[1:]
|
||||||
|
|
||||||
|
if len(args) > 0 && args[0] == "--elevated" {
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
runTUI(config)
|
runTUI(config)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ func getInstallDir() (string, error) {
|
|||||||
return "/opt/logofclient", nil
|
return "/opt/logofclient", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func platformEnsureElevated() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func platformRunPrivileged(config Config, action string) error {
|
func platformRunPrivileged(config Config, action string) error {
|
||||||
// Bereits als root gestartet.
|
// Bereits als root gestartet.
|
||||||
if os.Geteuid() == 0 {
|
if os.Geteuid() == 0 {
|
||||||
|
|||||||
+98
-107
@@ -7,7 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@@ -20,18 +19,17 @@ var (
|
|||||||
openProcessToken = advapi32.NewProc("OpenProcessToken")
|
openProcessToken = advapi32.NewProc("OpenProcessToken")
|
||||||
getTokenInformation = advapi32.NewProc("GetTokenInformation")
|
getTokenInformation = advapi32.NewProc("GetTokenInformation")
|
||||||
|
|
||||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
closeHandle = kernel32.NewProc("CloseHandle")
|
closeHandle = kernel32.NewProc("CloseHandle")
|
||||||
waitForSingleObject = kernel32.NewProc("WaitForSingleObject")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tokenQuery = 0x0008
|
tokenQuery = 0x0008
|
||||||
tokenElevationClass = 20
|
tokenElevationClass = 20
|
||||||
seeMaskNoCloseProcess = 0x00000040
|
|
||||||
swShow = 1
|
errorCancelled = 1223
|
||||||
infinite = 0xFFFFFFFF
|
|
||||||
errorCancelled = 1223
|
swShow = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
type shellExecuteInfo struct {
|
type shellExecuteInfo struct {
|
||||||
@@ -56,46 +54,94 @@ type tokenElevationData struct {
|
|||||||
TokenIsElevated uint32
|
TokenIsElevated uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func getInstallDir() (string, error) {
|
func platformEnsureElevated() error {
|
||||||
programFiles := os.Getenv("ProgramFiles")
|
// Die erhöhte Instanz wurde bereits gestartet.
|
||||||
|
// Sie darf sich nicht noch einmal selbst per runas starten.
|
||||||
if programFiles == "" {
|
if hasElevatedFlag() {
|
||||||
return "", errors.New("ProgramFiles ist nicht gesetzt")
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Join(programFiles, "logofclient"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func platformRunPrivileged(config Config, action string) error {
|
|
||||||
if isWindowsElevated() {
|
|
||||||
return runAction(config, action)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("Für diese Aktion werden Administratorrechte benötigt.")
|
|
||||||
fmt.Print("Jetzt Administratorrechte anfordern? [J/n]: ")
|
|
||||||
|
|
||||||
var answer string
|
|
||||||
if _, err := fmt.Scanln(&answer); err != nil {
|
|
||||||
// Enter ohne Eingabe = Ja
|
|
||||||
answer = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
answer = strings.ToLower(strings.TrimSpace(answer))
|
|
||||||
|
|
||||||
if answer != "" && answer != "j" && answer != "ja" {
|
|
||||||
fmt.Println("Abgebrochen.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return runElevated(action)
|
if isWindowsElevated() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return restartElevated()
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasElevatedFlag() bool {
|
||||||
|
for _, arg := range os.Args[1:] {
|
||||||
|
if arg == "--elevated" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func restartElevated() error {
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Pfad des Installers konnte nicht ermittelt werden: %w",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
verb, err := syscall.UTF16PtrFromString("runas")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := syscall.UTF16PtrFromString(exe)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Die erhöhte Instanz bekommt nur das interne Flag.
|
||||||
|
parameters, err := syscall.UTF16PtrFromString("--elevated")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
info := shellExecuteInfo{
|
||||||
|
cbSize: uint32(unsafe.Sizeof(shellExecuteInfo{})),
|
||||||
|
lpVerb: verb,
|
||||||
|
lpFile: file,
|
||||||
|
lpParameters: parameters,
|
||||||
|
nShow: swShow,
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, _, callErr := shellExecuteExW.Call(
|
||||||
|
uintptr(unsafe.Pointer(&info)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if ret == 0 {
|
||||||
|
if errno, ok := callErr.(syscall.Errno); ok &&
|
||||||
|
errno == errorCancelled {
|
||||||
|
fmt.Println("Administratorrechte wurden nicht erteilt.")
|
||||||
|
return errors.New("Administratorrechte erforderlich")
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Administratorrechte konnten nicht angefordert werden: %w",
|
||||||
|
callErr,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WICHTIG:
|
||||||
|
// Die ursprüngliche Instanz beendet sich sofort.
|
||||||
|
// Nur die erhöhte Instanz führt danach main() weiter aus.
|
||||||
|
os.Exit(0)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func isWindowsElevated() bool {
|
func isWindowsElevated() bool {
|
||||||
var token uintptr
|
var token uintptr
|
||||||
|
|
||||||
|
// GetCurrentProcess() = -1
|
||||||
ret, _, _ := openProcessToken.Call(
|
ret, _, _ := openProcessToken.Call(
|
||||||
uintptr(^uint(0)>>1),
|
uintptr(^uint(0)),
|
||||||
tokenQuery,
|
tokenQuery,
|
||||||
uintptr(unsafe.Pointer(&token)),
|
uintptr(unsafe.Pointer(&token)),
|
||||||
)
|
)
|
||||||
@@ -124,72 +170,17 @@ func isWindowsElevated() bool {
|
|||||||
return elevation.TokenIsElevated != 0
|
return elevation.TokenIsElevated != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func runElevated(action string) error {
|
func platformRunPrivileged(config Config, action string) error {
|
||||||
exe, err := os.Executable()
|
// Die komplette Windows-Anwendung läuft bereits erhöht.
|
||||||
if err != nil {
|
return runAction(config, action)
|
||||||
return fmt.Errorf(
|
}
|
||||||
"Pfad des Installers konnte nicht ermittelt werden: %w",
|
|
||||||
err,
|
func getInstallDir() (string, error) {
|
||||||
)
|
programFiles := os.Getenv("ProgramFiles")
|
||||||
|
|
||||||
|
if programFiles == "" {
|
||||||
|
return "", errors.New("ProgramFiles ist nicht gesetzt")
|
||||||
}
|
}
|
||||||
|
|
||||||
verb, err := syscall.UTF16PtrFromString("runas")
|
return filepath.Join(programFiles, "logofclient"), nil
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := syscall.UTF16PtrFromString(exe)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
parameters, err := syscall.UTF16PtrFromString(action)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
info := shellExecuteInfo{
|
|
||||||
cbSize: uint32(unsafe.Sizeof(shellExecuteInfo{})),
|
|
||||||
fMask: seeMaskNoCloseProcess,
|
|
||||||
lpVerb: verb,
|
|
||||||
lpFile: file,
|
|
||||||
lpParameters: parameters,
|
|
||||||
nShow: swShow,
|
|
||||||
}
|
|
||||||
|
|
||||||
ret, _, callErr := shellExecuteExW.Call(
|
|
||||||
uintptr(unsafe.Pointer(&info)),
|
|
||||||
)
|
|
||||||
|
|
||||||
if ret == 0 {
|
|
||||||
if errno, ok := callErr.(syscall.Errno); ok &&
|
|
||||||
errno == errorCancelled {
|
|
||||||
fmt.Println("Administratorrechte wurden nicht erteilt.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf(
|
|
||||||
"Administratorrechte konnten nicht angefordert werden: %w",
|
|
||||||
callErr,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.hProcess != 0 {
|
|
||||||
handle := syscall.Handle(info.hProcess)
|
|
||||||
defer syscall.CloseHandle(handle)
|
|
||||||
|
|
||||||
ret, _, err := waitForSingleObject.Call(
|
|
||||||
uintptr(handle),
|
|
||||||
infinite,
|
|
||||||
)
|
|
||||||
|
|
||||||
if ret == 0xFFFFFFFF {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"auf erhöhte Instanz konnte nicht gewartet werden: %w",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user