From 808f9d3542e21c819beb8fe72224f000ae2e019c Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Thu, 31 Aug 2017 10:58:59 +0200 Subject: [feat] expose an API to set/get/list gateway preferences - Related: #9010 --- src/leap/bitmask/cli/vpn.py | 2 +- src/leap/bitmask/core/dispatcher.py | 14 +++++++++ src/leap/bitmask/core/service.py | 3 +- src/leap/bitmask/vpn/service.py | 57 ++++++++++++++++++++++++------------- 4 files changed, 54 insertions(+), 22 deletions(-) (limited to 'src/leap') 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, -- cgit v1.2.3