diff options
Diffstat (limited to 'src/leap/bitmask/services/eip')
-rw-r--r-- | src/leap/bitmask/services/eip/__init__.py | 42 | ||||
-rw-r--r-- | src/leap/bitmask/services/eip/connection.py | 48 | ||||
-rw-r--r-- | src/leap/bitmask/services/eip/eipbootstrapper.py | 94 | ||||
-rw-r--r-- | src/leap/bitmask/services/eip/eipconfig.py | 19 | ||||
-rw-r--r-- | src/leap/bitmask/services/eip/providerbootstrapper.py | 6 | ||||
-rw-r--r-- | src/leap/bitmask/services/eip/vpnlaunchers.py | 68 | ||||
-rw-r--r-- | src/leap/bitmask/services/eip/vpnprocess.py | 3 |
7 files changed, 147 insertions, 133 deletions
diff --git a/src/leap/bitmask/services/eip/__init__.py b/src/leap/bitmask/services/eip/__init__.py index e69de29b..dd010027 100644 --- a/src/leap/bitmask/services/eip/__init__.py +++ b/src/leap/bitmask/services/eip/__init__.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# __init__.py +# Copyright (C) 2013 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/>. +""" +leap.bitmask.services.eip module initialization +""" +import os +import tempfile + +from leap.bitmask.platform_init import IS_WIN + + +def get_openvpn_management(): + """ + Returns the socket and port to be used for VPN + + :rtype: tuple (str, str) (host, port) + """ + if IS_WIN: + host = "localhost" + port = "9876" + else: + # XXX cleanup this on exit too + # XXX atexit.register ? + host = os.path.join(tempfile.mkdtemp(prefix="leap-tmp"), + 'openvpn.socket') + port = "unix" + + return host, port diff --git a/src/leap/bitmask/services/eip/connection.py b/src/leap/bitmask/services/eip/connection.py new file mode 100644 index 00000000..5f05ba07 --- /dev/null +++ b/src/leap/bitmask/services/eip/connection.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# connection.py +# Copyright (C) 2013 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/>. +""" +EIP Connection +""" +from PySide import QtCore + +from leap.bitmask.services.connections import AbstractLEAPConnection + + +class EIPConnectionSignals(QtCore.QObject): + """ + Qt Signals used by EIPConnection + """ + # commands + do_connect_signal = QtCore.Signal() + do_disconnect_signal = QtCore.Signal() + + # intermediate stages + # this is currently binded to mainwindow._start_eip + connecting_signal = QtCore.Signal() + # this is currently binded to mainwindow._stop_eip + disconnecting_signal = QtCore.Signal() + + connected_signal = QtCore.Signal() + disconnected_signal = QtCore.Signal() + + connection_died_signal = QtCore.Signal() + + +class EIPConnection(AbstractLEAPConnection): + + def __init__(self): + self._qtsigs = EIPConnectionSignals() diff --git a/src/leap/bitmask/services/eip/eipbootstrapper.py b/src/leap/bitmask/services/eip/eipbootstrapper.py index 6393e53a..885c4420 100644 --- a/src/leap/bitmask/services/eip/eipbootstrapper.py +++ b/src/leap/bitmask/services/eip/eipbootstrapper.py @@ -14,25 +14,23 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. - """ EIP bootstrapping """ - import logging import os from PySide import QtCore from leap.bitmask.config.providerconfig import ProviderConfig -from leap.bitmask.crypto.srpauth import SRPAuth -from leap.bitmask.services.eip.eipconfig import EIPConfig -from leap.bitmask.util.request_helpers import get_content -from leap.bitmask.util.constants import REQUEST_TIMEOUT +from leap.bitmask.crypto.certs import download_client_cert +from leap.bitmask.services import download_service_config from leap.bitmask.services.abstractbootstrapper import AbstractBootstrapper -from leap.common import certs +from leap.bitmask.services.eip.eipconfig import EIPConfig +from leap.common import certs as leap_certs +from leap.bitmask.util import get_path_prefix from leap.common.check import leap_assert, leap_assert_type -from leap.common.files import check_and_fix_urw_only, get_mtime, mkdir_p +from leap.common.files import check_and_fix_urw_only logger = logging.getLogger(__name__) @@ -63,50 +61,15 @@ class EIPBootstrapper(AbstractBootstrapper): leap_assert(self._provider_config, "We need a provider configuration!") - logger.debug("Downloading EIP config for %s" % (self._provider_config.get_domain(),)) - api_version = self._provider_config.get_api_version() self._eip_config = EIPConfig() - self._eip_config.set_api_version(api_version) - - headers = {} - mtime = get_mtime(os.path.join(self._eip_config - .get_path_prefix(), - "leap", - "providers", - self._provider_config.get_domain(), - "eip-service.json")) - - if self._download_if_needed and mtime: - headers['if-modified-since'] = mtime - - # there is some confusion with this uri, - # it's in 1/config/eip, config/eip and config/1/eip... - config_uri = "%s/%s/config/eip-service.json" % ( - self._provider_config.get_api_uri(), - api_version) - logger.debug('Downloading eip config from: %s' % config_uri) - - res = self._session.get(config_uri, - verify=self._provider_config - .get_ca_cert_path(), - headers=headers, - timeout=REQUEST_TIMEOUT) - res.raise_for_status() - - # Not modified - if res.status_code == 304: - logger.debug("EIP definition has not been modified") - else: - eip_definition, mtime = get_content(res) - - self._eip_config.load(data=eip_definition, mtime=mtime) - self._eip_config.save(["leap", - "providers", - self._provider_config.get_domain(), - "eip-service.json"]) + download_service_config( + self._provider_config, + self._eip_config, + self._session, + self._download_if_needed) def _download_client_certificates(self, *args): """ @@ -124,40 +87,17 @@ class EIPBootstrapper(AbstractBootstrapper): # For re-download if something is wrong with the cert self._download_if_needed = self._download_if_needed and \ - not certs.should_redownload(client_cert_path) + not leap_certs.should_redownload(client_cert_path) if self._download_if_needed and \ - os.path.exists(client_cert_path): + os.path.isfile(client_cert_path): check_and_fix_urw_only(client_cert_path) return - srp_auth = SRPAuth(self._provider_config) - session_id = srp_auth.get_session_id() - cookies = None - if session_id: - cookies = {"_session_id": session_id} - cert_uri = "%s/%s/cert" % ( - self._provider_config.get_api_uri(), - self._provider_config.get_api_version()) - logger.debug('getting cert from uri: %s' % cert_uri) - res = self._session.get(cert_uri, - verify=self._provider_config - .get_ca_cert_path(), - cookies=cookies, - timeout=REQUEST_TIMEOUT) - res.raise_for_status() - client_cert = res.content - - if not certs.is_valid_pemfile(client_cert): - raise Exception(self.tr("The downloaded certificate is not a " - "valid PEM file")) - - mkdir_p(os.path.dirname(client_cert_path)) - - with open(client_cert_path, "w") as f: - f.write(client_cert) - - check_and_fix_urw_only(client_cert_path) + download_client_cert( + self._provider_config, + client_cert_path, + self._session) def run_eip_setup_checks(self, provider_config, diff --git a/src/leap/bitmask/services/eip/eipconfig.py b/src/leap/bitmask/services/eip/eipconfig.py index 1cb7419e..7d8995b4 100644 --- a/src/leap/bitmask/services/eip/eipconfig.py +++ b/src/leap/bitmask/services/eip/eipconfig.py @@ -14,7 +14,6 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. - """ Provider configuration """ @@ -26,9 +25,10 @@ import time import ipaddr from leap.bitmask.config.providerconfig import ProviderConfig +from leap.bitmask.services import ServiceConfig from leap.bitmask.services.eip.eipspec import get_schema +from leap.bitmask.util import get_path_prefix from leap.common.check import leap_assert, leap_assert_type -from leap.common.config.baseconfig import BaseConfig logger = logging.getLogger(__name__) @@ -144,15 +144,17 @@ class VPNGatewaySelector(object): return -local_offset / 3600 -class EIPConfig(BaseConfig): +class EIPConfig(ServiceConfig): """ Provider configuration abstraction class """ + _service_name = "eip" + OPENVPN_ALLOWED_KEYS = ("auth", "cipher", "tls-cipher") OPENVPN_CIPHERS_REGEX = re.compile("[A-Z0-9\-]+") def __init__(self): - BaseConfig.__init__(self) + ServiceConfig.__init__(self) self._api_version = None def _get_schema(self): @@ -236,13 +238,10 @@ class EIPConfig(BaseConfig): leap_assert(providerconfig, "We need a provider") leap_assert_type(providerconfig, ProviderConfig) - cert_path = os.path.join(self.get_path_prefix(), - "leap", - "providers", + cert_path = os.path.join(get_path_prefix(), + "leap", "providers", providerconfig.get_domain(), - "keys", - "client", - "openvpn.pem") + "keys", "client", "openvpn.pem") if not about_to_download: leap_assert(os.path.exists(cert_path), diff --git a/src/leap/bitmask/services/eip/providerbootstrapper.py b/src/leap/bitmask/services/eip/providerbootstrapper.py index ac3a44db..3b7c9899 100644 --- a/src/leap/bitmask/services/eip/providerbootstrapper.py +++ b/src/leap/bitmask/services/eip/providerbootstrapper.py @@ -28,6 +28,7 @@ from PySide import QtCore from leap.bitmask.config.providerconfig import ProviderConfig, MissingCACert from leap.bitmask.util.request_helpers import get_content +from leap.bitmask.util import get_path_prefix from leap.bitmask.util.constants import REQUEST_TIMEOUT from leap.bitmask.services.abstractbootstrapper import AbstractBootstrapper from leap.bitmask.provider.supportedapis import SupportedAPIs @@ -133,9 +134,8 @@ class ProviderBootstrapper(AbstractBootstrapper): headers = {} - provider_json = os.path.join( - ProviderConfig().get_path_prefix(), "leap", "providers", - self._domain, "provider.json") + provider_json = os.path.join(get_path_prefix(), "leap", "providers", + self._domain, "provider.json") mtime = get_mtime(provider_json) if self._download_if_needed and mtime: diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py index a50da8b9..daa0d81f 100644 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ b/src/leap/bitmask/services/eip/vpnlaunchers.py @@ -34,16 +34,19 @@ from abc import ABCMeta, abstractmethod from functools import partial from time import sleep +from leap.bitmask.config import flags from leap.bitmask.config.leapsettings import LeapSettings from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector from leap.bitmask.util import first +from leap.bitmask.util import get_path_prefix from leap.bitmask.util.privilege_policies import LinuxPolicyChecker from leap.bitmask.util import privilege_policies from leap.common.check import leap_assert, leap_assert_type from leap.common.files import which + logger = logging.getLogger(__name__) @@ -98,15 +101,12 @@ class VPNLauncher(object): return [] @abstractmethod - def get_vpn_env(self, providerconfig): + def get_vpn_env(self): """ Returns a dictionary with the custom env for the platform. This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - :param providerconfig: provider specific configuration - :type providerconfig: ProviderConfig - :rtype: dict """ return {} @@ -220,14 +220,13 @@ def _is_auth_agent_running(): return any(is_running) -def _try_to_launch_agent(standalone=False): +def _try_to_launch_agent(): """ Tries to launch a polkit daemon. """ env = None - if standalone is True: - env = { - "PYTHONPATH": os.path.abspath('../../../../lib/')} + if flags.STANDALONE is True: + env = {"PYTHONPATH": os.path.abspath('../../../../lib/')} try: # We need to quote the command because subprocess call # will do "sh -c 'foo'", so if we do not quoute it we'll end @@ -247,8 +246,7 @@ class LinuxVPNLauncher(VPNLauncher): PKEXEC_BIN = 'pkexec' OPENVPN_BIN = 'openvpn' OPENVPN_BIN_PATH = os.path.join( - ProviderConfig().get_path_prefix(), - "..", "apps", "eip", OPENVPN_BIN) + get_path_prefix(), "..", "apps", "eip", OPENVPN_BIN) SYSTEM_CONFIG = "/etc/leap" UP_DOWN_FILE = "resolv-update" @@ -320,7 +318,7 @@ class LinuxVPNLauncher(VPNLauncher): """ if _is_pkexec_in_system(): if not _is_auth_agent_running(): - _try_to_launch_agent(ProviderConfig.standalone) + _try_to_launch_agent() sleep(0.5) if _is_auth_agent_running(): pkexec_possibilities = which(kls.PKEXEC_BIN) @@ -397,10 +395,9 @@ class LinuxVPNLauncher(VPNLauncher): leap_assert(socket_port, "We need a socket port!") kwargs = {} - if ProviderConfig.standalone: + if flags.STANDALONE: kwargs['path_extension'] = os.path.join( - providerconfig.get_path_prefix(), - "..", "apps", "eip") + get_path_prefix(), "..", "apps", "eip") openvpn_possibilities = which(self.OPENVPN_BIN, **kwargs) @@ -423,7 +420,7 @@ class LinuxVPNLauncher(VPNLauncher): args += ['--verb', '%d' % (openvpn_verb,)] gateways = [] - leap_settings = LeapSettings(ProviderConfig.standalone) + leap_settings = LeapSettings() domain = providerconfig.get_domain() gateway_conf = leap_settings.get_selected_gateway(domain) @@ -513,23 +510,17 @@ class LinuxVPNLauncher(VPNLauncher): return [openvpn] + args - def get_vpn_env(self, providerconfig): + def get_vpn_env(self): """ Returns a dictionary with the custom env for the platform. This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - :param providerconfig: provider specific configuration - :type providerconfig: ProviderConfig - :rtype: dict """ - leap_assert(providerconfig, "We need a provider config") - leap_assert_type(providerconfig, ProviderConfig) - - return {"LD_LIBRARY_PATH": os.path.join( - providerconfig.get_path_prefix(), - "..", "lib")} + return { + "LD_LIBRARY_PATH": os.path.join(get_path_prefix(), "..", "lib") + } class DarwinVPNLauncher(VPNLauncher): @@ -664,10 +655,9 @@ class DarwinVPNLauncher(VPNLauncher): raise EIPNoTunKextLoaded kwargs = {} - if ProviderConfig.standalone: + if flags.STANDALONE: kwargs['path_extension'] = os.path.join( - providerconfig.get_path_prefix(), - "..", "apps", "eip") + get_path_prefix(), "..", "apps", "eip") openvpn_possibilities = which( self.OPENVPN_BIN, @@ -686,7 +676,7 @@ class DarwinVPNLauncher(VPNLauncher): args += ['--verb', '%d' % (openvpn_verb,)] gateways = [] - leap_settings = LeapSettings(ProviderConfig.standalone) + leap_settings = LeapSettings() domain = providerconfig.get_domain() gateway_conf = leap_settings.get_selected_gateway(domain) @@ -787,20 +777,17 @@ class DarwinVPNLauncher(VPNLauncher): return [command] + cmd_args - def get_vpn_env(self, providerconfig): + def get_vpn_env(self): """ Returns a dictionary with the custom env for the platform. This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - :param providerconfig: provider specific configuration - :type providerconfig: ProviderConfig - :rtype: dict """ - return {"DYLD_LIBRARY_PATH": os.path.join( - providerconfig.get_path_prefix(), - "..", "lib")} + return { + "DYLD_LIBRARY_PATH": os.path.join(get_path_prefix(), "..", "lib") + } class WindowsVPNLauncher(VPNLauncher): @@ -852,7 +839,7 @@ class WindowsVPNLauncher(VPNLauncher): openvpn_possibilities = which( self.OPENVPN_BIN, - path_extension=os.path.join(providerconfig.get_path_prefix(), + path_extension=os.path.join(get_path_prefix(), "..", "apps", "eip")) if len(openvpn_possibilities) == 0: @@ -869,7 +856,7 @@ class WindowsVPNLauncher(VPNLauncher): args += ['--verb', '%d' % (openvpn_verb,)] gateways = [] - leap_settings = LeapSettings(ProviderConfig.standalone) + leap_settings = LeapSettings() domain = providerconfig.get_domain() gateway_conf = leap_settings.get_selected_gateway(domain) @@ -936,15 +923,12 @@ class WindowsVPNLauncher(VPNLauncher): return [openvpn] + args - def get_vpn_env(self, providerconfig): + def get_vpn_env(self): """ Returns a dictionary with the custom env for the platform. This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - :param providerconfig: provider specific configuration - :type providerconfig: ProviderConfig - :rtype: dict """ return {} diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index a896b60c..15ac812b 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -95,6 +95,7 @@ class VPN(object): self._reactor = reactor self._qtsigs = VPNSignals() + # XXX should get it from config.flags self._openvpn_verb = kwargs.get(self.OPENVPN_VERB, None) @property @@ -536,7 +537,7 @@ class VPNManager(object): """ Return a dict containing the vpn environment to be used. """ - return self._launcher.get_vpn_env(self._providerconfig) + return self._launcher.get_vpn_env() def terminate_openvpn(self, shutdown=False): """ |