From fb481e0ff5f14ae7202288bd73b70446b7d3a5ef Mon Sep 17 00:00:00 2001 From: Reginald Gillespie <109245101+Reginald-Gillespie@users.noreply.github.com> Date: Wed, 26 Mar 2025 13:14:10 -0500 Subject: [PATCH 1/3] Updater requests elevation if needed (issue 981) Signed-off-by: Reginald Gillespie <109245101+Reginald-Gillespie@users.noreply.github.com> --- .gitignore | 5 ++++ updater/updater.go | 56 +++++++++++++++++++++++++++++++++++++- updater/updater_default.go | 6 ++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c1926ca22..f0ebb6236 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ bufferflow_tinyg_old.md +/arduino-create-agent* /arduino-cloud-agent* !/arduino-cloud-agent*/ rsrc.syso @@ -19,3 +20,7 @@ logs/ # Python __pycache__ + +# Debugging +__debug_bin*.exe* +vendor/ \ No newline at end of file diff --git a/updater/updater.go b/updater/updater.go index db4e5454f..5e7a60ab1 100644 --- a/updater/updater.go +++ b/updater/updater.go @@ -23,9 +23,13 @@ import ( "io" "net/http" "os" + "os/exec" "path/filepath" "runtime" "strings" + "syscall" + + "golang.org/x/sys/windows" log "github.com/sirupsen/logrus" ) @@ -83,9 +87,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" } @@ -110,3 +116,51 @@ 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 + if runtime.GOOS == "windows" { + err = elevateWindows() + } else { + err = elevateUnix() + } + + if err != nil { + log.Println("Failed to request elevation:", err) + return + } +} + +func elevateWindows() 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) +} + +func elevateUnix() 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() +} diff --git a/updater/updater_default.go b/updater/updater_default.go index 2cf01b8ad..c603ea1d5 100644 --- a/updater/updater_default.go +++ b/updater/updater_default.go @@ -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) } @@ -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 "" From a5fb2d2bfed58a8820ddbadaf644ee5b5fbc72f8 Mon Sep 17 00:00:00 2001 From: Reginald Gillespie <109245101+Reginald-Gillespie@users.noreply.github.com> Date: Wed, 26 Mar 2025 13:35:49 -0500 Subject: [PATCH 2/3] Fix build on non-windows devices Signed-off-by: Reginald Gillespie <109245101+Reginald-Gillespie@users.noreply.github.com> --- updater/elevate_unix.go | 17 +++++++++++++++ updater/elevate_windows.go | 32 +++++++++++++++++++++++++++ updater/updater.go | 44 ++------------------------------------ 3 files changed, 51 insertions(+), 42 deletions(-) create mode 100644 updater/elevate_unix.go create mode 100644 updater/elevate_windows.go diff --git a/updater/elevate_unix.go b/updater/elevate_unix.go new file mode 100644 index 000000000..d5edfd992 --- /dev/null +++ b/updater/elevate_unix.go @@ -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() +} \ No newline at end of file diff --git a/updater/elevate_windows.go b/updater/elevate_windows.go new file mode 100644 index 000000000..4ce78cf81 --- /dev/null +++ b/updater/elevate_windows.go @@ -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) +} \ No newline at end of file diff --git a/updater/updater.go b/updater/updater.go index 5e7a60ab1..891ba4380 100644 --- a/updater/updater.go +++ b/updater/updater.go @@ -23,13 +23,9 @@ import ( "io" "net/http" "os" - "os/exec" "path/filepath" "runtime" "strings" - "syscall" - - "golang.org/x/sys/windows" log "github.com/sirupsen/logrus" ) @@ -120,47 +116,11 @@ func copyExe(from, to string) error { // 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 - if runtime.GOOS == "windows" { - err = elevateWindows() - } else { - err = elevateUnix() - } + + var err error = elevate() if err != nil { log.Println("Failed to request elevation:", err) return } } - -func elevateWindows() 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) -} - -func elevateUnix() 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() -} From fbab5eba17817b962ac8ca1e7eaa3355405b940f Mon Sep 17 00:00:00 2001 From: Reginald Gillespie <109245101+Reginald-Gillespie@users.noreply.github.com> Date: Wed, 26 Mar 2025 13:38:25 -0500 Subject: [PATCH 3/3] Updater formatting Signed-off-by: Reginald Gillespie <109245101+Reginald-Gillespie@users.noreply.github.com> --- updater/elevate_unix.go | 2 +- updater/elevate_windows.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/updater/elevate_unix.go b/updater/elevate_unix.go index d5edfd992..17e819505 100644 --- a/updater/elevate_unix.go +++ b/updater/elevate_unix.go @@ -14,4 +14,4 @@ func elevate() error { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() -} \ No newline at end of file +} diff --git a/updater/elevate_windows.go b/updater/elevate_windows.go index 4ce78cf81..ab3c34936 100644 --- a/updater/elevate_windows.go +++ b/updater/elevate_windows.go @@ -29,4 +29,4 @@ func elevate() error { argPtr, _ := syscall.UTF16PtrFromString(args) var showCmd int32 = 1 return windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd) -} \ No newline at end of file +}