Skip to content

Updater requests elevation if needed (issue 981) #1026

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

bufferflow_tinyg_old.md

/arduino-create-agent*
/arduino-cloud-agent*
!/arduino-cloud-agent*/
rsrc.syso
Expand All @@ -19,3 +20,7 @@ logs/

# Python
__pycache__

# Debugging
__debug_bin*.exe*
vendor/
17 changes: 17 additions & 0 deletions updater/elevate_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//go:build !windows

package updater

import (
"os"
"os/exec"
)

func elevate() error {
args := append([]string{os.Args[0]}, os.Args[1:]...)
cmd := exec.Command("sudo", args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
32 changes: 32 additions & 0 deletions updater/elevate_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package updater

import (
"os"
"strings"
"syscall"

"golang.org/x/sys/windows"
)

func elevate() error {
verb := "runas"
exe, _ := os.Executable()
cwd, _ := os.Getwd()
args := strings.Join(os.Args[1:], " ")

verbPtr, err := syscall.UTF16PtrFromString(verb)
if err != nil {
return err
}
exePtr, err := syscall.UTF16PtrFromString(exe)
if err != nil {
return err
}
cwdPtr, err := syscall.UTF16PtrFromString(cwd)
if err != nil {
return err
}
argPtr, _ := syscall.UTF16PtrFromString(args)
var showCmd int32 = 1
return windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd)
}
16 changes: 15 additions & 1 deletion updater/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,11 @@ func fetch(url string) (io.ReadCloser, error) {

// addTempSuffixToPath adds the "-temp" suffix to the path to an executable file (a ".exe" extension is replaced with "-temp.exe")
func addTempSuffixToPath(path string) string {
if filepath.Ext(path) == "exe" {
if filepath.Ext(path) == ".exe" {
// Windows
path = strings.Replace(path, ".exe", "-temp.exe", -1)
} else {
// Unix
path = path + "-temp"
}

Expand All @@ -110,3 +112,15 @@ func copyExe(from, to string) error {
}
return nil
}

// requestElevation requests this program to rerun as administrator, for when we don't have permission over the update files
func requestElevation() {
log.Println("Permission denied. Requesting elevated privileges...")

var err error = elevate()

if err != nil {
log.Println("Failed to request elevation:", err)
return
}
}
6 changes: 6 additions & 0 deletions updater/updater_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ func start(src string) string {
if strings.Contains(src, "-temp") {
newPath := removeTempSuffixFromPath(src)
if err := copyExe(src, newPath); err != nil {
if os.IsPermission(err) {
requestElevation()
}
log.Println("Copy error: ", err)
panic(err)
}
Expand All @@ -74,6 +77,9 @@ func start(src string) string {

// Otherwise copy to a path with -temp suffix
if err := copyExe(src, addTempSuffixToPath(src)); err != nil {
if os.IsPermission(err) {
requestElevation()
}
panic(err)
}
return ""
Expand Down
Loading