diff --git a/backend/networking/ping.go b/backend/networking/ping.go index 769c122e..1313b865 100644 --- a/backend/networking/ping.go +++ b/backend/networking/ping.go @@ -1,18 +1,30 @@ package networking import ( - "fmt" "net" "os" "os/exec" "runtime" "strconv" + "syscall" "time" "github.com/pocketbase/pocketbase/core" probing "github.com/prometheus-community/pro-bing" ) +func isNoRouteOrDownError(err error) bool { + opErr, ok := err.(*net.OpError) + if !ok { + return false + } + syscallErr, ok := opErr.Err.(*os.SyscallError) + if !ok { + return false + } + return syscallErr.Err == syscall.EHOSTUNREACH || syscallErr.Err == syscall.EHOSTDOWN +} + func PingDevice(device *core.Record) (bool, error) { ping_cmd := device.GetString("ping_cmd") if ping_cmd == "" { @@ -22,21 +34,26 @@ func PingDevice(device *core.Record) (bool, error) { } pinger.Count = 1 pinger.Timeout = 500 * time.Millisecond - privileged, err := strconv.ParseBool(os.Getenv("UPSNAP_PING_PRIVILEGED")) - if err != nil { - privileged = true + + privileged := isRoot() + privilegedEnv := os.Getenv("UPSNAP_PING_PRIVILEGED") + if privilegedEnv != "" { + privileged, err = strconv.ParseBool(privilegedEnv) + if err != nil { + privileged = false + } } pinger.SetPrivileged(privileged) + err = pinger.Run() if err != nil { + if isNoRouteOrDownError(err) { + return false, nil + } return false, err } stats := pinger.Statistics() - if stats.PacketLoss > 0 { - return false, fmt.Errorf("packet loss is > 0: %v", stats.PacketLoss) - } else { - return true, nil - } + return stats.PacketLoss == 0, nil } else { var shell string var shell_arg string diff --git a/backend/networking/root.go b/backend/networking/root.go new file mode 100644 index 00000000..0cf0691f --- /dev/null +++ b/backend/networking/root.go @@ -0,0 +1,9 @@ +//go:build !windows + +package networking + +import "os" + +func isRoot() bool { + return os.Geteuid() == 0 +} diff --git a/backend/networking/root_windows.go b/backend/networking/root_windows.go new file mode 100644 index 00000000..2f62d0b0 --- /dev/null +++ b/backend/networking/root_windows.go @@ -0,0 +1,16 @@ +//go:build windows + +package networking + +import "golang.org/x/sys/windows" + +func isRoot() bool { + var sid *windows.SID + sid, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid) + if err != nil { + return false + } + token := windows.GetCurrentProcessToken() + isAdmin, err := token.IsMember(sid) + return err == nil && isAdmin +}