diff options
Diffstat (limited to 'src/leap/bitmask')
-rw-r--r-- | src/leap/bitmask/keymanager/__init__.py | 99 | ||||
-rw-r--r-- | src/leap/bitmask/keymanager/keys.py | 3 | ||||
-rw-r--r-- | src/leap/bitmask/keymanager/nicknym.py | 12 | ||||
-rw-r--r-- | src/leap/bitmask/keymanager/openpgp.py | 3 | ||||
-rw-r--r-- | src/leap/bitmask/keymanager/refresher.py | 19 | ||||
-rw-r--r-- | src/leap/bitmask/mail/testing/__init__.py | 2 |
6 files changed, 39 insertions, 99 deletions
diff --git a/src/leap/bitmask/keymanager/__init__.py b/src/leap/bitmask/keymanager/__init__.py index 319be08..ed3726a 100644 --- a/src/leap/bitmask/keymanager/__init__.py +++ b/src/leap/bitmask/keymanager/__init__.py @@ -19,10 +19,8 @@ Key Manager is a Nicknym agent for LEAP client. """ import fileinput import json -import os import sys import tempfile -import urllib from urlparse import urlparse @@ -32,13 +30,13 @@ from twisted.web import client from twisted.web._responses import NOT_FOUND from leap.common import ca_bundle -from leap.common.check import leap_assert -from leap.common.decorators import memoized_method from leap.common.http import HTTPClient from leap.common.events import emit_async, catalog from leap.bitmask.keymanager import errors as keymanager_errors +from leap.bitmask.keymanager.errors import KeyNotFound from leap.bitmask.keymanager.nicknym import Nicknym +from leap.bitmask.keymanager.refresher import RandomRefreshPublicKey from leap.bitmask.keymanager.validation import ValidationLevels, can_upgrade from leap.bitmask.keymanager.openpgp import OpenPGPScheme @@ -101,7 +99,8 @@ class KeyManager(object): self._combined_ca_bundle = '' self._async_client = HTTPClient(self._combined_ca_bundle) - self._nicknym = Nicknym(self._nickserver_uri, self._ca_cert_path, self._token) + self._nicknym = Nicknym(self._nickserver_uri, + self._ca_cert_path, self._token) self.refresher = None # @@ -155,14 +154,17 @@ class KeyManager(object): except IOError as e: logger.warn("HTTP error retrieving key: %r" % (e,)) logger.warn("%s" % (content,)) - raise keymanager_errors.KeyNotFound(e.message), None, sys.exc_info()[2] + raise keymanager_errors.KeyNotFound(e.message), \ + None, sys.exc_info()[2] except ValueError as v: logger.warn("invalid JSON data from key: %s" % (uri,)) - raise keymanager_errors.KeyNotFound(v.message + ' - ' + uri), None, sys.exc_info()[2] + raise keymanager_errors.KeyNotFound(v.message + ' - ' + uri), \ + None, sys.exc_info()[2] except Exception as e: logger.warn("error retrieving key: %r" % (e,)) - raise keymanager_errors.KeyNotFound(e.message), None, sys.exc_info()[2] + raise keymanager_errors.KeyNotFound(e.message), \ + None, sys.exc_info()[2] # Responses are now text/plain, although it's json anyway, but # this will fail when it shouldn't # leap_assert( @@ -189,7 +191,7 @@ class KeyManager(object): raise KeyNotFound(message), None, sys.exc_info()[2] return response - d = self._async_client_pinned.request( + d = self._nicknym._async_client_pinned.request( str(uri), 'GET', callback=check_404) d.addCallback(client.readBody) return d @@ -219,76 +221,6 @@ class KeyManager(object): raise keymanager_errors.KeyNotFound(uri) defer.returnValue(content) - @defer.inlineCallbacks - def _put(self, uri, data=None): - """ - Send a PUT request to C{uri} containing C{data}. - - The request will be sent using the configured CA certificate path to - verify the server certificate and the configured session id for - authentication. - - :param uri: The URI of the request. - :type uri: str - :param data: The body of the request. - :type data: dict, str or file - - :return: A deferred that will be fired when PUT request finishes - :rtype: Deferred - """ - leap_assert( - self._token is not None, - 'We need a token to interact with webapp!') - if type(data) == dict: - data = urllib.urlencode(data) - headers = {'Authorization': [str('Token token=%s' % self._token)]} - headers['Content-Type'] = ['application/x-www-form-urlencoded'] - try: - res = yield self._async_client_pinned.request(str(uri), 'PUT', - body=str(data), - headers=headers) - except Exception as e: - logger.warn("Error uploading key: %r" % (e,)) - raise e - if 'error' in res: - # FIXME: That's a workaround for 500, - # we need to implement a readBody to assert response code - logger.warn("Error uploading key: %r" % (res,)) - raise Exception(res) - - @memoized_method(invalidation=300) - @defer.inlineCallbacks - def _fetch_keys_from_server(self, address): - """ - Fetch keys bound to address from nickserver and insert them in - local database. - - :param address: The address bound to the keys. - :type address: str - - :return: A Deferred which fires when the key is in the storage, - or which fails with KeyNotFound if the key was not found on - nickserver. - :rtype: Deferred - - """ - # request keys from the nickserver - server_keys = yield self._get_key_from_nicknym(address) - - # insert keys in local database - if self.OPENPGP_KEY in server_keys: - # nicknym server is authoritative for its own domain, - # for other domains the key might come from key servers. - validation_level = ValidationLevels.Weak_Chain - _, domain = _split_email(address) - if (domain == _get_domain(self._nickserver_uri)): - validation_level = ValidationLevels.Provider_Trust - - yield self.put_raw_key( - server_keys['openpgp'], - address=address, - validation=validation_level) - # # key management # @@ -307,7 +239,8 @@ class KeyManager(object): :raise UnsupportedKeyTypeError: if invalid key type """ def send(pubkey): - d = self._nicknym.put_key(self.uid, pubkey.key_data, self._api_uri, self._api_version) + d = self._nicknym.put_key(self.uid, pubkey.key_data, + self._api_uri, self._api_version) d.addCallback(lambda _: emit_async(catalog.KEYMANAGER_DONE_UPLOADING_KEYS, self._address)) @@ -327,9 +260,9 @@ class KeyManager(object): :type address: str :return: A Deferred which fires when the key is in the storage, - or which fails with KeyNotFound if the key was not found on - nickserver. - :rtype: Deferred + or which fails with KeyNotFound if the key was not + found on nickserver. + :rtype: Deferred """ server_keys = yield self._nicknym.fetch_key_with_address(address) diff --git a/src/leap/bitmask/keymanager/keys.py b/src/leap/bitmask/keymanager/keys.py index 1b236c3..fd45448 100644 --- a/src/leap/bitmask/keymanager/keys.py +++ b/src/leap/bitmask/keymanager/keys.py @@ -292,7 +292,8 @@ class OpenPGPKey(object): :return: True if key expired. :rtype: bool """ - return False if self.expiry_date is None else self.expiry_date < datetime.now() + return False if self.expiry_date is None \ + else self.expiry_date < datetime.now() def parse_address(address): diff --git a/src/leap/bitmask/keymanager/nicknym.py b/src/leap/bitmask/keymanager/nicknym.py index 7af49d6..5fe9992 100644 --- a/src/leap/bitmask/keymanager/nicknym.py +++ b/src/leap/bitmask/keymanager/nicknym.py @@ -139,12 +139,14 @@ class Nicknym(object): def check_404(response): if response.code == NOT_FOUND: - message = ' %s: Key not found. Request: %s' % (response.code, uri) + message = ' %s: Key not found. Request: %s' \ + % (response.code, uri) logger.warning(message) raise KeyNotFound(message), None, sys.exc_info()[2] return response - d = self._async_client_pinned.request(str(uri), 'GET', callback=check_404) + d = self._async_client_pinned.request(str(uri), 'GET', + callback=check_404) d.addCallback(client.readBody) return d @@ -162,7 +164,8 @@ class Nicknym(object): :rtype: Deferred """ - return self._get_key_from_nicknym(self._nickserver_uri + '?address=' + address) + return self._get_key_from_nicknym(self._nickserver_uri + + '?address=' + address) @memoized_method(invalidation=300) def fetch_key_with_fingerprint(self, fingerprint): @@ -178,4 +181,5 @@ class Nicknym(object): :rtype: Deferred """ - return self._get_key_from_nicknym(self._nickserver_uri + '?fingerprint=' + fingerprint) + return self._get_key_from_nicknym(self._nickserver_uri + + '?fingerprint=' + fingerprint) diff --git a/src/leap/bitmask/keymanager/openpgp.py b/src/leap/bitmask/keymanager/openpgp.py index b256ff0..b72c62c 100644 --- a/src/leap/bitmask/keymanager/openpgp.py +++ b/src/leap/bitmask/keymanager/openpgp.py @@ -533,12 +533,13 @@ class OpenPGPScheme(object): d.addCallback(delete_key) return d + @defer.inlineCallbacks def unactivate_key(self, address): """ Mark a active doc as deleted. :param address: The unique address for the active content. """ - active_doc = self._get_active_doc_from_address(address, False) + active_doc = yield self._get_active_doc_from_address(address, False) yield self._soledad.delete_doc(active_doc) # diff --git a/src/leap/bitmask/keymanager/refresher.py b/src/leap/bitmask/keymanager/refresher.py index 54232c3..694a537 100644 --- a/src/leap/bitmask/keymanager/refresher.py +++ b/src/leap/bitmask/keymanager/refresher.py @@ -17,24 +17,25 @@ """ -A service which continuous refreshes the (public) key directories randomly in a random time interval. +A service which continuous refreshes the (public) key directories randomly in a +random time interval. """ -import logging - from twisted.internet.task import LoopingCall +from twisted.logger import Logger from twisted.internet import defer from random import choice, randrange DEBUG_STOP_REFRESH = "Stop to refresh the key directory ..." DEBUG_START_REFRESH = "Start to refresh the key directory ..." -ERROR_UNEQUAL_FINGERPRINTS = "[WARNING] Your provider might be cheat on you, " \ - "and gave a wrong key back. Fingerprints are unequal, old %s new %s " +ERROR_UNEQUAL_FINGERPRINTS = "[WARNING] Your provider might be cheat " \ + "on you, and gave a wrong key back. " \ + "Fingerprints are unequal, old %s new %s " MIN_RANDOM_INTERVAL_RANGE = 4 * 60 # four minutes MAX_RANDOM_INTERVAL_RANGE = 6 * 60 # six minutes -logger = logging.getLogger(__name__) +logger = Logger() class RandomRefreshPublicKey(object): @@ -74,7 +75,6 @@ class RandomRefreshPublicKey(object): :return: A random key. :rtype: A deferred. """ - # TODO maybe make a check first if key is active and get another one then. keys = yield self._openpgp.get_all_keys() defer.returnValue(None if keys is None or keys == [] else choice(keys)) @@ -117,8 +117,9 @@ class RandomRefreshPublicKey(object): yield self._maybe_unactivate_key(old_updated_key) yield self._openpgp.put_key(old_updated_key) - # No new fetch by address needed, bc that will happen before sending an email - # could be discussed since fetching before sending an email leaks information. + # No new fetch by address needed, bc that will happen before sending an + # email could be discussed since fetching before sending an email + # leaks information. def _get_random_interval_to_refresh(self): """ diff --git a/src/leap/bitmask/mail/testing/__init__.py b/src/leap/bitmask/mail/testing/__init__.py index 5ebfaf5..afb8e43 100644 --- a/src/leap/bitmask/mail/testing/__init__.py +++ b/src/leap/bitmask/mail/testing/__init__.py @@ -69,7 +69,7 @@ class KeyManagerWithSoledadTestCase(unittest.TestCase, BaseLeapTest): def deliverBody(self, x): return '' - self.km._async_client_pinned.request = Mock( + self.km._nicknym._async_client_pinned.request = Mock( return_value=defer.succeed(Response())) d1 = self.km.put_raw_key(PRIVATE_KEY, ADDRESS) |