diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-04-05 00:28:47 -0600 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-04-05 00:39:49 -0600 |
commit | 34e3a000c561fd2c8ef65bdb5a296f0b03095a99 (patch) | |
tree | 92557d70ea2433808636e9aafed27bcd5c12bcc2 /elevate | |
parent | syntax: insist on 256-bit keys, not 257-bit or 258-bit (diff) | |
download | wireguard-windows-34e3a000c561fd2c8ef65bdb5a296f0b03095a99.tar.xz wireguard-windows-34e3a000c561fd2c8ef65bdb5a296f0b03095a99.zip |
updater: allow updating from the command line
The administrator user may run `wireguard.exe /update`, which will check
for updates and install it if available. A log file may be written using
`wireguard.exe /update path\to\log\file.txt`.
Requested-by: Elliot Saba <staticfloat@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'elevate')
-rw-r--r-- | elevate/doas.go | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/elevate/doas.go b/elevate/doas.go index ceedb78b..8322a5c9 100644 --- a/elevate/doas.go +++ b/elevate/doas.go @@ -7,6 +7,7 @@ package elevate import ( "errors" + "os" "runtime" "strings" "unsafe" @@ -15,6 +16,17 @@ import ( "golang.org/x/sys/windows/svc/mgr" ) +func setAllEnv(env []string) { + windows.Clearenv() + for _, e := range env { + kv := strings.SplitN(e, "=", 2) + if len(kv) != 2 { + continue + } + windows.Setenv(kv[0], kv[1]) + } +} + func DoAsSystem(f func() error) error { runtime.LockOSThread() defer func() { @@ -58,12 +70,14 @@ func DoAsSystem(f func() error) error { return err } processEntry := windows.ProcessEntry32{Size: uint32(unsafe.Sizeof(windows.ProcessEntry32{}))} + var impersonationError error for err = windows.Process32First(processes, &processEntry); err == nil; err = windows.Process32Next(processes, &processEntry) { if strings.ToLower(windows.UTF16ToString(processEntry.ExeFile[:])) != "winlogon.exe" { continue } winlogonProcess, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, false, processEntry.ProcessID) if err != nil { + impersonationError = err continue } var winlogonToken windows.Token @@ -85,14 +99,26 @@ func DoAsSystem(f func() error) error { if err != nil { return err } + newEnv, err := duplicatedToken.Environ(false) + if err != nil { + duplicatedToken.Close() + return err + } + currentEnv := os.Environ() err = windows.SetThreadToken(nil, duplicatedToken) duplicatedToken.Close() if err != nil { return err } - return f() + setAllEnv(newEnv) + err = f() + setAllEnv(currentEnv) + return err } windows.CloseHandle(processes) + if impersonationError != nil { + return impersonationError + } return errors.New("unable to find winlogon.exe process") } @@ -131,11 +157,20 @@ func DoAsService(serviceName string, f func() error) error { if err != nil { return err } + newEnv, err := duplicatedToken.Environ(false) + if err != nil { + duplicatedToken.Close() + return err + } + currentEnv := os.Environ() err = windows.SetThreadToken(nil, duplicatedToken) duplicatedToken.Close() if err != nil { return err } - return f() + setAllEnv(newEnv) + err = f() + setAllEnv(currentEnv) + return err }) } |