diff options
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | bitmask/bitmask.go | 29 | ||||
-rw-r--r-- | bitmask_go.go | 26 | ||||
-rw-r--r-- | bitmask_go/bonafide.go | 87 | ||||
-rw-r--r-- | bitmask_go/bonafide_test.go | 26 | ||||
-rw-r--r-- | bitmask_go/launcher_linux.go | 92 | ||||
-rw-r--r-- | bitmask_go/main.go | 78 | ||||
-rw-r--r-- | bitmask_go/status.go | 91 | ||||
-rw-r--r-- | bitmask_go/vpn.go | 98 | ||||
-rw-r--r-- | bitmaskd.go | 26 | ||||
-rw-r--r-- | bitmaskd/events.go (renamed from bitmask/events.go) | 0 | ||||
-rw-r--r-- | bitmaskd/main.go (renamed from bitmask/main.go) | 6 | ||||
-rw-r--r-- | bitmaskd/vpn.go (renamed from bitmask/vpn.go) | 0 | ||||
-rw-r--r-- | main.go | 8 | ||||
-rw-r--r-- | systray.go | 12 |
15 files changed, 576 insertions, 16 deletions
@@ -1,15 +1,20 @@ -.PHONY: all get build icon locales generate_locales clean +.PHONY: all get build build_go icon locales generate_locales clean + +TAGS ?= gtk_3_18 all: icon locales get build get: - go get -tags 'gtk_3_18' . + go get -tags $(TAGS) . ./bitmask_go build: - go build -tags 'gtk_3_18' -ldflags "-X main.version=`git describe --tags`" + go build -tags $(TAGS) -ldflags "-X main.version=`git describe --tags`" test: - go test -tags 'gtk_3_18' ./... + go test -tags $(TAGS) ./... + +build_go: + go build -tags "$(TAGS) bitmask_go" -ldflags "-X main.version=`git describe --tags`" clean: make -C icon clean diff --git a/bitmask/bitmask.go b/bitmask/bitmask.go new file mode 100644 index 0000000..f9b1cc9 --- /dev/null +++ b/bitmask/bitmask.go @@ -0,0 +1,29 @@ +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package bitmask + +type Bitmask interface { + GetStatusCh() <-chan string + Close() + Version() (string, error) + StartVPN(provider string) error + StopVPN() error + GetStatus() (string, error) + InstallHelpers() error + VPNCheck() (helpers bool, priviledge bool, err error) + ListGateways(provider string) ([]string, error) + UseGateway(name string) error +} diff --git a/bitmask_go.go b/bitmask_go.go new file mode 100644 index 0000000..38ec289 --- /dev/null +++ b/bitmask_go.go @@ -0,0 +1,26 @@ +// +build bitmask_go +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package main + +import ( + "0xacab.org/leap/bitmask-systray/bitmask" + bitmask_go "0xacab.org/leap/bitmask-systray/bitmask_go" +) + +func initBitmask() (bitmask.Bitmask, error) { + return bitmask_go.Init() +} diff --git a/bitmask_go/bonafide.go b/bitmask_go/bonafide.go new file mode 100644 index 0000000..25fa302 --- /dev/null +++ b/bitmask_go/bonafide.go @@ -0,0 +1,87 @@ +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package bitmask + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" + "net/http" +) + +const ( + certAPI = "https://api.black.riseup.net/1/cert" +) + +var ( + caCert = []byte(`-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBZMRgwFgYDVQQKDA9SaXNl +dXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UE +AwwXUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EwHhcNMTQwNDI4MDAwMDAwWhcNMjQw +NDI4MDAwMDAwWjBZMRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsM +Emh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UEAwwXUmlzZXVwIE5ldHdvcmtzIFJv +b3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC76J4ciMJ8Sg0m +TP7DF2DT9zNe0Csk4myoMFC57rfJeqsAlJCv1XMzBmXrw8wq/9z7XHv6n/0sWU7a +7cF2hLR33ktjwODlx7vorU39/lXLndo492ZBhXQtG1INMShyv+nlmzO6GT7ESfNE +LliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq/SYUMoOJ96O3hmPSl1kFDRMtWXY +iw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK +5VNTlNy6nZpkjt1QycYvNycffyPOFm/Q/RKDlvnorJIrihPkyniV3YY5cGgP+Qkx +HUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58 +m/4UIjG3PInWTNf293GngK2Bnz8Qx9e/6TueMSAn/3JBLem56E0WtmbLVjvko+LF +PM5xA+m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG+cXB28k6XikXt6MRG7q +hzIPG38zwkooM55yy5i1YfcIi5NjMH6A+t4IJxxwb67MSb6UFOwg5kFokdONZcwj +shczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu//STcQxOailDBQCnXXfAATj9pYzdY4k +ha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu +f9hwfK4AGliaet5KkcgwDgYDVR0PAQH/BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD +VR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB +AGzL+GRnYu99zFoy0bXJKOGCF5XUXP/3gIXPRDqQf5g7Cu/jYMID9dB3No4Zmf7v +qHjiSXiS8jx1j/6/Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P/ +3GJAVYH/+7OjA39za9AieM7+H5BELGccGrM5wfl7JeEz8in+V2ZWDzHQO4hMkiTQ +4ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY/wvlrOpclh95qn+lG6/2jk7 +3AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch +Td5CHKGxEEWbGUWEMP0s1A/JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf +Xu5pYKNkzKSEtT/MrNJt44tTZWbKV/Pi/N2Fx36my7TgTUj7g3xcE9eF4JV2H/sg +tsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF +tGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x/eaWdTc4vPpf/rIlgbAjarnJ +UN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp +0BuC1b7uW/bBn/xKm319wXVDvBgZgcktMolak39V7DVO +-----END CERTIFICATE-----`) +) + +func getCertPem() ([]byte, error) { + certs := x509.NewCertPool() + certs.AppendCertsFromPEM(caCert) + client := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: certs, + }, + }, + } + + resp, err := client.Post(certAPI, "", nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("get vpn cert has failed with status: %s", resp.Status) + } + + return ioutil.ReadAll(resp.Body) +} diff --git a/bitmask_go/bonafide_test.go b/bitmask_go/bonafide_test.go new file mode 100644 index 0000000..c40c98d --- /dev/null +++ b/bitmask_go/bonafide_test.go @@ -0,0 +1,26 @@ +package bitmask + +import ( + "bytes" + "testing" +) + +var ( + privateKeyHeader = []byte("-----BEGIN RSA PRIVATE KEY-----") + certHeader = []byte("-----BEGIN CERTIFICATE-----") +) + +func TestGetCert(t *testing.T) { + cert, err := getCertPem() + if err != nil { + t.Fatal("get_cert returned an error: ", err) + } + + if !bytes.Contains(cert, privateKeyHeader) { + t.Errorf("No private key present: \n%q", cert) + } + + if !bytes.Equal(cert, certHeader) { + t.Errorf("No cert present: \n%q", cert) + } +} diff --git a/bitmask_go/launcher_linux.go b/bitmask_go/launcher_linux.go new file mode 100644 index 0000000..05398a6 --- /dev/null +++ b/bitmask_go/launcher_linux.go @@ -0,0 +1,92 @@ +// +build linux +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package bitmask + +import ( + "errors" + "log" + "os" + "os/exec" +) + +const ( + systemOpenvpnPath = "/usr/sbin/openvpn" + snapOpenvpnPath = "/snap/bin/riseup-vpn.openvpn" +) + +var bitmaskRootPaths = []string{ + "/usr/sbin/bitmask-root", + "/usr/local/sbin/bitmask-root", + "/snap/bin/riseup-vpn.bitmask-root", +} + +func openvpnStart(flags ...string) error { + log.Println("openvpn start: ", flags) + arg := []string{"openvpn", "start", getOpenvpnPath()} + arg = append(arg, flags...) + // TODO: check errors somehow instead of fire and forget + go runBitmaskRoot(arg...) + return nil +} + +func openvpnStop() error { + log.Println("openvpn stop") + return runBitmaskRoot("openvpn", "stop") +} + +func firewallStart(gateways []string) error { + log.Println("firewall start") + arg := []string{"firewall", "start"} + arg = append(arg, gateways...) + return runBitmaskRoot(arg...) +} + +func firewallStop() error { + log.Println("firewall stop") + return runBitmaskRoot("firewall", "stop") +} + +func runBitmaskRoot(arg ...string) error { + bitmaskRoot, err := bitmaskRootPath() + if err != nil { + return err + } + arg = append([]string{bitmaskRoot}, arg...) + + cmd := exec.Command("pkexec", arg...) + err = cmd.Run() + if err != nil { + return err + } + return nil +} + +func bitmaskRootPath() (string, error) { + for _, path := range bitmaskRootPaths { + if _, err := os.Stat(path); !os.IsNotExist(err) { + return path, nil + } + } + return "", errors.New("No bitmask-root found") +} + +func getOpenvpnPath() string { + if os.Getenv("SNAP") != "" { + return snapOpenvpnPath + } + return systemOpenvpnPath +} diff --git a/bitmask_go/main.go b/bitmask_go/main.go new file mode 100644 index 0000000..49f803a --- /dev/null +++ b/bitmask_go/main.go @@ -0,0 +1,78 @@ +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package bitmask + +import ( + "io/ioutil" + "log" + "os" + + "github.com/apparentlymart/go-openvpn-mgmt/openvpn" +) + +// Bitmask holds the bitmask client data +type Bitmask struct { + tempdir string + statusCh chan string + managementClient *openvpn.MgmtClient +} + +// Init the connection to bitmask +func Init() (*Bitmask, error) { + statusCh := make(chan string, 10) + tempdir, err := ioutil.TempDir("", "leap-") + if err != nil { + return nil, err + } + b := Bitmask{tempdir, statusCh, nil} + + err = b.StopVPN() + if err != nil { + return nil, err + } + + cert, err := getCertPem() + if err != nil { + return nil, err + } + err = ioutil.WriteFile(b.getCertPemPath(), cert, 0600) + if err != nil { + return nil, err + } + err = ioutil.WriteFile(b.getCaCertPath(), caCert, 0600) + + go b.openvpnManagement() + return &b, err +} + +// GetStatusCh returns a channel that will recieve VPN status changes +func (b *Bitmask) GetStatusCh() <-chan string { + return b.statusCh +} + +// Close the connection to bitmask +func (b *Bitmask) Close() { + b.StopVPN() + err := os.RemoveAll(b.tempdir) + if err != nil { + log.Printf("There was an error removing temp dir: %v", err) + } +} + +// Version gets the bitmask version string +func (b *Bitmask) Version() (string, error) { + return "", nil +} diff --git a/bitmask_go/status.go b/bitmask_go/status.go new file mode 100644 index 0000000..5a1ee3d --- /dev/null +++ b/bitmask_go/status.go @@ -0,0 +1,91 @@ +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package bitmask + +import ( + "fmt" + "log" + + "github.com/apparentlymart/go-openvpn-mgmt/openvpn" +) + +const ( + On = "on" + Off = "off" + Starting = "starting" + Stopping = "stopping" + Failed = "failed" +) + +var statusNames = map[string]string{ + "CONNECTING": Starting, + "WAIT": Starting, + "AUTH": Starting, + "GET_CONFIG": Starting, + "ASSIGN_IP": Starting, + "ADD_ROUTES": Starting, + "CONNECTED": On, + "RECONNECTING": Starting, + "EXITING": Stopping, + "OFF": Off, + "FAILED": Off, +} + +func (b *Bitmask) openvpnManagement() { + // TODO: we should warn the user on ListenAndServe errors + newConnection := func(conn openvpn.IncomingConn) { + eventCh := make(chan openvpn.Event, 10) + log.Println("New connection into the management") + b.managementClient = conn.Open(eventCh) + b.managementClient.SetStateEvents(true) + b.eventHandler(eventCh) + } + log.Fatal(openvpn.ListenAndServe( + fmt.Sprintf("%s:%s", openvpnManagementAddr, openvpnManagementPort), + openvpn.IncomingConnHandlerFunc(newConnection), + )) +} + +func (b *Bitmask) eventHandler(eventCh <-chan openvpn.Event) { + // TODO: we are reporing only openvpn status, missing firewall status + for event := range eventCh { + log.Printf("Event: %v", event) + stateEvent, ok := event.(*openvpn.StateEvent) + if !ok { + continue + } + status, ok := statusNames[stateEvent.NewState()] + if ok { + b.statusCh <- status + } + } + b.statusCh <- Off +} + +func (b *Bitmask) getOpenvpnState() (string, error) { + if b.managementClient == nil { + return "", fmt.Errorf("No management connected") + } + stateEvent, err := b.managementClient.LatestState() + if err != nil { + return "", err + } + status, ok := statusNames[stateEvent.NewState()] + if !ok { + return "", fmt.Errorf("Unkonw status") + } + return status, nil +} diff --git a/bitmask_go/vpn.go b/bitmask_go/vpn.go new file mode 100644 index 0000000..09adcf0 --- /dev/null +++ b/bitmask_go/vpn.go @@ -0,0 +1,98 @@ +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package bitmask + +import ( + "path" +) + +const ( + openvpnManagementAddr = "127.0.0.1" + openvpnManagementPort = "6061" +) + +var gateways = []string{ + "5.79.86.180", + "199.58.81.145", + "198.252.153.28", +} + +// StartVPN for provider +func (b *Bitmask) StartVPN(provider string) error { + // TODO: openvpn args are hardcoded + err := firewallStart(gateways) + if err != nil { + return err + } + + arg := []string{"--nobind", "--verb", "1"} + for _, gw := range gateways { + arg = append(arg, "--remote", gw, "443", "tcp4") + } + certPemPath := b.getCertPemPath() + arg = append(arg, "--client", "--tls-client", "--remote-cert-tls", "server", "--tls-cipher", "DHE-RSA-AES128-SHA", "--cipher", "AES-128-CBC", "--tun-ipv6", "--auth", "SHA1", "--keepalive", "10 30", "--management-client", "--management", openvpnManagementAddr+" "+openvpnManagementPort, "--ca", b.getCaCertPath(), "--cert", certPemPath, "--key", certPemPath) + return openvpnStart(arg...) +} + +// StopVPN or cancel +func (b *Bitmask) StopVPN() error { + err := firewallStop() + if err != nil { + return err + } + return openvpnStop() +} + +// GetStatus returns the VPN status +func (b *Bitmask) GetStatus() (string, error) { + status, err := b.getOpenvpnState() + if err != nil { + status = Off + } + return status, nil +} + +// InstallHelpers into the system +func (b *Bitmask) InstallHelpers() error { + // TODO + 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) { + // TODO + return true, true, nil +} + +// ListGateways return the names of the gateways +func (b *Bitmask) ListGateways(provider string) ([]string, error) { + // TODO + return []string{}, nil +} + +// UseGateway selects name as the default gateway +func (b *Bitmask) UseGateway(name string) error { + // TODO + return nil +} + +func (b *Bitmask) getCertPemPath() string { + return path.Join(b.tempdir, "openvpn.pem") +} + +func (b *Bitmask) getCaCertPath() string { + return path.Join(b.tempdir, "cacert.pem") +} diff --git a/bitmaskd.go b/bitmaskd.go new file mode 100644 index 0000000..aa94ca0 --- /dev/null +++ b/bitmaskd.go @@ -0,0 +1,26 @@ +// +build !bitmask_go +// Copyright (C) 2018 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package main + +import ( + "0xacab.org/leap/bitmask-systray/bitmask" + bitmaskd "0xacab.org/leap/bitmask-systray/bitmaskd" +) + +func initBitmask() (bitmask.Bitmask, error) { + return bitmaskd.Init() +} diff --git a/bitmask/events.go b/bitmaskd/events.go index e97804c..e97804c 100644 --- a/bitmask/events.go +++ b/bitmaskd/events.go diff --git a/bitmask/main.go b/bitmaskd/main.go index e0bf4a0..2ff2268 100644 --- a/bitmask/main.go +++ b/bitmaskd/main.go @@ -24,6 +24,8 @@ import ( "net/http" "path" "time" + + "0xacab.org/leap/bitmask-systray/bitmask" ) const ( @@ -62,7 +64,7 @@ func Init() (*Bitmask, error) { } // GetStatusCh returns a channel that will recieve VPN status changes -func (b *Bitmask) GetStatusCh() chan string { +func (b *Bitmask) GetStatusCh() <-chan string { return b.statusCh } @@ -148,7 +150,7 @@ func parseResponse(resJSON []byte) (interface{}, error) { func getToken() (string, error) { var err error - path := path.Join(ConfigPath, "authtoken") + path := path.Join(bitmask.ConfigPath, "authtoken") for i := 0; i < 30; i++ { b, err := ioutil.ReadFile(path) if err == nil { diff --git a/bitmask/vpn.go b/bitmaskd/vpn.go index aee5e8f..aee5e8f 100644 --- a/bitmask/vpn.go +++ b/bitmaskd/vpn.go @@ -62,7 +62,7 @@ func main() { notify := newNotificator(conf) - b, err := bitmask.Init() + b, err := initBitmask() if err != nil { log.Print(err) notify.bitmaskNotRunning() @@ -74,7 +74,7 @@ func main() { run(b, conf, notify) } -func checkAndStartBitmask(b *bitmask.Bitmask, notify *notificator, conf *systrayConfig) { +func checkAndStartBitmask(b bitmask.Bitmask, notify *notificator, conf *systrayConfig) { err := checkAndInstallHelpers(b, notify) if err != nil { log.Printf("Is bitmask running? %v", err) @@ -87,7 +87,7 @@ func checkAndStartBitmask(b *bitmask.Bitmask, notify *notificator, conf *systray } } -func checkAndInstallHelpers(b *bitmask.Bitmask, notify *notificator) error { +func checkAndInstallHelpers(b bitmask.Bitmask, notify *notificator) error { helpers, priviledge, err := b.VPNCheck() if (err != nil && err.Error() == "nopolkit") || (err == nil && !priviledge) { log.Printf("No polkit found") @@ -106,7 +106,7 @@ func checkAndInstallHelpers(b *bitmask.Bitmask, notify *notificator) error { return nil } -func maybeStartVPN(b *bitmask.Bitmask, conf *systrayConfig) error { +func maybeStartVPN(b bitmask.Bitmask, conf *systrayConfig) error { if conf.UserStoppedVPN { return nil } @@ -27,7 +27,7 @@ import ( ) type bmTray struct { - bm *bitmask.Bitmask + bm bitmask.Bitmask conf *systrayConfig notify *notificator waitCh chan bool @@ -44,7 +44,7 @@ type gatewayTray struct { name string } -func run(bm *bitmask.Bitmask, conf *systrayConfig, notify *notificator) { +func run(bm bitmask.Bitmask, conf *systrayConfig, notify *notificator) { bt := bmTray{bm: bm, conf: conf, notify: notify} systray.Run(bt.onReady, bt.onExit) } @@ -117,13 +117,13 @@ func (bt *bmTray) onReady() { open.Run("https://riseup.net/vpn/donate") case <-mAbout.ClickedCh: bitmaskVersion, err := bt.bm.Version() + versionStr := version if err != nil { log.Printf("Error getting version: %v", err) - bt.notify.about(version) - } else { - versionStr := fmt.Sprintf("%s (bitmaskd %s)", version, bitmaskVersion) - bt.notify.about(versionStr) + } else if bitmaskVersion != "" { + versionStr = fmt.Sprintf("%s (bitmaskd %s)", version, bitmaskVersion) } + bt.notify.about(versionStr) case <-mQuit.ClickedCh: systray.Quit() |