diff options
-rw-r--r-- | CHANGELOG | 10 | ||||
-rw-r--r-- | changes/VERSION_COMPAT | 11 | ||||
-rw-r--r-- | changes/feature_4784-memoize-get-key | 1 | ||||
-rw-r--r-- | pkg/requirements.pip | 2 | ||||
-rw-r--r-- | src/leap/keymanager/__init__.py | 50 | ||||
-rw-r--r-- | src/leap/keymanager/openpgp.py | 14 | ||||
-rw-r--r-- | src/leap/keymanager/tests/test_keymanager.py | 16 |
7 files changed, 64 insertions, 40 deletions
@@ -1,3 +1,13 @@ +0.3.8 Apr 4: + o Properly raise KeyNotFound exception when looking for keys on + nickserver. Fixes #5415. + o Do not decode decrypted data, return as str. + o Use a better version handler for the gnupg version check. + o Memoize call to get_key. Closes #4784. + o Update auth to interact with webapp v2. Fixes #5120. + +-- 2014 -- + 0.3.7 Dec 6: o Fix error return values on openpgp backend. o Remove address check when sending email and rely in the email diff --git a/changes/VERSION_COMPAT b/changes/VERSION_COMPAT index dfe67ab..cc00ecf 100644 --- a/changes/VERSION_COMPAT +++ b/changes/VERSION_COMPAT @@ -1 +1,10 @@ -leap.common >= 0.3.7 # memoize +################################################# +# This file keeps track of the recent changes +# introduced in internal leap dependencies. +# Add your changes here so we can properly update +# requirements.pip during the release process. +# (leave header when resetting) +################################################# +# +# BEGIN DEPENDENCY LIST ------------------------- +# leap.foo.bar>=x.y.z diff --git a/changes/feature_4784-memoize-get-key b/changes/feature_4784-memoize-get-key deleted file mode 100644 index 5284827..0000000 --- a/changes/feature_4784-memoize-get-key +++ /dev/null @@ -1 +0,0 @@ - o Memoize call to get_key. Closes: #4784 diff --git a/pkg/requirements.pip b/pkg/requirements.pip index 0cbdf57..a6092a9 100644 --- a/pkg/requirements.pip +++ b/pkg/requirements.pip @@ -1,4 +1,4 @@ -leap.common>=0.3.6.99 +leap.common>=0.3.7 simplejson requests # if we bump the gnupg version, bump also the sanity check diff --git a/src/leap/keymanager/__init__.py b/src/leap/keymanager/__init__.py index aa4e2e7..41f352e 100644 --- a/src/leap/keymanager/__init__.py +++ b/src/leap/keymanager/__init__.py @@ -23,9 +23,9 @@ import sys try: from gnupg.gnupg import GPGUtilities assert(GPGUtilities) # pyflakes happy - from gnupg import __version__ - from distutils.version import LooseVersion as V - assert(V(__version__) >= V('1.2.3')) + from gnupg import __version__ as _gnupg_version + from pkg_resources import parse_version + assert(parse_version(_gnupg_version) >= parse_version('1.2.3')) except (ImportError, AssertionError): print "*******" @@ -77,7 +77,7 @@ class KeyManager(object): OPENPGP_KEY = 'openpgp' PUBKEY_KEY = "user[public_key]" - def __init__(self, address, nickserver_uri, soledad, session_id=None, + def __init__(self, address, nickserver_uri, soledad, token=None, ca_cert_path=None, api_uri=None, api_version=None, uid=None, gpgbinary=None): """ @@ -90,8 +90,8 @@ class KeyManager(object): :type url: str :param soledad: A Soledad instance for local storage of keys. :type soledad: leap.soledad.Soledad - :param session_id: The session ID for interacting with the webapp API. - :type session_id: str + :param token: The token for interacting with the webapp API. + :type token: str :param ca_cert_path: The path to the CA certificate. :type ca_cert_path: str :param api_uri: The URI of the webapp API. @@ -106,7 +106,7 @@ class KeyManager(object): self._address = address self._nickserver_uri = nickserver_uri self._soledad = soledad - self._session_id = session_id + self._token = token self.ca_cert_path = ca_cert_path self.api_uri = api_uri self.api_version = api_version @@ -180,11 +180,11 @@ class KeyManager(object): self._ca_cert_path is not None, 'We need the CA certificate path!') leap_assert( - self._session_id is not None, - 'We need a session_id to interact with webapp!') + self._token is not None, + 'We need a token to interact with webapp!') res = self._fetcher.put( uri, data=data, verify=self._ca_cert_path, - cookies={'_session_id': self._session_id}) + headers={'Authorization': 'Token token=%s' % self._token}) # assert that the response is valid res.raise_for_status() return res @@ -197,21 +197,25 @@ class KeyManager(object): :param address: The address bound to the keys. :type address: str - @raise KeyNotFound: If the key was not found on nickserver. + :raise KeyNotFound: If the key was not found on nickserver. """ # request keys from the nickserver res = None try: res = self._get(self._nickserver_uri, {'address': address}) + res.raise_for_status() server_keys = res.json() # insert keys in local database if self.OPENPGP_KEY in server_keys: self._wrapper_map[OpenPGPKey].put_ascii_key( server_keys['openpgp']) + except requests.exceptions.HTTPError as e: + if e.response.status_code == 404: + raise KeyNotFound(address) + logger.warning("HTTP error retrieving key: %r" % (e,)) + logger.warning("%s" % (res.content,)) except Exception as e: - logger.warning("Error retrieving the keys: %r" % (e,)) - if res: - logger.warning("%s" % (res.content,)) + logger.warning("Error retrieving key: %r" % (e,)) # # key management @@ -233,7 +237,7 @@ class KeyManager(object): :param ktype: The type of the key. :type ktype: KeyType - @raise KeyNotFound: If the key was not found in local database. + :raise KeyNotFound: If the key was not found in local database. """ leap_assert( ktype is OpenPGPKey, @@ -297,7 +301,7 @@ class KeyManager(object): raise signal(proto.KEYMANAGER_LOOKING_FOR_KEY, address) - self._fetch_keys_from_server(address) + self._fetch_keys_from_server(address) # might raise KeyNotFound key = self._wrapper_map[ktype].get_key(address, private=False) signal(proto.KEYMANAGER_KEY_FOUND, address) @@ -353,14 +357,14 @@ class KeyManager(object): # Setters/getters # - def _get_session_id(self): - return self._session_id + def _get_token(self): + return self._token - def _set_session_id(self, session_id): - self._session_id = session_id + def _set_token(self, token): + self._token = token - session_id = property( - _get_session_id, _set_session_id, doc='The session id.') + token = property( + _get_token, _set_token, doc='The session token.') def _get_ca_cert_path(self): return self._ca_cert_path @@ -443,7 +447,7 @@ class KeyManager(object): :return: The decrypted data. :rtype: str - @raise InvalidSignature: Raised if unable to verify the signature with + :raise InvalidSignature: Raised if unable to verify the signature with C{verify} key. """ leap_assert_type(privkey, EncryptionKey) diff --git a/src/leap/keymanager/openpgp.py b/src/leap/keymanager/openpgp.py index 4276b19..950d022 100644 --- a/src/leap/keymanager/openpgp.py +++ b/src/leap/keymanager/openpgp.py @@ -17,12 +17,10 @@ """ Infrastructure for using OpenPGP keys in Key Manager. """ -import locale import logging import os import re import shutil -import sys import tempfile from contextlib import closing @@ -522,7 +520,7 @@ class OpenPGPScheme(EncryptionScheme): return result.data except errors.GPGError as e: logger.error('Failed to decrypt: %s.' % str(e)) - raise error.EncryptError() + raise errors.EncryptError() def decrypt(self, data, privkey, passphrase=None, verify=None): """ @@ -564,15 +562,7 @@ class OpenPGPScheme(EncryptionScheme): 'Failed to verify signature with key %s: %s' % (verify.key_id, result.stderr)) - # XXX: this is the encoding used by gpg module - # https://github.com/isislovecruft/python-gnupg/\ - # blob/master/gnupg/_meta.py#L121 - encoding = locale.getpreferredencoding() - if encoding is None: - encoding = sys.stdin.encoding - if encoding is None: - encoding = 'utf-8' - return result.data.decode(encoding, 'replace') + return result.data except errors.GPGError as e: logger.error('Failed to decrypt: %s.' % str(e)) raise errors.DecryptError(str(e)) diff --git a/src/leap/keymanager/tests/test_keymanager.py b/src/leap/keymanager/tests/test_keymanager.py index 67676e9..e2558e4 100644 --- a/src/leap/keymanager/tests/test_keymanager.py +++ b/src/leap/keymanager/tests/test_keymanager.py @@ -118,9 +118,21 @@ class KeyManagerWithSoledadTestCase(BaseLeapTest): Soledad._get_secrets_from_shared_db = Mock(return_value=None) Soledad._put_secrets_in_shared_db = Mock(return_value=None) + class MockSharedDB(object): + + get_doc = Mock(return_value=None) + put_doc = Mock() + lock = Mock(return_value=('atoken', 300)) + unlock = Mock(return_value=True) + + def __call__(self): + return self + + Soledad._shared_db = MockSharedDB() + self._soledad = Soledad( - "leap@leap.se", - "123456", + u"leap@leap.se", + u"123456", secrets_path=self.tempdir + "/secret.gpg", local_db_path=self.tempdir + "/soledad.u1db", server_url='', |