summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2017-08-31 10:58:59 +0200
committerRuben Pollan <meskio@sindominio.net>2017-08-31 19:21:42 +0200
commit808f9d3542e21c819beb8fe72224f000ae2e019c (patch)
tree661e9e098103658a49d4e9170128c8592464249e
parentf721c5ef0cdd9952d014a1dc9e3a944afc0f7f45 (diff)
[feat] expose an API to set/get/list gateway preferences
- Related: #9010
-rw-r--r--docs/vpn/index.rst2
-rw-r--r--src/leap/bitmask/cli/vpn.py2
-rw-r--r--src/leap/bitmask/core/dispatcher.py14
-rw-r--r--src/leap/bitmask/core/service.py3
-rw-r--r--src/leap/bitmask/vpn/service.py57
-rw-r--r--ui/app/lib/bitmask.js40
6 files changed, 95 insertions, 23 deletions
diff --git a/docs/vpn/index.rst b/docs/vpn/index.rst
index 7bb4799a..0ec660fe 100644
--- a/docs/vpn/index.rst
+++ b/docs/vpn/index.rst
@@ -22,7 +22,7 @@ wants to manually override the selection, the only way to do this for the
``0.10`` version of Bitmask is to add a section to the ``bitmaskd.cfg``
configuration file::
- [vpn_prefs]
+ [vpn]
locations = ["rio__br"]
countries = ["BR", "AR", "UY"]
diff --git a/src/leap/bitmask/cli/vpn.py b/src/leap/bitmask/cli/vpn.py
index cf4cf169..6917b15d 100644
--- a/src/leap/bitmask/cli/vpn.py
+++ b/src/leap/bitmask/cli/vpn.py
@@ -47,7 +47,7 @@ SUBCOMMANDS:
'''.format(name=command.appname)
commands = ['stop', 'install', 'uninstall',
- 'enable', 'disable']
+ 'enable', 'disable', 'locations', 'countries']
def start(self, raw_args):
parser = argparse.ArgumentParser(
diff --git a/src/leap/bitmask/core/dispatcher.py b/src/leap/bitmask/core/dispatcher.py
index 508a925d..363594ca 100644
--- a/src/leap/bitmask/core/dispatcher.py
+++ b/src/leap/bitmask/core/dispatcher.py
@@ -237,6 +237,20 @@ class VPNCmd(SubCommand):
d = vpn.do_list()
return d
+ @register_method('list')
+ def do_LOCATIONS(self, vpn, *parts):
+ if len(parts) > 2:
+ return vpn.do_set_locations(parts[2:])
+
+ return vpn.do_get_locations()
+
+ @register_method('list')
+ def do_COUNTRIES(self, vpn, *parts):
+ if len(parts) > 2:
+ return vpn.do_set_countries(parts[2:])
+
+ return vpn.do_get_countries()
+
class MailCmd(SubCommand):
diff --git a/src/leap/bitmask/core/service.py b/src/leap/bitmask/core/service.py
index e823d829..026e51d9 100644
--- a/src/leap/bitmask/core/service.py
+++ b/src/leap/bitmask/core/service.py
@@ -208,7 +208,8 @@ class BitmaskBackend(configurable.ConfigurableService):
def _init_vpn(self):
if HAS_VPN:
- self._maybe_init_service('vpn', VPNService)
+ cfg = self.get_config_section('vpn')
+ self._maybe_init_service('vpn', VPNService, cfg)
def _init_zmq(self):
zs = _zmq.ZMQServerService(self)
diff --git a/src/leap/bitmask/vpn/service.py b/src/leap/bitmask/vpn/service.py
index 6588e1d5..c410f7e4 100644
--- a/src/leap/bitmask/vpn/service.py
+++ b/src/leap/bitmask/vpn/service.py
@@ -50,7 +50,7 @@ class VPNService(HookableService):
_last_vpn_path = os.path.join('leap', 'last_vpn')
log = Logger()
- def __init__(self, basepath=None):
+ def __init__(self, cfg, basepath=None):
"""
Initialize VPN service. This launches both the firewall and the vpn.
"""
@@ -59,12 +59,24 @@ class VPNService(HookableService):
self._tunnel = None
self._firewall = FirewallManager([])
self._domain = ''
+ self._cfg = cfg
if basepath is None:
self._basepath = get_path_prefix()
else:
self._basepath = basepath
+ try:
+ _cco = self._cfg.get('countries', "")
+ self._cco = json.loads(_cco)
+ except ValueError:
+ self._cco = []
+ try:
+ _loc = self._cfg.get('locations', "")
+ self._loc = json.loads(_loc)
+ except ValueError:
+ self._loc = []
+
if helpers.check() and self._firewall.is_up():
self._firewall.stop()
@@ -194,10 +206,29 @@ class VPNService(HookableService):
config = yield bonafide.do_provider_read(provider, 'eip')
except ValueError:
continue
- gateways = self._gateways(config)
+ gateways = GatewaySelector(
+ config.gateways, config.locations,
+ preferred={'cc': self._cco, 'loc': self._loc}
+ )
provider_dict[provider] = gateways.get_sorted_gateways()
defer.returnValue(provider_dict)
+ def do_set_locations(self, locations):
+ self._loc = locations
+ self._cfg.set('locations', json.dumps(locations))
+ return {'locations': 'ok'}
+
+ def do_get_locations(self):
+ return self._loc
+
+ def do_set_countries(self, countries):
+ self._cco = countries
+ self._cfg.set('countries', json.dumps(countries))
+ return {'countries': 'ok'}
+
+ def do_get_countries(self):
+ return self._cco
+
@defer.inlineCallbacks
def _setup(self, provider):
"""Set up ConfiguredTunnel for a specified provider.
@@ -208,7 +239,10 @@ class VPNService(HookableService):
bonafide = self.parent.getServiceNamed('bonafide')
config = yield bonafide.do_provider_read(provider, 'eip')
- sorted_gateways = self._gateways(config).select_gateways()
+ sorted_gateways = GatewaySelector(
+ config.gateways, config.locations,
+ preferred={'cc': self._cco, 'loc': self._loc}
+ ).select_gateways()
extra_flags = config.openvpn_configuration
@@ -231,23 +265,6 @@ class VPNService(HookableService):
provider, remotes, cert_path, key_path, ca_path, extra_flags)
self._firewall = FirewallManager(remotes)
- def _gateways(self, config):
- try:
- _cco = self.parent.get_config('vpn_prefs', 'countries', "")
- pref_cco = json.loads(_cco)
- except ValueError:
- pref_cco = []
- try:
- _loc = self.parent.get_config('vpn_prefs', 'locations', "")
- pref_loc = json.loads(_loc)
- except ValueError:
- pref_loc = []
-
- return GatewaySelector(
- config.gateways, config.locations,
- preferred={'cc': pref_cco, 'loc': pref_loc}
- )
-
def _cert_expires(self, provider):
path = os.path.join(
self._basepath, "leap", "providers", provider,
diff --git a/ui/app/lib/bitmask.js b/ui/app/lib/bitmask.js
index bfdf0501..7a97319b 100644
--- a/ui/app/lib/bitmask.js
+++ b/ui/app/lib/bitmask.js
@@ -289,6 +289,46 @@ var bitmask = function(){
uninstall: function() {
return call(['vpn', 'uninstall'])
}
+
+ /**
+ * List VPN gateways
+ *
+ * They will be sorted in the order that they will be used
+ *
+ * @return {Promise<{provider_name: [{'name': string,
+ * 'country_code': string,
+ * 'location': string,
+ * ...}]}>
+ */
+ list: function() {
+ return call(['vpn', 'list'])
+ }
+
+ /**
+ * Get/set the location preference for the gateways
+ *
+ * @param {list<strings>} Order of preference of locations.
+ * If it's missing it will return the existing location list
+ */
+ locations: function(locations) {
+ if (typeof locations !== 'list') {
+ locations = [];
+ }
+ return call(['vpn', 'locations'].concat(locations))
+ }
+
+ /**
+ * Get/set the country preference for the gateways
+ *
+ * @param {list<strings>} Order of preference of countries.
+ * If it's missing it will return the existing country list
+ */
+ countries: function(countries) {
+ if (typeof countries !== 'list') {
+ countries = [];
+ }
+ return call(['vpn', 'countries'].concat(countries))
+ }
},
mail: {