summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/changelog.rst1
-rw-r--r--src/leap/bitmask/config.py4
-rw-r--r--src/leap/bitmask/vpn/autostart.py45
-rw-r--r--src/leap/bitmask/vpn/service.py33
4 files changed, 76 insertions, 7 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 86f07ea4..c7bca741 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -13,6 +13,7 @@ Features
- `#9188 <https://0xacab.org/leap/bitmask-dev/issues/9188>`_: try other gateways if the main one fails.
- `#9125 <https://0xacab.org/leap/bitmask-dev/issues/9125>`_: port to use qtwebengine for rendering UI.
- `#9181 <https://0xacab.org/leap/bitmask-dev/issues/9181>`_: hardcode tcp4 in the vpn connection parameters.
+- Autostart VPN if it was running when closed the application.
- Set a windows title, so that Bitmask windows can be programmatically manipulated.
- Support anonymous vpn.
diff --git a/src/leap/bitmask/config.py b/src/leap/bitmask/config.py
index 4c1fbca7..17a20d3f 100644
--- a/src/leap/bitmask/config.py
+++ b/src/leap/bitmask/config.py
@@ -96,4 +96,8 @@ class _ConfigurationSection(object):
return self.config.get(self.section, option, default, boolean)
def set(self, option, value):
+ if value is True:
+ value = 'true'
+ elif value is False:
+ value = 'false'
return self.config.set(self.section, option, value)
diff --git a/src/leap/bitmask/vpn/autostart.py b/src/leap/bitmask/vpn/autostart.py
new file mode 100644
index 00000000..43abfdf5
--- /dev/null
+++ b/src/leap/bitmask/vpn/autostart.py
@@ -0,0 +1,45 @@
+import os
+import os.path
+
+from leap.bitmask.vpn.constants import IS_LINUX, IS_MAC
+from leap.bitmask.util import STANDALONE
+from leap.common.config import get_path_prefix
+
+if IS_LINUX:
+ AUTOSTART = r"""[Desktop Entry]
+Name=Bitmask
+Type=Application
+Exec=bitmask
+Terminal=false
+"""
+ config = get_path_prefix(standalone=False)
+ autostart_file = os.path.join(config, 'autostart', 'bitmask.desktop')
+
+ def autostart_app(status):
+ """
+ Leave an autostart file in the user's autostart path.
+
+ The bundle could in principle find its own path and add
+ the path to the bitmaskd binary in the Exec entry.
+ But for now it's simpler to do autostart only for the debian packages
+ or any other method that puts bitmask in the path.
+ On the other hand, we want to reduce the modifications that the bundle
+ leaves behind.
+ """
+ if not STANDALONE:
+ if status == 'on':
+ _dir = os.path.split(autostart_file)[0]
+ if not os.path.isdir(_dir):
+ os.makedirs(_dir)
+ with open(autostart_file, 'w') as f:
+ f.write(AUTOSTART)
+ elif status == 'off':
+ os.unlink(autostart_file)
+
+if IS_MAC:
+
+ def autostart_app_on():
+ pass
+
+ def autostart_app_off():
+ pass
diff --git a/src/leap/bitmask/vpn/service.py b/src/leap/bitmask/vpn/service.py
index db4c20af..c12f66dd 100644
--- a/src/leap/bitmask/vpn/service.py
+++ b/src/leap/bitmask/vpn/service.py
@@ -19,6 +19,7 @@
"""
VPN service declaration.
"""
+
import json
import os
@@ -38,6 +39,7 @@ from leap.bitmask.vpn._checks import (
)
from leap.bitmask.vpn import privilege, helpers
+from leap.bitmask.vpn import autostart
from leap.common.config import get_path_prefix
from leap.common.files import check_and_fix_urw_only
from leap.common.events import catalog, emit_async
@@ -85,10 +87,10 @@ class VPNService(HookableService):
except ValueError:
self._loc = []
- _autostart = self._cfg.get('autostart', False)
+ _autostart = self._cfg.get('autostart', False, boolean=True)
self._autostart = _autostart
- _anonymous = self._cfg.get('anonymous', True)
+ _anonymous = self._cfg.get('anonymous', True, boolean=True)
self._anonymous_enabled = _anonymous
if helpers.check() and self._firewall.is_up():
@@ -114,6 +116,7 @@ class VPNService(HookableService):
@defer.inlineCallbacks
def start_vpn(self, domain=None):
self._cfg.set('autostart', True)
+ autostart.autostart_app('on')
if self.do_status()['status'] == 'on':
exc = Exception('VPN already started')
exc.expected = True
@@ -152,26 +155,42 @@ class VPNService(HookableService):
else:
data = {'result': 'failed', 'error': '%r' % result}
- self.watchdog.start(WATCHDOG_PERIOD)
+ if not self.watchdog.running:
+ self.watchdog.start(WATCHDOG_PERIOD)
defer.returnValue(data)
def stop_vpn(self, shutdown=False):
- self._cfg.set('autostart', shutdown)
+ if shutdown:
+ if self._tunnel and self._tunnel.status.get('status') == 'on':
+ self._set_autostart('on')
+ else:
+ self._set_autostart('off')
+ else:
+ self._set_autostart('off')
+
if self._firewall.is_up():
fw_ok = self._firewall.stop()
if not fw_ok:
- self.log.error("Firewall: error stopping")
+ self.log.error('Firewall: error stopping')
if not self._tunnel:
return {'result': 'VPN was not running'}
vpn_ok = self._tunnel.stop()
if not vpn_ok:
- raise Exception("Error stopping VPN")
+ raise Exception('Error stopping VPN')
self.watchdog.stop()
return {'result': 'vpn stopped'}
+ def _set_autostart(self, status):
+ if status.lower() == 'on':
+ self._cfg.set('autostart', True)
+ autostart.autostart_app('on')
+ elif status.lower() == 'off':
+ self._cfg.set('autostart', False)
+ autostart.autostart_app('off')
+
def push_status(self):
try:
statusdict = self.do_status()
@@ -221,7 +240,7 @@ class VPNService(HookableService):
# fetch vpn cert and store
bonafide = self.parent.getServiceNamed("bonafide")
_, cert_str = yield bonafide.do_get_vpn_cert(
- username, anonymous=anonymous)
+ username, anonymous=anonymous)
cert_path = get_vpn_cert_path(provider)
cert_dir = os.path.dirname(cert_path)