diff options
Diffstat (limited to 'src/leap/eip')
-rw-r--r-- | src/leap/eip/checks.py | 17 | ||||
-rw-r--r-- | src/leap/eip/config.py | 4 | ||||
-rw-r--r-- | src/leap/eip/exceptions.py | 7 | ||||
-rw-r--r-- | src/leap/eip/openvpnconnection.py | 15 | ||||
-rw-r--r-- | src/leap/eip/specs.py | 148 | ||||
-rw-r--r-- | src/leap/eip/tests/data.py | 9 | ||||
-rw-r--r-- | src/leap/eip/tests/test_checks.py | 30 | ||||
-rw-r--r-- | src/leap/eip/tests/test_config.py | 14 | ||||
-rw-r--r-- | src/leap/eip/tests/test_openvpnconnection.py | 12 |
9 files changed, 160 insertions, 96 deletions
diff --git a/src/leap/eip/checks.py b/src/leap/eip/checks.py index b68ee23a..f739c3e8 100644 --- a/src/leap/eip/checks.py +++ b/src/leap/eip/checks.py @@ -155,6 +155,9 @@ class ProviderCertChecker(object): # verify=verify # Workaround for #638. return to verification # when That's done!!! + + # XXX HOOK SRP here... + # will have to be more generic in the future. req = self.fetcher.get(uri, verify=False) req.raise_for_status() except requests.exceptions.SSLError: @@ -180,7 +183,7 @@ class ProviderCertChecker(object): valid = exists() and valid_pemfile() and not_expired() if not valid: if do_raise: - raise Exception('missing cert') + raise Exception('missing valid cert') else: return False return True @@ -196,7 +199,9 @@ class ProviderCertChecker(object): with open(certfile) as cf: cert_s = cf.read() cert = crypto.X509Certificate(cert_s) - return cert.activation_time < now() < cert.expiration_time + from_ = time.gmtime(cert.activation_time) + to_ = time.gmtime(cert.expiration_time) + return from_ < now() < to_ def is_valid_pemfile(self, cert_s=None): """ @@ -316,7 +321,7 @@ class EIPConfigChecker(object): This is catched by ui and runs FirstRunWizard (MVS+) """ if config is None: - config = self.eipconfig.get_config() + config = self.eipconfig.config logger.debug('checking default provider') provider = config.get('provider', None) if provider is None: @@ -340,7 +345,7 @@ class EIPConfigChecker(object): logger.debug('(fetching def skipped)') return True if config is None: - config = self.defaultprovider.get_config() + config = self.defaultprovider.config if uri is None: domain = config.get('provider', None) uri = self._get_provider_definition_uri(domain=domain) @@ -357,7 +362,7 @@ class EIPConfigChecker(object): if skip_download: return True if config is None: - config = self.eipserviceconfig.get_config() + config = self.eipserviceconfig.config if uri is None: domain = config.get('provider', None) uri = self._get_eip_service_uri(domain=domain) @@ -368,7 +373,7 @@ class EIPConfigChecker(object): def check_complete_eip_config(self, config=None): # TODO check for gateway if config is None: - config = self.eipconfig.get_config() + config = self.eipconfig.config try: 'trying assertions' assert 'provider' in config diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 082cc24d..ef0f52b4 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -61,8 +61,10 @@ def get_eip_gateway(): """ placeholder = "testprovider.example.org" eipconfig = EIPConfig() + #import ipdb;ipdb.set_trace() eipconfig.load() - conf = eipconfig.get_config() + conf = eipconfig.config + primary_gateway = conf.get('primary_gateway', None) if not primary_gateway: return placeholder diff --git a/src/leap/eip/exceptions.py b/src/leap/eip/exceptions.py index 24c9bfe8..11bfd620 100644 --- a/src/leap/eip/exceptions.py +++ b/src/leap/eip/exceptions.py @@ -92,6 +92,13 @@ class LeapBadConfigFetchedError(Warning): message = "provider sent a malformed json file" usermessage = "an error occurred during configuratio of leap services" + +class OpenVPNAlreadyRunning(EIPClientError): + message = "Another OpenVPN Process is already running." + usermessage = ("Another OpenVPN Process has been detected." + "Please close it before starting leap-client") + + # # errors still needing some love # diff --git a/src/leap/eip/openvpnconnection.py b/src/leap/eip/openvpnconnection.py index f4d1c449..a835ead9 100644 --- a/src/leap/eip/openvpnconnection.py +++ b/src/leap/eip/openvpnconnection.py @@ -3,6 +3,7 @@ OpenVPN Connection """ from __future__ import (print_function) import logging +import psutil import socket import time from functools import partial @@ -87,6 +88,7 @@ to be triggered for each one of them. def run_openvpn_checks(self): logger.debug('running openvpn checks') + self._check_if_running_instance() self._set_ovpn_command() self._check_vpn_keys() @@ -156,9 +158,20 @@ to be triggered for each one of them. raise eip_exceptions.EIPNoCommandError if self.subp is not None: logger.debug('cowardly refusing to launch subprocess again') - return + self._launch_openvpn() + def _check_if_running_instance(self): + """ + check if openvpn is already running + """ + for process in psutil.get_process_list(): + if process.name == "openvpn": + logger.debug('an openvpn instance is already running.') + raise eip_exceptions.OpenVPNAlreadyRunning + + logger.debug('no openvpn instance found.') + def cleanup(self): """ terminates child subprocess diff --git a/src/leap/eip/specs.py b/src/leap/eip/specs.py index 2391e919..1a670b0e 100644 --- a/src/leap/eip/specs.py +++ b/src/leap/eip/specs.py @@ -8,7 +8,7 @@ PROVIDER_CA_CERT = __branding.get( 'provider_ca_file', 'testprovider-ca-cert.pem') -provider_ca_path = lambda: unicode(os.path.join( +provider_ca_path = lambda: str(os.path.join( baseconfig.get_default_provider_path(), 'keys', 'ca', PROVIDER_CA_CERT @@ -24,78 +24,86 @@ client_cert_path = lambda: unicode(os.path.join( )) eipconfig_spec = { - 'provider': { - 'type': unicode, - 'default': u"%s" % PROVIDER_DOMAIN, - 'required': True, - }, - 'transport': { - 'type': unicode, - 'default': u"openvpn", - }, - 'openvpn_protocol': { - 'type': unicode, - 'default': u"tcp" - }, - 'openvpn_port': { - 'type': int, - 'default': 80 - }, - 'openvpn_ca_certificate': { - 'type': unicode, # path - 'default': provider_ca_path - }, - 'openvpn_client_certificate': { - 'type': unicode, # path - 'default': client_cert_path - }, - 'connect_on_login': { - 'type': bool, - 'default': True - }, - 'block_cleartext_traffic': { - 'type': bool, - 'default': True - }, - 'primary_gateway': { - 'type': unicode, - 'default': u"turkey", - 'required': True - }, - 'secondary_gateway': { - 'type': unicode, - 'default': u"france" - }, - 'management_password': { - 'type': unicode + 'description': 'sample eipconfig', + 'type': 'object', + 'properties': { + 'provider': { + 'type': unicode, + 'default': u"%s" % PROVIDER_DOMAIN, + 'required': True, + }, + 'transport': { + 'type': unicode, + 'default': u"openvpn", + }, + 'openvpn_protocol': { + 'type': unicode, + 'default': u"tcp" + }, + 'openvpn_port': { + 'type': int, + 'default': 80 + }, + 'openvpn_ca_certificate': { + 'type': unicode, # path + 'default': provider_ca_path + }, + 'openvpn_client_certificate': { + 'type': unicode, # path + 'default': client_cert_path + }, + 'connect_on_login': { + 'type': bool, + 'default': True + }, + 'block_cleartext_traffic': { + 'type': bool, + 'default': True + }, + 'primary_gateway': { + 'type': unicode, + 'default': u"turkey", + #'required': True + }, + 'secondary_gateway': { + 'type': unicode, + 'default': u"france" + }, + 'management_password': { + 'type': unicode + } } } eipservice_config_spec = { - 'serial': { - 'type': int, - 'required': True, - 'default': 1 - }, - 'version': { - 'type': unicode, - 'required': True, - 'default': "0.1.0" - }, - 'capabilities': { - 'type': dict, - 'default': { - "transport": ["openvpn"], - "ports": ["80", "53"], - "protocols": ["udp", "tcp"], - "static_ips": True, - "adblock": True} - }, - 'gateways': { - 'type': list, - 'default': [{"country_code": "us", - "label": {"en":"west"}, - "capabilities": {}, - "hosts": ["1.2.3.4", "1.2.3.5"]}] + 'description': 'sample eip service config', + 'type': 'object', + 'properties': { + 'serial': { + 'type': int, + 'required': True, + 'default': 1 + }, + 'version': { + 'type': unicode, + 'required': True, + 'default': "0.1.0" + }, + 'capabilities': { + 'type': dict, + 'default': { + "transport": ["openvpn"], + "ports": ["80", "53"], + "protocols": ["udp", "tcp"], + "static_ips": True, + "adblock": True} + }, + 'gateways': { + 'type': list, + 'default': [{"country_code": "us", + "label": {"en":"west"}, + "capabilities": {}, + "hosts": ["1.2.3.4", "1.2.3.5"]}] + } } } diff --git a/src/leap/eip/tests/data.py b/src/leap/eip/tests/data.py index 9bf86540..43df2013 100644 --- a/src/leap/eip/tests/data.py +++ b/src/leap/eip/tests/data.py @@ -7,7 +7,7 @@ from leap import __branding PROVIDER = __branding.get('provider_domain') -EIP_SAMPLE_JSON = { +EIP_SAMPLE_CONFIG = { "provider": "%s" % PROVIDER, "transport": "openvpn", "openvpn_protocol": "tcp", @@ -38,9 +38,10 @@ EIP_SAMPLE_SERVICE = { "adblock": True }, "gateways": [ - {"country_code": "us", - "label": {"en":"west"}, + {"country_code": "tr", + "name": "turkey", + "label": {"en":"Ankara, Turkey"}, "capabilities": {}, - "hosts": ["1.2.3.4", "1.2.3.5"]}, + "hosts": ["94.103.43.4"]} ] } diff --git a/src/leap/eip/tests/test_checks.py b/src/leap/eip/tests/test_checks.py index 06133825..58ce473f 100644 --- a/src/leap/eip/tests/test_checks.py +++ b/src/leap/eip/tests/test_checks.py @@ -11,6 +11,8 @@ import urlparse from mock import (patch, Mock) +import jsonschema +#import ping import requests from leap.base import config as baseconfig @@ -89,12 +91,12 @@ class EIPCheckTest(BaseLeapTest): # force re-evaluation of the paths # small workaround for evaluating home dirs correctly - EIP_SAMPLE_JSON = copy.copy(testdata.EIP_SAMPLE_JSON) - EIP_SAMPLE_JSON['openvpn_client_certificate'] = \ + EIP_SAMPLE_CONFIG = copy.copy(testdata.EIP_SAMPLE_CONFIG) + EIP_SAMPLE_CONFIG['openvpn_client_certificate'] = \ eipspecs.client_cert_path() - EIP_SAMPLE_JSON['openvpn_ca_certificate'] = \ + EIP_SAMPLE_CONFIG['openvpn_ca_certificate'] = \ eipspecs.provider_ca_path() - self.assertEqual(deserialized, EIP_SAMPLE_JSON) + self.assertEqual(deserialized, EIP_SAMPLE_CONFIG) # TODO: shold ALSO run validation methods. @@ -111,16 +113,20 @@ class EIPCheckTest(BaseLeapTest): # ok. now, messing with real files... # blank out default_provider - sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_CONFIG) sampleconfig['provider'] = None eipcfg_path = checker.eipconfig.filename with open(eipcfg_path, 'w') as fp: json.dump(sampleconfig, fp) - with self.assertRaises(eipexceptions.EIPMissingDefaultProvider): + #with self.assertRaises(eipexceptions.EIPMissingDefaultProvider): + # XXX we should catch this as one of our errors, but do not + # see how to do it quickly. + with self.assertRaises(jsonschema.ValidationError): + #import ipdb;ipdb.set_trace() checker.eipconfig.load(fromfile=eipcfg_path) checker.check_is_there_default_provider() - sampleconfig = testdata.EIP_SAMPLE_JSON + sampleconfig = testdata.EIP_SAMPLE_CONFIG #eipcfg_path = checker._get_default_eipconfig_path() with open(eipcfg_path, 'w') as fp: json.dump(sampleconfig, fp) @@ -132,7 +138,7 @@ class EIPCheckTest(BaseLeapTest): mocked_get.return_value.status_code = 200 mocked_get.return_value.json = DEFAULT_PROVIDER_DEFINITION checker = eipchecks.EIPConfigChecker(fetcher=requests) - sampleconfig = testdata.EIP_SAMPLE_JSON + sampleconfig = testdata.EIP_SAMPLE_CONFIG checker.fetch_definition(config=sampleconfig) fn = os.path.join(baseconfig.get_default_provider_path(), @@ -150,22 +156,22 @@ class EIPCheckTest(BaseLeapTest): mocked_get.return_value.status_code = 200 mocked_get.return_value.json = testdata.EIP_SAMPLE_SERVICE checker = eipchecks.EIPConfigChecker(fetcher=requests) - sampleconfig = testdata.EIP_SAMPLE_JSON + sampleconfig = testdata.EIP_SAMPLE_CONFIG checker.fetch_eip_service_config(config=sampleconfig) def test_check_complete_eip_config(self): checker = eipchecks.EIPConfigChecker() with self.assertRaises(eipexceptions.EIPConfigurationError): - sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_CONFIG) sampleconfig['provider'] = None checker.check_complete_eip_config(config=sampleconfig) with self.assertRaises(eipexceptions.EIPConfigurationError): - sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_CONFIG) del sampleconfig['provider'] checker.check_complete_eip_config(config=sampleconfig) # normal case - sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_CONFIG) checker.check_complete_eip_config(config=sampleconfig) diff --git a/src/leap/eip/tests/test_config.py b/src/leap/eip/tests/test_config.py index f9f963dc..6759b522 100644 --- a/src/leap/eip/tests/test_config.py +++ b/src/leap/eip/tests/test_config.py @@ -12,7 +12,7 @@ except ImportError: #from leap.eip import config as eip_config from leap import __branding as BRANDING from leap.eip import config as eipconfig -from leap.eip.tests.data import EIP_SAMPLE_SERVICE +from leap.eip.tests.data import EIP_SAMPLE_CONFIG, EIP_SAMPLE_SERVICE from leap.testing.basetest import BaseLeapTest from leap.util.fileutil import mkdir_p @@ -47,13 +47,21 @@ class EIPConfigTest(BaseLeapTest): os.chmod(tfile, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) def write_sample_eipservice(self): - conf = eipconfig.EIPConfig() + conf = eipconfig.EIPServiceConfig() folder, f = os.path.split(conf.filename) if not os.path.isdir(folder): mkdir_p(folder) with open(conf.filename, 'w') as fd: fd.write(json.dumps(EIP_SAMPLE_SERVICE)) + def write_sample_eipconfig(self): + conf = eipconfig.EIPConfig() + folder, f = os.path.split(conf.filename) + if not os.path.isdir(folder): + mkdir_p(folder) + with open(conf.filename, 'w') as fd: + fd.write(json.dumps(EIP_SAMPLE_CONFIG)) + def get_expected_openvpn_args(self): args = [] username = self.get_username() @@ -123,6 +131,8 @@ class EIPConfigTest(BaseLeapTest): def test_build_ovpn_command_empty_config(self): self.touch_exec() self.write_sample_eipservice() + self.write_sample_eipconfig() + from leap.eip import config as eipconfig from leap.util.fileutil import which path = os.environ['PATH'] diff --git a/src/leap/eip/tests/test_openvpnconnection.py b/src/leap/eip/tests/test_openvpnconnection.py index 885c80b3..61769f04 100644 --- a/src/leap/eip/tests/test_openvpnconnection.py +++ b/src/leap/eip/tests/test_openvpnconnection.py @@ -1,6 +1,7 @@ import logging import os import platform +import psutil import shutil #import socket @@ -16,6 +17,7 @@ from mock import Mock, patch # MagicMock from leap.eip import config as eipconfig from leap.eip import openvpnconnection +from leap.eip import exceptions as eipexceptions from leap.eip.udstelnet import UDSTelnet from leap.testing.basetest import BaseLeapTest @@ -73,6 +75,16 @@ class OpenVPNConnectionTest(BaseLeapTest): # tests # + def test_detect_vpn(self): + openvpn_connection = openvpnconnection.OpenVPNConnection() + with patch.object(psutil, "get_process_list") as mocked_psutil: + with self.assertRaises(eipexceptions.OpenVPNAlreadyRunning): + mocked_process = Mock() + mocked_process.name = "openvpn" + mocked_psutil.return_value = [mocked_process] + openvpn_connection._check_if_running_instance() + openvpn_connection._check_if_running_instance() + @unittest.skipIf(_system == "Windows", "lin/mac only") def test_lin_mac_default_init(self): """ |