Newer
Older
// 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/>.
"0xacab.org/leap/bitmask-systray/bitmask"
"0xacab.org/leap/bitmask-systray/icon"
"github.com/skratchdot/open-golang/open"
)
type bmTray struct {
conf *systrayConfig
waitCh chan bool
mStatus *systray.MenuItem
mTurnOn *systray.MenuItem
mTurnOff *systray.MenuItem
mDonate *systray.MenuItem
mCancel *systray.MenuItem
activeGateway *gatewayTray
}
type gatewayTray struct {
menuItem *systray.MenuItem
name string
func run(bm bitmask.Bitmask, conf *systrayConfig, notify *notificator, as autostart) {
bt := bmTray{bm: bm, conf: conf, notify: notify, autostart: as}
systray.Run(bt.onReady, bt.onExit)
}
func (bt bmTray) onExit() {
status, _ := bt.bm.GetStatus()
if status != "off" {
ch := bt.bm.GetStatusCh()
bt.bm.StopVPN()
status = <-ch
}
}
func (bt *bmTray) onReady() {
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt)
systray.SetIcon(icon.Off)
bt.mStatus = systray.AddMenuItem(printer.Sprintf("Checking status..."), "")
bt.mTurnOn = systray.AddMenuItem(printer.Sprintf("Turn on"), "")
bt.mTurnOff = systray.AddMenuItem(printer.Sprintf("Turn off"), "")
bt.mCancel = systray.AddMenuItem(printer.Sprintf("Cancel"), printer.Sprintf("Cancel connection to %s", applicationName))
bt.addGateways()
}
mHelp := systray.AddMenuItem(printer.Sprintf("Help..."), "")
bt.mDonate = systray.AddMenuItem(printer.Sprintf("Donate..."), "")
mAbout := systray.AddMenuItem(printer.Sprintf("About..."), "")
mQuit := systray.AddMenuItem(printer.Sprintf("Quit"), "")
log.Printf("Error getting status: %v", err)
} else {
bt.changeStatus(status)
}
for {
select {
case status := <-ch:
log.Println("status: " + status)
bt.changeStatus(status)
case <-bt.mTurnOn.ClickedCh:
bt.conf.setUserStoppedVPN(false)
bt.conf.setUserStoppedVPN(true)
bt.conf.setUserStoppedVPN(true)
case <-bt.mDonate.ClickedCh:
bt.conf.setDonated()
open.Run("https://riseup.net/vpn/donate")
case <-mAbout.ClickedCh:
bitmaskVersion, err := bt.bm.Version()
if err != nil {
log.Printf("Error getting version: %v", err)
} else if bitmaskVersion != "" {
versionStr = fmt.Sprintf("%s (bitmaskd %s)", version, bitmaskVersion)
err := bt.autostart.Disable()
if err != nil {
log.Printf("Error disabling autostart: %v", err)
}
case <-time.After(5 * time.Second):
if status, err := bt.bm.GetStatus(); err != nil {
log.Printf("Error getting status: %v", err)
} else {
bt.changeStatus(status)
}
func (bt *bmTray) addGateways() {
gatewayList, err := bt.bm.ListGateways(provider)
if err != nil {
log.Printf("Gateway initialization error: %v", err)
return
}
mGateway := systray.AddMenuItem(printer.Sprintf("Route traffic through"), "")
for i, city := range gatewayList {
menuItem := systray.AddMenuItem(city, printer.Sprintf("Use %s %v gateway", applicationName, city))
gateway := gatewayTray{menuItem, city}
bt.activeGateway = &gateway
} else {
menuItem.Uncheck()
}
go func(gateway gatewayTray) {
for {
<-menuItem.ClickedCh
gateway.menuItem.SetTitle("*" + gateway.name)
gateway.menuItem.Check()
bt.activeGateway.menuItem.Uncheck()
bt.activeGateway.menuItem.SetTitle(bt.activeGateway.name)
bt.activeGateway = &gateway
bt.bm.UseGateway(gateway.name)
}
}(gateway)
}
systray.AddSeparator()
}
func (bt *bmTray) changeStatus(status string) {
if bt.waitCh != nil {
bt.waitCh <- true
bt.waitCh = nil
}
switch status {
case "on":
systray.SetIcon(icon.On)
statusStr = printer.Sprintf("%s on", applicationName)
bt.mTurnOn.Hide()
bt.mTurnOff.Show()
bt.mCancel.Hide()
case "off":
systray.SetIcon(icon.Off)
statusStr = printer.Sprintf("%s off", applicationName)
bt.mTurnOn.Show()
bt.mTurnOff.Hide()
bt.mCancel.Hide()
statusStr = printer.Sprintf("Connecting to %s", applicationName)
bt.mTurnOn.Hide()
bt.mTurnOff.Hide()
bt.mCancel.Show()
statusStr = printer.Sprintf("Stopping %s", applicationName)
bt.mTurnOn.Hide()
bt.mTurnOff.Hide()
bt.mCancel.Hide()
statusStr = printer.Sprintf("%s blocking internet", applicationName)
bt.mTurnOn.Show()
bt.mTurnOff.Show()
bt.mCancel.Hide()
systray.SetTooltip(statusStr)
bt.mStatus.SetTitle(statusStr)
func (bt *bmTray) waitIcon() {
icons := [][]byte{icon.Wait0, icon.Wait1, icon.Wait2, icon.Wait3}
select {
case <-bt.waitCh:
return
case <-time.After(time.Millisecond * 500):