1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package tunservice
import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
)
// pkexec's exit statuses for the prompt (pkexec(1)).
const (
pkexecDismissed = 126
pkexecNotAuthorized = 127
)
// runElevated runs this executable with args as root through pkexec,
// whose polkit prompt asks for the permission, and waits for it. polkit's
// prompt names the program, so prompt (macOS') is not used.
func runElevated(_ string, args ...string) error {
self, err := os.Executable()
if err != nil {
return err
}
pkexec, err := exec.LookPath("pkexec")
if err != nil {
return errors.New("asking for the administrator permission needs pkexec (polkit), which is not found")
}
report, remove, err := reportFile()
if err != nil {
return err
}
defer remove()
out, err := exec.Command(pkexec, append(append([]string{self}, args...), "-report", report)...).CombinedOutput()
var exit *exec.ExitError
if !errors.As(err, &exit) {
return err
}
switch exit.ExitCode() {
case pkexecDismissed:
return ErrCancelled
case pkexecNotAuthorized:
if text := strings.TrimSpace(string(out)); text != "" {
return fmt.Errorf("the administrator permission was refused: %s", text)
}
return errors.New("the administrator permission was refused")
}
if text := readReport(report); text != "" {
return errors.New(text)
}
return fmt.Errorf("%s failed with exit code %d", filepath.Base(self), exit.ExitCode())
}