From 20266b063c1be8818d4582bff7b59486551ee447 Mon Sep 17 00:00:00 2001 From: "kali kaneko (leap communications)" Date: Wed, 17 Jun 2020 21:14:35 +0200 Subject: [feat] pass initialization errors to gui --- gui/backend.go | 1 - gui/main.cpp | 2 +- gui/qml/main.qml | 22 +++++++++----- pkg/backend/bitmask.go | 67 ------------------------------------------ pkg/backend/callbacks.go | 2 +- pkg/backend/donate.go | 9 ++++++ pkg/backend/init.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++ pkg/backend/status.go | 1 + pkg/bitmask/init.go | 39 +++++++------------------ pkg/config/gui.go | 1 - pkg/vpn/launcher_linux.go | 53 +++++++++++++++++++++------------ pkg/vpn/main.go | 11 ++++--- pkg/vpn/openvpn.go | 5 ++-- 13 files changed, 156 insertions(+), 131 deletions(-) delete mode 100644 pkg/backend/bitmask.go create mode 100644 pkg/backend/init.go diff --git a/gui/backend.go b/gui/backend.go index edb2b17..92cda6e 100644 --- a/gui/backend.go +++ b/gui/backend.go @@ -30,7 +30,6 @@ func Unblock() { //export Quit func Quit() { backend.Quit() - } //export DonateAccepted diff --git a/gui/main.cpp b/gui/main.cpp index eca834a..670e664 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -34,7 +34,7 @@ std::string getEnv(std::string const& key) return val == NULL ? std::string() : std::string(val); } -void signalHandler(int signum) { +void signalHandler(int) { Quit(); exit(0); } diff --git a/gui/qml/main.qml b/gui/qml/main.qml index 8d756c6..efcfef2 100644 --- a/gui/qml/main.qml +++ b/gui/qml/main.qml @@ -11,7 +11,6 @@ ApplicationWindow { property var ctx - Connections { target: jsonModel onDataChanged: { @@ -20,9 +19,24 @@ ApplicationWindow { console.debug(jsonModel.getJson()) donate.visible = true } + if (ctx.errors ) { + // TODO consider disabling on/off buttons, or quit after closing the dialog + if ( ctx.errors == "nohelpers" ) { + showInitFailure(qsTr("Could not find helpers. Check your installation")) + } else if ( ctx.errors == "nopolkit" ) { + showInitFailure(qsTr("Could not find polkit agent.")) + } else { + console.debug(ctx.errors) + } + } } } + function showInitFailure(msg) { + initFailure.text = msg + initFailure.visible = true + } + Component.onCompleted: { /* stupid as it sounds, windows doesn't like to have the systray icon not being attached to an actual application window. @@ -210,9 +224,6 @@ ApplicationWindow { text: "" detailedText: "" visible: false - //text: ctx ? qsTr("Can't connect to %1").arg(ctx.appName) : "" - //detailedText: ctx ? ctx.errorStartingMsg : "" - //visible: ctx.errorStartingMsg != "" } MessageDialog { @@ -222,7 +233,6 @@ ApplicationWindow { title: qsTr("Missing authentication agent") text: qsTr("Could not find a polkit authentication agent. Please run one and try again.") visible: false - //visible: ctx.missingAuthAgent == "true" } MessageDialog { @@ -232,7 +242,5 @@ ApplicationWindow { title: qsTr("Initialization Error") text: "" visible: false - //text: ctx ? ctx.errorInitMsg : "" - //visible: ctx.errorInitMsg != "" } } diff --git a/pkg/backend/bitmask.go b/pkg/backend/bitmask.go deleted file mode 100644 index 2b58859..0000000 --- a/pkg/backend/bitmask.go +++ /dev/null @@ -1,67 +0,0 @@ -package backend - -import ( - "log" - "os" - - "0xacab.org/leap/bitmask-vpn/pkg/bitmask" - "0xacab.org/leap/bitmask-vpn/pkg/config" - "0xacab.org/leap/bitmask-vpn/pkg/config/version" -) - -func initializeBitmask() { - if ctx == nil { - log.Println("error: cannot initialize bitmask, ctx is nil") - os.Exit(1) - } - bitmask.InitializeLogger() - - b, err := bitmask.InitializeBitmask() - if err != nil { - log.Println("error: cannot initialize bitmask") - } - ctx.bm = b - ctx.cfg = config.ParseConfig() -} - -func startVPN() { - err := ctx.bm.StartVPN(ctx.Provider) - if err != nil { - log.Println(err) - os.Exit(1) - } -} - -func stopVPN() { - err := ctx.bm.StopVPN() - if err != nil { - log.Println(err) - } -} - -func wantDonations() bool { - if config.AskForDonations == "true" { - return true - } - return false -} - -// initializeContext initializes an empty connStatus and assigns it to the -// global ctx holder. This is expected to be called only once, so the public -// api uses the sync.Once primitive to call this. -func initializeContext(provider, appName string) { - var st status = off - ctx = &connectionCtx{ - AppName: appName, - Provider: provider, - TosURL: config.TosURL, - HelpURL: config.HelpURL, - DonateURL: config.DonateURL, - AskForDonations: wantDonations(), - DonateDialog: false, - Version: version.VERSION, - Status: st, - } - go trigger(OnStatusChanged) - initializeBitmask() -} diff --git a/pkg/backend/callbacks.go b/pkg/backend/callbacks.go index 5ea3b04..f3bb39f 100644 --- a/pkg/backend/callbacks.go +++ b/pkg/backend/callbacks.go @@ -7,7 +7,7 @@ import ( "unsafe" ) -/* NOTE! ATCHUNG! what follow are not silly comments. Well, *this one* is, but +/* ATCHUNG! what follow are not silly comments. Well, *this one* is, but the lines after this are not. Those are inline C functions, that are invoked by CGO later on. it's also crucial that you don't any extra space between the function diff --git a/pkg/backend/donate.go b/pkg/backend/donate.go index d216687..608128f 100644 --- a/pkg/backend/donate.go +++ b/pkg/backend/donate.go @@ -3,8 +3,17 @@ package backend import ( "log" "time" + + "0xacab.org/leap/bitmask-vpn/pkg/config" ) +func wantDonations() bool { + if config.AskForDonations == "true" { + return true + } + return false +} + func needsDonationReminder() bool { return ctx.cfg.NeedsDonationReminder() } diff --git a/pkg/backend/init.go b/pkg/backend/init.go new file mode 100644 index 0000000..5abb05e --- /dev/null +++ b/pkg/backend/init.go @@ -0,0 +1,74 @@ +package backend + +import ( + "log" + "os" + + "0xacab.org/leap/bitmask-vpn/pkg/bitmask" + "0xacab.org/leap/bitmask-vpn/pkg/config" + "0xacab.org/leap/bitmask-vpn/pkg/config/version" +) + +// initializeContext initializes an empty connStatus and assigns it to the +// global ctx holder. This is expected to be called only once, so the public +// api uses the sync.Once primitive to call this. +func initializeContext(provider, appName string) { + var st status = off + ctx = &connectionCtx{ + AppName: appName, + Provider: provider, + TosURL: config.TosURL, + HelpURL: config.HelpURL, + DonateURL: config.DonateURL, + AskForDonations: wantDonations(), + DonateDialog: false, + Version: version.VERSION, + Status: st, + } + errCh := make(chan string) + go trigger(OnStatusChanged) + go checkErrors(errCh) + initializeBitmask(errCh) +} + +func checkErrors(errCh chan string) { + for { + err := <-errCh + ctx.Errors = err + go trigger(OnStatusChanged) + } +} + +func initializeBitmask(errCh chan string) { + if ctx == nil { + log.Println("bug: cannot initialize bitmask, ctx is nil!") + os.Exit(1) + } + bitmask.InitializeLogger() + + b, err := bitmask.InitializeBitmask() + if err != nil { + log.Println("error: cannot initialize bitmask") + errCh <- err.Error() + return + } + + helpers, privilege, err := b.VPNCheck() + + if err != nil { + log.Println("error doing vpn check") + errCh <- err.Error() + } + + if helpers == false { + log.Println("no helpers") + errCh <- "nohelpers" + } + if privilege == false { + log.Println("no polkit") + errCh <- "nopolkit" + } + + ctx.bm = b + ctx.cfg = config.ParseConfig() +} diff --git a/pkg/backend/status.go b/pkg/backend/status.go index 84b27b7..2e9c282 100644 --- a/pkg/backend/status.go +++ b/pkg/backend/status.go @@ -35,6 +35,7 @@ type connectionCtx struct { DonateDialog bool `json:"donateDialog"` DonateURL string `json:"donateURL"` Version string `json:"version"` + Errors string `json:"errors"` Status status `json:"status"` bm bitmask.Bitmask cfg *config.Config diff --git a/pkg/bitmask/init.go b/pkg/bitmask/init.go index 7f10ab9..33a5911 100644 --- a/pkg/bitmask/init.go +++ b/pkg/bitmask/init.go @@ -68,15 +68,17 @@ func InitializeBitmask() (Bitmask, error) { defer pid.ReleasePID() conf := config.ParseConfig() - conf.Version = "unknown" conf.Printer = initPrinter() b, err := initBitmask(conf.Printer) if err != nil { - // TODO notify failure - log.Fatal(err) + return nil, err + } + + err = checkAndStartBitmask(b, conf) + if err != nil { + return nil, err } - go checkAndStartBitmask(b, conf) var as Autostart if conf.DisableAustostart { @@ -84,6 +86,7 @@ func InitializeBitmask() (Bitmask, error) { } else { as = newAutostart(config.ApplicationName, "") } + err = as.Enable() if err != nil { log.Printf("Error enabling autostart: %v", err) @@ -100,40 +103,20 @@ func initPrinter() *message.Printer { return message.NewPrinter(message.MatchLanguage(locale, "en")) } -func checkAndStartBitmask(b Bitmask, conf *config.Config) { +func checkAndStartBitmask(b Bitmask, conf *config.Config) error { if conf.Obfs4 { err := b.UseTransport("obfs4") if err != nil { log.Printf("Error setting transport: %v", err) + return err } } - err := checkAndInstallHelpers(b) - if err != nil { - log.Printf("Is bitmask running? %v", err) - os.Exit(1) - } - err = maybeStartVPN(b, conf) + + err := maybeStartVPN(b, conf) if err != nil { log.Println("Error starting VPN: ", err) - } -} - -func checkAndInstallHelpers(b Bitmask) error { - helpers, privilege, err := b.VPNCheck() - if (err != nil && err.Error() == "nopolkit") || (err == nil && !privilege) { - log.Printf("No polkit found") - os.Exit(1) - } else if err != nil { - log.Printf("Error checking vpn: %v", err) return err } - - if !helpers { - err = b.InstallHelpers() - if err != nil { - log.Println("Error installing helpers: ", err) - } - } return nil } diff --git a/pkg/config/gui.go b/pkg/config/gui.go index 5fa4886..7f2515c 100644 --- a/pkg/config/gui.go +++ b/pkg/config/gui.go @@ -48,7 +48,6 @@ type Config struct { Obfs4 bool DisableAustostart bool StartVPN bool - Version string Printer *message.Printer } diff --git a/pkg/vpn/launcher_linux.go b/pkg/vpn/launcher_linux.go index 71a74ea..f92cf6f 100644 --- a/pkg/vpn/launcher_linux.go +++ b/pkg/vpn/launcher_linux.go @@ -1,5 +1,5 @@ // +build linux -// Copyright (C) 2018 LEAP +// Copyright (C) 2018-2020 LEAP // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -53,32 +53,49 @@ func (l *launcher) close() error { return nil } -func (l *launcher) check() (helpers bool, priviledge bool, err error) { +func (l *launcher) check() (helpers bool, privilege bool, err error) { + hasHelpers, err := hasHelpers() + if err != nil { + return + } + if !hasHelpers { + return false, true, nil + } - /* - isRunning, err := isPolkitRunning() + 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 } - 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 - } - */ + isRunning, err = isPolkitRunning() + return true, isRunning, err + } return true, true, nil } +func hasHelpers() (bool, error) { + /* TODO add polkit file too */ + for _, f := range bitmaskRootPaths { + if _, err := os.Stat(f); err == nil { + return true, nil + } + } + return false, nil +} + func isPolkitRunning() (bool, error) { + // TODO shouldn't we also check for polkitd running? var polkitProcNames = [...]string{ "polkit-gnome-authentication-agent-1", "polkit-kde-authentication-agent-1", diff --git a/pkg/vpn/main.go b/pkg/vpn/main.go index ce599c9..9d59131 100644 --- a/pkg/vpn/main.go +++ b/pkg/vpn/main.go @@ -51,10 +51,13 @@ func Init() (*Bitmask, error) { } b := Bitmask{tempdir, statusCh, nil, bonafide, launch, "", nil} - err = b.StopVPN() - if err != nil { - return nil, err - } + /* + err = b.StopVPN() + if err != nil { + return nil, err + } + */ + err = ioutil.WriteFile(b.getCaCertPath(), config.CaCert, 0600) go b.openvpnManagement() diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go index a75b830..984aa09 100644 --- a/pkg/vpn/openvpn.go +++ b/pkg/vpn/openvpn.go @@ -207,14 +207,13 @@ func (b *Bitmask) GetStatus() (string, error) { return status, nil } -// InstallHelpers into the system func (b *Bitmask) InstallHelpers() error { - // TODO + // TODO use pickle module from here return nil } // 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) { +func (b *Bitmask) VPNCheck() (helpers bool, privilege bool, err error) { return b.launch.check() } -- cgit v1.2.3