summaryrefslogtreecommitdiff
path: root/src/leap/eip
diff options
context:
space:
mode:
authorkali <kali@leap.se>2012-09-18 22:55:45 +0900
committerkali <kali@leap.se>2012-09-18 22:55:45 +0900
commit89735a5fd3c81e8aba3cb7b1d4836c1bf1e8c098 (patch)
treea8a00856a7ee856cb08f263d613ac038f82043fd /src/leap/eip
parent0d35f2a82bf15504ace2135af3e0c66ae1c16874 (diff)
cert verification and malformed json checks
Diffstat (limited to 'src/leap/eip')
-rw-r--r--src/leap/eip/checks.py65
-rw-r--r--src/leap/eip/eipconnection.py26
-rw-r--r--src/leap/eip/exceptions.py15
3 files changed, 83 insertions, 23 deletions
diff --git a/src/leap/eip/checks.py b/src/leap/eip/checks.py
index aea5a5d7..b55f5827 100644
--- a/src/leap/eip/checks.py
+++ b/src/leap/eip/checks.py
@@ -9,6 +9,8 @@ import netifaces
import ping
import requests
+from leap import __branding as BRANDING
+from leap import certs
from leap.base import constants as baseconstants
from leap.base import providers
from leap.eip import config as eipconfig
@@ -20,6 +22,11 @@ from leap.util.fileutil import mkdir_p
logger = logging.getLogger(name=__name__)
"""
+ProviderCertChecker
+-------------------
+Checks on certificates. To be moved to base.
+docs TBD
+
EIPConfigChecker
----------
It is used from the eip conductor (a instance of EIPConnection that is
@@ -36,14 +43,15 @@ LeapNetworkChecker
------------------
Network checks. To be moved to base.
docs TBD
-
-ProviderCertChecker
--------------------
-Checks on certificates.
-docs TBD
"""
+def get_ca_cert():
+ ca_file = BRANDING.get('provider_ca_file')
+ if ca_file:
+ return certs.where(ca_file)
+
+
class LeapNetworkChecker(object):
"""
all network related checks
@@ -67,6 +75,7 @@ class LeapNetworkChecker(object):
# XXX we probably should raise an exception here?
# unless we use this as smoke test
try:
+ # XXX remove this hardcoded random ip
requests.get('http://216.172.161.165')
except (requests.HTTPError, requests.RequestException) as e:
self.error = e.message
@@ -124,7 +133,7 @@ class ProviderCertChecker(object):
"""
def __init__(self, fetcher=requests):
self.fetcher = fetcher
- self.cacert = None
+ self.cacert = get_ca_cert()
def run_all(self, checker=None, skip_download=False):
if not checker:
@@ -159,25 +168,34 @@ class ProviderCertChecker(object):
raise NotImplementedError
def is_there_provider_ca(self):
- # XXX fake it till you make it! :P
+ from leap import certs
+ logger.debug('do we have provider_ca?')
+ cacert_path = BRANDING.get('provider_ca_file', None)
+ if not cacert_path:
+ logger.debug('False')
+ return False
+ self.cacert = certs.where(cacert_path)
+ logger.debug('True')
return True
- # enable this when we have
- # a custom "branded" bundle
- # certs package.
- try:
- from leap.custom import certs
- except ImportError:
- raise
- self.cacert = certs.where('cacert.pem')
-
def is_https_working(self, uri=None, verify=True):
+ if uri is None:
+ uri = self._get_root_uri()
# XXX raise InsecureURI or something better
+ logger.debug('is https working?')
+ logger.debug('uri: %s', uri)
+ #import ipdb;ipdb.set_trace()
assert uri.startswith('https')
if verify is True and self.cacert is not None:
+ logger.debug('verify cert: %s', self.cacert)
verify = self.cacert
- self.fetcher.get(uri, verify=verify)
- return True
+ try:
+ self.fetcher.get(uri, verify=verify)
+ except requests.exceptions.SSLError:
+ raise eipexceptions.EIPBadCertError
+ else:
+ logger.debug('True')
+ return True
def check_new_cert_needed(self, skip_download=False):
if not self.is_cert_valid(do_raise=False):
@@ -256,7 +274,11 @@ class ProviderCertChecker(object):
raise
return True
+ def _get_root_uri(self):
+ return u"https://%s/" % baseconstants.DEFAULT_PROVIDER
+
def _get_client_cert_uri(self):
+ # XXX get the whole thing from constants
return "https://%s/cert/get" % (baseconstants.DEFAULT_PROVIDER)
def _get_client_cert_path(self):
@@ -370,7 +392,12 @@ class EIPConfigChecker(object):
domain = config.get('provider', None)
uri = self._get_provider_definition_uri(domain=domain)
- self.defaultprovider.load(from_uri=uri, fetcher=self.fetcher)
+ # FIXME! Pass ca path verify!!!
+ self.defaultprovider.load(
+ from_uri=uri,
+ fetcher=self.fetcher,
+ verify=False)
+ #import ipdb;ipdb.set_trace()
self.defaultprovider.save()
def fetch_eip_service_config(self, skip_download=False,
diff --git a/src/leap/eip/eipconnection.py b/src/leap/eip/eipconnection.py
index d1c84b2a..4e240f16 100644
--- a/src/leap/eip/eipconnection.py
+++ b/src/leap/eip/eipconnection.py
@@ -6,6 +6,7 @@ import logging
import Queue
import sys
+from leap.eip.checks import ProviderCertChecker
from leap.eip.checks import EIPConfigChecker
from leap.eip import config as eipconfig
from leap.eip import exceptions as eip_exceptions
@@ -22,7 +23,10 @@ class EIPConnection(OpenVPNConnection):
Status updates (connected, bandwidth, etc) are signaled to the GUI.
"""
- def __init__(self, config_checker=EIPConfigChecker, *args, **kwargs):
+ def __init__(self,
+ provider_cert_checker=ProviderCertChecker,
+ config_checker=EIPConfigChecker,
+ *args, **kwargs):
self.settingsfile = kwargs.get('settingsfile', None)
self.logfile = kwargs.get('logfile', None)
@@ -30,6 +34,8 @@ class EIPConnection(OpenVPNConnection):
status_signals = kwargs.pop('status_signals', None)
self.status = EIPConnectionStatus(callbacks=status_signals)
+
+ self.provider_cert_checker = provider_cert_checker()
self.config_checker = config_checker()
host = eipconfig.get_socket_path()
@@ -45,12 +51,25 @@ class EIPConnection(OpenVPNConnection):
run all eip checks previous to attempting a connection
"""
logger.debug('running conductor checks')
+
+ def push_err(exc):
+ # keep the original traceback!
+ exc_traceback = sys.exc_info()[2]
+ self.error_queue.put((exc, exc_traceback))
+
+ try:
+ # network (1)
+ self.provider_cert_checker.run_all()
+ except Exception as exc:
+ push_err(exc)
try:
self.config_checker.run_all(skip_download=skip_download)
+ except Exception as exc:
+ push_err(exc)
+ try:
self.run_openvpn_checks()
except Exception as exc:
- exc_traceback = sys.exc_info()[2]
- self.error_queue.put((exc, exc_traceback))
+ push_err(exc)
def connect(self):
"""
@@ -84,6 +103,7 @@ class EIPConnection(OpenVPNConnection):
# XXX this separation does not
# make sense anymore after having
# merged Connection and Manager classes.
+ # XXX GET RID OF THIS FUNCTION HERE!
try:
state = self.get_connection_state()
except eip_exceptions.ConnectionRefusedError:
diff --git a/src/leap/eip/exceptions.py b/src/leap/eip/exceptions.py
index 467be7fe..f048621f 100644
--- a/src/leap/eip/exceptions.py
+++ b/src/leap/eip/exceptions.py
@@ -40,6 +40,8 @@ class EIPClientError(Exception):
base EIPClient exception
"""
critical = False
+ failfirst = False
+ warning = False
class CriticalError(EIPClientError):
@@ -54,7 +56,7 @@ class Warning(EIPClientError):
"""
just that, warnings
"""
- pass
+ warning = True
class EIPNoPolkitAuthAgentAvailable(CriticalError):
@@ -81,10 +83,21 @@ class EIPNoCommandError(EIPClientError):
"<br/>(Might be a permissions problem)")
+class EIPBadCertError(Warning):
+ # XXX this should be critical and fail close
+ message = "cert verification failed"
+ usermessage = "there is a problem with provider certificate"
+
+
+class LeapBadConfigFetchedError(Warning):
+ message = "provider sent a malformed json file"
+ usermessage = "an error occurred during configuratio of leap services"
+
#
# errors still needing some love
#
+
class EIPInitNoKeyFileError(CriticalError):
message = "No vpn keys found in the expected path"
usermessage = "We could not find your eip certs in the expected path"