From 3cafd7ef3f6578a3f45d0b0218b8ca6d388be6d3 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 21 Nov 2013 12:12:31 -0300 Subject: Do not check for a valid address, rely on client. An email address regexp that supports all (or almost) emails is really complex, and is_address uses a simpler one since we restrict the valid usernames and provider names. For that we rely on the email client to check whether the email address is valid or not. --- src/leap/keymanager/openpgp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/leap/keymanager/openpgp.py b/src/leap/keymanager/openpgp.py index f6223d5..0c11d17 100644 --- a/src/leap/keymanager/openpgp.py +++ b/src/leap/keymanager/openpgp.py @@ -297,7 +297,6 @@ class OpenPGPScheme(EncryptionScheme): :rtype: OpenPGPKey @raise KeyNotFound: If the key was not found on local storage. """ - leap_assert(is_address(address), 'Not an user address: %s' % address) doc = self._get_key_doc(address, private) if doc is None: raise errors.KeyNotFound(address) -- cgit v1.2.3 From bf5ce4086647ddf8381b0e75e928c1f675b0cddf Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 21 Nov 2013 12:23:33 -0300 Subject: Remove '+' suffix in email address. This allows us to support encrypt mails to 'test_user@provider.com' even if was sent to 'test_user+optional_string@provider.com'. --- src/leap/keymanager/openpgp.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/leap/keymanager/openpgp.py b/src/leap/keymanager/openpgp.py index 0c11d17..cb46371 100644 --- a/src/leap/keymanager/openpgp.py +++ b/src/leap/keymanager/openpgp.py @@ -297,6 +297,11 @@ class OpenPGPScheme(EncryptionScheme): :rtype: OpenPGPKey @raise KeyNotFound: If the key was not found on local storage. """ + # Remove the identity suffix after the '+' until the '@' + # e.g.: test_user+something@provider.com becomes test_user@probider.com + # since the key belongs to the identity without the '+' suffix. + address = re.sub(r'\+.*\@', '@', address) + doc = self._get_key_doc(address, private) if doc is None: raise errors.KeyNotFound(address) -- cgit v1.2.3 From 146948c060c1f69b997400e995ec9d4ba4160c56 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 21 Nov 2013 12:30:14 -0300 Subject: Add changes file for #4491. --- changes/email-checks | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changes/email-checks diff --git a/changes/email-checks b/changes/email-checks new file mode 100644 index 0000000..eee7de7 --- /dev/null +++ b/changes/email-checks @@ -0,0 +1,3 @@ + o Remove address check when sending email and rely in the email client to + verify that is correct. Closes #4491. + o Support sending encrypted mails to addresses using the '+' sign. -- cgit v1.2.3 From dea149b6f5175a8082c81f32ee34ce4e4d878e0e Mon Sep 17 00:00:00 2001 From: drebs Date: Mon, 25 Nov 2013 11:20:55 -0200 Subject: Fix error returns on openpgp backend. Also fix: - some docstrings. - variabled referenced without previous assignement. --- changes/bug_fix-returns | 1 + src/leap/keymanager/__init__.py | 3 +++ src/leap/keymanager/openpgp.py | 9 +++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 changes/bug_fix-returns diff --git a/changes/bug_fix-returns b/changes/bug_fix-returns new file mode 100644 index 0000000..3bb7264 --- /dev/null +++ b/changes/bug_fix-returns @@ -0,0 +1 @@ + o Fix error return values on openpgp backend. diff --git a/src/leap/keymanager/__init__.py b/src/leap/keymanager/__init__.py index dbc5489..6cfbf71 100644 --- a/src/leap/keymanager/__init__.py +++ b/src/leap/keymanager/__init__.py @@ -425,6 +425,9 @@ class KeyManager(object): :type data: str :param privkey: The key used to decrypt. :type privkey: OpenPGPKey + :param passphrase: The passphrase for the secret key used for + decryption. + :type passphrase: str :param verify: The key used to verify a signature. :type verify: OpenPGPKey diff --git a/src/leap/keymanager/openpgp.py b/src/leap/keymanager/openpgp.py index cb46371..5781d67 100644 --- a/src/leap/keymanager/openpgp.py +++ b/src/leap/keymanager/openpgp.py @@ -341,6 +341,7 @@ class OpenPGPScheme(EncryptionScheme): leap_assert(match is not None, 'No user address in key data.') address = match.group(1) + openpgp_privkey = None if privkey is not None: match = re.match(mail_regex, privkey['uids'].pop()) leap_assert(match is not None, 'No user address in key data.') @@ -374,6 +375,7 @@ class OpenPGPScheme(EncryptionScheme): """ leap_assert_type(key_data, (str, unicode)) + openpgp_privkey = None try: openpgp_pubkey, openpgp_privkey = self.parse_ascii_key(key_data) except (errors.KeyAddressMismatch, errors.KeyFingerprintMismatch) as e: @@ -524,6 +526,9 @@ class OpenPGPScheme(EncryptionScheme): :type data: str :param privkey: The key used to decrypt. :type privkey: OpenPGPKey + :param passphrase: The passphrase for the secret key used for + decryption. + :type passphrase: str :param verify: The key used to verify a signature. :type verify: OpenPGPKey @@ -549,7 +554,7 @@ class OpenPGPScheme(EncryptionScheme): verify.fingerprint != result.pubkey_fingerprint: raise errors.InvalidSignature( 'Failed to verify signature with key %s: %s' % - (verify.key_id, stderr)) + (verify.key_id, result.stderr)) # XXX: this is the encoding used by gpg module # https://github.com/isislovecruft/python-gnupg/\ @@ -612,7 +617,7 @@ class OpenPGPScheme(EncryptionScheme): if result.fingerprint is None: raise errors.SignFailed( 'Failed to sign with key %s: %s' % - (privkey['keyid'], stderr)) + (privkey['keyid'], result.stderr)) leap_assert( result.fingerprint == kfprint, 'Signature and private key fingerprints mismatch: ' -- cgit v1.2.3 From 5d5f5ee44ab0baec3984f435dcd8783609f79867 Mon Sep 17 00:00:00 2001 From: drebs Date: Mon, 25 Nov 2013 16:35:27 -0200 Subject: Improve exceptions names and handling. --- .../feature_improve-exceptions-names-and-handling | 1 + src/leap/keymanager/errors.py | 6 +- src/leap/keymanager/openpgp.py | 70 +++++++++++++--------- 3 files changed, 47 insertions(+), 30 deletions(-) create mode 100644 changes/feature_improve-exceptions-names-and-handling diff --git a/changes/feature_improve-exceptions-names-and-handling b/changes/feature_improve-exceptions-names-and-handling new file mode 100644 index 0000000..936232d --- /dev/null +++ b/changes/feature_improve-exceptions-names-and-handling @@ -0,0 +1 @@ + o Improve exception names and handling. diff --git a/src/leap/keymanager/errors.py b/src/leap/keymanager/errors.py index 27180db..ebe4fd5 100644 --- a/src/leap/keymanager/errors.py +++ b/src/leap/keymanager/errors.py @@ -58,21 +58,21 @@ class InvalidSignature(Exception): pass -class EncryptionFailed(Exception): +class EncryptError(Exception): """ Raised upon failures of encryption. """ pass -class DecryptionFailed(Exception): +class DecryptError(Exception): """ Raised upon failures of decryption. """ pass -class EncryptionDecryptionFailed(Exception): +class GPGError(Exception): """ Raised upon failures of encryption/decryption. """ diff --git a/src/leap/keymanager/openpgp.py b/src/leap/keymanager/openpgp.py index 5781d67..856b21e 100644 --- a/src/leap/keymanager/openpgp.py +++ b/src/leap/keymanager/openpgp.py @@ -471,14 +471,18 @@ class OpenPGPScheme(EncryptionScheme): def _assert_gpg_result_ok(result): """ Check if GPG result is 'ok' and log stderr outputs. - :param result: The GPG results - :type result: + + :param result: GPG results, which have a field calld 'ok' that states + whether the gpg operation was successful or not. + :type result: object + + :raise GPGError: Raised when the gpg operation was not successful. """ stderr = getattr(result, 'stderr', None) if stderr: logger.debug("%s" % (stderr,)) if getattr(result, 'ok', None) is not True: - raise errors.EncryptionDecryptionFailed( + raise errors.GPGError( 'Failed to encrypt/decrypt: %s' % stderr) def encrypt(self, data, pubkey, passphrase=None, sign=None, @@ -497,6 +501,8 @@ class OpenPGPScheme(EncryptionScheme): :return: The encrypted data. :rtype: str + + :raise EncryptError: Raised if failed encrypting for some reason. """ leap_assert_type(pubkey, OpenPGPKey) leap_assert(pubkey.private is False, 'Key is not public.') @@ -515,8 +521,12 @@ class OpenPGPScheme(EncryptionScheme): # in the ciphertext. # result.ok - (bool) indicates if the operation succeeded # result.data - (bool) contains the result of the operation - self._assert_gpg_result_ok(result) - return result.data + try: + self._assert_gpg_result_ok(result) + return result.data + except errors.GPGError as e: + logger.error('Failed to decrypt: %s.' % str(e)) + raise error.EncryptError() def decrypt(self, data, privkey, passphrase=None, verify=None): """ @@ -535,8 +545,9 @@ class OpenPGPScheme(EncryptionScheme): :return: The decrypted data. :rtype: unicode - @raise InvalidSignature: Raised if unable to verify the signature with - C{verify} key. + :raise DecryptError: Raised if failed decrypting for some reason. + :raise InvalidSignature: Raised if unable to verify the signature with + C{verify} key. """ leap_assert(privkey.private is True, 'Key is not private.') keys = [privkey] @@ -545,26 +556,31 @@ class OpenPGPScheme(EncryptionScheme): leap_assert(verify.private is False) keys.append(verify) with self._temporary_gpgwrapper(keys) as gpg: - result = gpg.decrypt( - data, passphrase=passphrase, always_trust=True) - self._assert_gpg_result_ok(result) - # verify signature - if (verify is not None): - if result.valid is False or \ - verify.fingerprint != result.pubkey_fingerprint: - raise errors.InvalidSignature( - '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') + try: + result = gpg.decrypt( + data, passphrase=passphrase, always_trust=True) + self._assert_gpg_result_ok(result) + # verify signature + if (verify is not None): + if result.valid is False or \ + verify.fingerprint != result.pubkey_fingerprint: + raise errors.InvalidSignature( + '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') + except errors.GPGError as e: + logger.error('Failed to decrypt: %s.' % str(e)) + raise errors.DecryptError(str(e)) + def is_encrypted(self, data): """ -- cgit v1.2.3 From 48751fa19bf9d9dfd1acbe96c582d08d57b81d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 6 Dec 2013 15:33:25 -0300 Subject: Fold in changes --- CHANGELOG | 7 +++++++ changes/VERSION_COMPAT | 0 changes/bug_fix-returns | 1 - changes/email-checks | 3 --- changes/feature_improve-exceptions-names-and-handling | 1 - 5 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 changes/VERSION_COMPAT delete mode 100644 changes/bug_fix-returns delete mode 100644 changes/email-checks delete mode 100644 changes/feature_improve-exceptions-names-and-handling diff --git a/CHANGELOG b/CHANGELOG index e20b86c..a081cc5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +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 + client to verify that is correct. Closes #4491. + o Support sending encrypted mails to addresses using the '+' sign. + o Improve exception names and handling. + 0.3.6 Nov 15: o Default encoding to 'utf-8' in case of system encodings not set. Closes #4427. diff --git a/changes/VERSION_COMPAT b/changes/VERSION_COMPAT new file mode 100644 index 0000000..e69de29 diff --git a/changes/bug_fix-returns b/changes/bug_fix-returns deleted file mode 100644 index 3bb7264..0000000 --- a/changes/bug_fix-returns +++ /dev/null @@ -1 +0,0 @@ - o Fix error return values on openpgp backend. diff --git a/changes/email-checks b/changes/email-checks deleted file mode 100644 index eee7de7..0000000 --- a/changes/email-checks +++ /dev/null @@ -1,3 +0,0 @@ - o Remove address check when sending email and rely in the email client to - verify that is correct. Closes #4491. - o Support sending encrypted mails to addresses using the '+' sign. diff --git a/changes/feature_improve-exceptions-names-and-handling b/changes/feature_improve-exceptions-names-and-handling deleted file mode 100644 index 936232d..0000000 --- a/changes/feature_improve-exceptions-names-and-handling +++ /dev/null @@ -1 +0,0 @@ - o Improve exception names and handling. -- cgit v1.2.3