From 56d79a60679ba3783dcb5dd1ebe69436c5e5af7c Mon Sep 17 00:00:00 2001
From: Ruben Pollan <meskio@sindominio.net>
Date: Wed, 12 Jun 2019 19:04:51 +0200
Subject: [PATCH] [feat] check if polkit is running and launch it if possible

- Resolves: #141
---
 pkg/standalone/launcher.go       |  4 ++
 pkg/standalone/launcher_linux.go | 78 ++++++++++++++++++++++++++++++++
 pkg/standalone/vpn.go            |  3 +-
 pkg/systray/run.go               |  1 +
 4 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/pkg/standalone/launcher.go b/pkg/standalone/launcher.go
index 4dc47616..16ea8b0d 100644
--- a/pkg/standalone/launcher.go
+++ b/pkg/standalone/launcher.go
@@ -40,6 +40,10 @@ func (l *launcher) close() error {
 	return nil
 }
 
+func (l *launcher) check() (helpers bool, priviledge bool, err error) {
+	return true, true, nil
+}
+
 func (l *launcher) openvpnStart(flags ...string) error {
 	byteFlags, err := json.Marshal(flags)
 	if err != nil {
diff --git a/pkg/standalone/launcher_linux.go b/pkg/standalone/launcher_linux.go
index 1bbf4d14..e678de45 100644
--- a/pkg/standalone/launcher_linux.go
+++ b/pkg/standalone/launcher_linux.go
@@ -21,8 +21,10 @@ import (
 	"log"
 	"os"
 	"os/exec"
+	"strings"
 
 	"0xacab.org/leap/bitmask-vpn/pkg/config"
+	"github.com/mitchellh/go-ps"
 )
 
 const (
@@ -50,6 +52,82 @@ func (l *launcher) close() error {
 	return nil
 }
 
+func (l *launcher) check() (helpers bool, priviledge bool, err error) {
+
+	isRunning, err := isPolkitRunning()
+	if err != nil {
+		return
+	}
+	if !isRunning {
+		polkitPath := getPolkitPath()
+		if polkitPath == "" {
+			return true, false, nil
+		}
+		cmd := exec.Command("setsid", polkitPath)
+		err = cmd.Start()
+		if err != nil {
+			return
+		}
+		isRunning, err = isPolkitRunning()
+		return true, isRunning, err
+	}
+
+	return true, true, nil
+}
+
+func isPolkitRunning() (bool, error) {
+	var polkitProcNames = [...]string{
+		"polkit-gnome-authentication-agent-1",
+		"polkit-kde-authentication-agent-1",
+		"polkit-mate-authentication-agent-1",
+		"lxpolkit",
+		"lxsession",
+		"gnome-shell",
+		"gnome-flashback",
+		"fingerprint-polkit-agent",
+		"xfce-polkit",
+	}
+
+	processes, err := ps.Processes()
+	if err != nil {
+		return false, err
+	}
+
+	for _, proc := range processes {
+		executable := proc.Executable()
+		for _, name := range polkitProcNames {
+			if strings.Contains(executable, name) {
+				return true, nil
+			}
+		}
+	}
+	return false, nil
+}
+
+func getPolkitPath() string {
+	var polkitPaths = [...]string{
+		"/usr/bin/lxpolkit",
+		"/usr/bin/lxqt-policykit-agent",
+		"/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1",
+		"/usr/lib/x86_64-linux-gnu/polkit-mate/polkit-mate-authentication-agent-1",
+		"/usr/lib/mate-polkit/polkit-mate-authentication-agent-1",
+		"/usr/lib/x86_64-linux-gnu/libexec/polkit-kde-authentication-agent-1",
+		"/usr/lib/kde4/libexec/polkit-kde-authentication-agent-1",
+		// now we get weird
+		"/usr/libexec/policykit-1-pantheon/pantheon-agent-polkit",
+		"/usr/lib/polkit-1-dde/dde-polkit-agent",
+		// do you know some we"re still missing? :)
+	}
+
+	for _, polkit := range polkitPaths {
+		_, err := os.Stat(polkit)
+		if err == nil {
+			return polkit
+		}
+	}
+	return ""
+}
+
 func (l *launcher) openvpnStart(flags ...string) error {
 	log.Println("openvpn start: ", flags)
 	arg := []string{"openvpn", "start", getOpenvpnPath()}
diff --git a/pkg/standalone/vpn.go b/pkg/standalone/vpn.go
index 941d4445..b858ee0e 100644
--- a/pkg/standalone/vpn.go
+++ b/pkg/standalone/vpn.go
@@ -124,8 +124,7 @@ func (b *Bitmask) InstallHelpers() error {
 
 // VPNCheck returns if the helpers are installed and up to date and if polkit is running
 func (b *Bitmask) VPNCheck() (helpers bool, priviledge bool, err error) {
-	// TODO
-	return true, true, nil
+	return b.launch.check()
 }
 
 // ListGateways return the names of the gateways
diff --git a/pkg/systray/run.go b/pkg/systray/run.go
index 172b9e85..d9d39dea 100644
--- a/pkg/systray/run.go
+++ b/pkg/systray/run.go
@@ -82,6 +82,7 @@ func checkAndInstallHelpers(b bitmask.Bitmask, notify *notificator) error {
 	if (err != nil && err.Error() == "nopolkit") || (err == nil && !priviledge) {
 		log.Printf("No polkit found")
 		notify.authAgent()
+		os.Exit(1)
 	} else if err != nil {
 		log.Printf("Error checking vpn: %v", err)
 		notify.errorStartingVPN(err)
-- 
GitLab