diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/crypto/srpauth.py | 22 | ||||
| -rw-r--r-- | src/leap/gui/mainwindow.py | 3 | ||||
| -rw-r--r-- | src/leap/gui/statuspanel.py | 2 | ||||
| -rw-r--r-- | src/leap/services/abstractbootstrapper.py | 7 | ||||
| -rw-r--r-- | src/leap/services/eip/eipconfig.py | 91 | ||||
| -rw-r--r-- | src/leap/services/eip/vpnlaunchers.py | 12 | ||||
| -rw-r--r-- | src/leap/util/leap_log_handler.py | 9 | 
7 files changed, 127 insertions, 19 deletions
| diff --git a/src/leap/crypto/srpauth.py b/src/leap/crypto/srpauth.py index bcd24de3..0e95ae64 100644 --- a/src/leap/crypto/srpauth.py +++ b/src/leap/crypto/srpauth.py @@ -24,6 +24,7 @@ import json  #this error is raised from requests  from simplejson.decoder import JSONDecodeError +from functools import partial  from PySide import QtCore  from twisted.internet import threads @@ -321,6 +322,9 @@ class SRPAuth(QtCore.QObject):              self.set_session_id(session_id) +        def _threader(self, cb, res, *args, **kwargs): +            return threads.deferToThread(cb, res, *args, **kwargs) +          def authenticate(self, username, password):              """              Executes the whole authentication process for a user @@ -341,10 +345,17 @@ class SRPAuth(QtCore.QObject):                                        username=username,                                        password=password) -            d.addCallback(self._start_authentication, username=username, -                          password=password) -            d.addCallback(self._process_challenge, username=username) -            d.addCallback(self._verify_session) +            d.addCallback( +                partial(self._threader, +                        self._start_authentication), +                username=username, +                password=password) +            d.addCallback( +                partial(self._threader, +                        self._process_challenge), +                username=username) +            d.addCallback(partial(self._threader, +                                  self._verify_session))              return d @@ -459,7 +470,8 @@ class SRPAuth(QtCore.QObject):          :type failure: twisted.python.failure.Failure          """          logger.error("Error logging in %s" % (failure,)) -        self.authentication_finished.emit(False, "%s" % (failure,)) +        self.authentication_finished.emit(False, "%s" % (failure.value,)) +        failure.trap(Exception)      def get_session_id(self):          return self.__instance.get_session_id() diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index c58cd4e3..80876c27 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -1149,7 +1149,8 @@ class MainWindow(QtGui.QMainWindow):          """          passed = data[self._provider_bootstrapper.PASSED_KEY]          if not passed: -            self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) +            self._login_widget.set_status( +                data[self._provider_bootstrapper.ERROR_KEY])              self._already_started_eip = False      def _eip_finished(self, exitCode): diff --git a/src/leap/gui/statuspanel.py b/src/leap/gui/statuspanel.py index 53c19e86..554903d8 100644 --- a/src/leap/gui/statuspanel.py +++ b/src/leap/gui/statuspanel.py @@ -189,7 +189,7 @@ class StatusPanelWidget(QtGui.QWidget):                                                          "it's already "                                                          "running.")))          else: -            self._set_eip_status(status) +            self.set_eip_status(status)      def set_eip_status_icon(self, status):          """ diff --git a/src/leap/services/abstractbootstrapper.py b/src/leap/services/abstractbootstrapper.py index 2cbd56bc..f0937197 100644 --- a/src/leap/services/abstractbootstrapper.py +++ b/src/leap/services/abstractbootstrapper.py @@ -22,6 +22,8 @@ import logging  import requests +from functools import partial +  from PySide import QtCore  from twisted.internet import threads  from leap.common.check import leap_assert, leap_assert_type @@ -128,6 +130,9 @@ class AbstractBootstrapper(QtCore.QObject):              logger.debug("Emitting %s" % (signal,))              signal.emit({self.PASSED_KEY: True, self.ERROR_KEY: ""}) +    def _callback_threader(self, cb, res, *args, **kwargs): +        return threads.deferToThread(cb, res, *args, **kwargs) +      def addCallbackChain(self, callbacks):          """          Creates a callback/errback chain on another thread using @@ -148,7 +153,7 @@ class AbstractBootstrapper(QtCore.QObject):              if d is None:                  d = threads.deferToThread(cb)              else: -                d.addCallback(cb) +                d.addCallback(partial(self._callback_threader, cb))              d.addErrback(self._errback, signal=sig)              d.addCallback(self._gui_notify, signal=sig)          d.addErrback(self._gui_errback) diff --git a/src/leap/services/eip/eipconfig.py b/src/leap/services/eip/eipconfig.py index 0a7d2b23..f7d03963 100644 --- a/src/leap/services/eip/eipconfig.py +++ b/src/leap/services/eip/eipconfig.py @@ -21,6 +21,8 @@ Provider configuration  import logging  import os  import re +import datetime +import time  import ipaddr @@ -32,6 +34,79 @@ from leap.services.eip.eipspec import eipservice_config_spec  logger = logging.getLogger(__name__) +class VPNGatewaySelector(object): +    """ +    VPN Gateway selector. +    """ + +    def __init__(self, eipconfig): +        ''' +        Constructor for VPNGatewaySelector. + +        :param eipconfig: a valid EIP Configuration. +        :type eipconfig: EIPConfig +        ''' +        leap_assert_type(eipconfig, EIPConfig) +        self._local_offset = 0  # defaults to GMT +        self._local_timezone = None +        self._set_local_offset() +        self._eipconfig = eipconfig + +    def _get_best_gateway(self): +        """ +        Returns index of the closest gateway, using timezones offsets. + +        :rtype: int +        """ +        best_gateway = (-1, 99)  # gateway, distance +        locations = self._eipconfig.get_locations() +        gateways = self._eipconfig.get_gateways() +        for idx, gateway in enumerate(gateways): +            gateway_offset = int(locations[gateway['location']]['timezone']) +            gateway_distance = self._get_timezone_distance(gateway_offset) +            if gateway_distance < best_gateway[1]: +                best_gateway = (idx, gateway_distance) + +        return best_gateway[0] + +    def get_best_gateway_ip(self): +        """ +        Returns the ip of the best possible gateway. + +        :rtype: An IPv4Address or IPv6Address object. +        """ +        best_gateway = self._get_best_gateway() +        gateway_ip = self._eipconfig.get_gateway_ip(best_gateway) + +        return gateway_ip + +    def _get_timezone_distance(self, offset): +        ''' +        Returns the distance between the local timezone and +        the one with offset 'offset'. + +        :param offset: the distance of a timezone to GMT. +        :type offset: int +        :returns: distance between local offset and param offset. +        :rtype: int +        ''' +        delta1 = datetime.timedelta(hours=offset) +        delta2 = self._local_offset +        diff = abs(delta1 - delta2) +        hours = diff.seconds / (60 * 60) +        return hours + +    def _set_local_offset(self): +        ''' +        Sets the distance between GMT and the local timezone. +        ''' +        local_offset = time.timezone +        if time.daylight: +            local_offset = time.altzone + +        self._local_offset = datetime.timedelta(seconds=-local_offset) + +  class EIPConfig(BaseConfig):      """      Provider configuration abstraction class @@ -56,6 +131,14 @@ class EIPConfig(BaseConfig):          # TODO: create an abstraction for gateways          return self._safe_get_value("gateways") +    def get_locations(self): +        ''' +        Returns a list of locations + +        :rtype: dict +        ''' +        return self._safe_get_value("locations") +      def get_openvpn_configuration(self):          """          Returns a dictionary containing the openvpn configuration @@ -63,8 +146,8 @@ class EIPConfig(BaseConfig):          These are sanitized with alphanumeric whitelist. -        @returns: openvpn configuration dict -        @rtype: C{dict} +        :returns: openvpn configuration dict +        :rtype: C{dict}          """          ovpncfg = self._safe_get_value("openvpn_configuration")          config = {} @@ -84,7 +167,9 @@ class EIPConfig(BaseConfig):      def get_gateway_ip(self, index=0):          """ -        Returns the ip of the gateway +        Returns the ip of the gateway. + +        :rtype: An IPv4Address or IPv6Address object.          """          gateways = self.get_gateways()          leap_assert(len(gateways) > 0, "We don't have any gateway!") diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 6c2ff006..fa2989bc 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -34,7 +34,7 @@ from functools import partial  from leap.common.check import leap_assert, leap_assert_type  from leap.common.files import which  from leap.config.providerconfig import ProviderConfig -from leap.services.eip.eipconfig import EIPConfig +from leap.services.eip.eipconfig import EIPConfig, VPNGatewaySelector  logger = logging.getLogger(__name__) @@ -228,7 +228,8 @@ class LinuxVPNLauncher(VPNLauncher):          # TODO: handle verbosity -        gateway_ip = str(eipconfig.get_gateway_ip(0)) +        gateway_selector = VPNGatewaySelector(eipconfig) +        gateway_ip = gateway_selector.get_best_gateway_ip()          logger.debug("Using gateway ip %s" % (gateway_ip,)) @@ -391,7 +392,9 @@ class DarwinVPNLauncher(VPNLauncher):          # TODO: handle verbosity -        gateway_ip = str(eipconfig.get_gateway_ip(0)) +        gateway_selector = VPNGatewaySelector(eipconfig) +        gateway_ip = gateway_selector.get_best_gateway_ip() +          logger.debug("Using gateway ip %s" % (gateway_ip,))          args += [ @@ -530,7 +533,8 @@ class WindowsVPNLauncher(VPNLauncher):          # TODO: handle verbosity -        gateway_ip = str(eipconfig.get_gateway_ip(0)) +        gateway_selector = VPNGatewaySelector(eipconfig) +        gateway_ip = gateway_selector.get_best_gateway_ip()          logger.debug("Using gateway ip %s" % (gateway_ip,)) diff --git a/src/leap/util/leap_log_handler.py b/src/leap/util/leap_log_handler.py index 5b8ae789..e5bc87e1 100644 --- a/src/leap/util/leap_log_handler.py +++ b/src/leap/util/leap_log_handler.py @@ -31,16 +31,16 @@ class LogHandler(logging.Handler):      MESSAGE_KEY = 'message'      RECORD_KEY = 'record' -    # TODO This is going to eat lots of memory after some time. -    # Should be pruned at some moment. -    _log_history = [] -      def __init__(self, qtsignal):          """          LogHander initialization.          Calls parent method and keeps a reference to the qtsignal          that will be used to fire the gui update.          """ +        # TODO This is going to eat lots of memory after some time. +        # Should be pruned at some moment. +        self._log_history = [] +          logging.Handler.__init__(self)          self._qtsignal = qtsignal @@ -85,6 +85,7 @@ class LogHandler(logging.Handler):          self._set_format(logRecord.levelname)          log = self.format(logRecord)          log_item = {self.RECORD_KEY: logRecord, self.MESSAGE_KEY: log} +        self._log_history.append(log_item)          self._qtsignal(log_item) | 
