From 1bf85b44bcf97f13e2e63dfe35cc1ec2fe80c80a Mon Sep 17 00:00:00 2001 From: "Kali Kaneko (leap communications)" Date: Thu, 7 Jul 2016 16:48:46 +0200 Subject: ProtectionLevel object --- memoryhole/memoryhole.old.py | 25 --------- memoryhole/message.py | 124 +++++++++++++++++++++++++++++++++++++++++++ requirements.pip | 18 +++++++ tests/test_message.py | 24 +++++++++ 4 files changed, 166 insertions(+), 25 deletions(-) create mode 100644 memoryhole/message.py create mode 100644 tests/test_message.py diff --git a/memoryhole/memoryhole.old.py b/memoryhole/memoryhole.old.py index e6b93b9..9777f48 100644 --- a/memoryhole/memoryhole.old.py +++ b/memoryhole/memoryhole.old.py @@ -15,31 +15,6 @@ logger = logging.getLogger(__name__) COPY_HEADERS = ('Subject', 'Message-ID', 'Date', 'To', 'From') -class ProtectionLevel(object): - - def __init__(self, signed_by, encrypted_by): - - self.signed_by = signed_by - self.encrypted_by = encrypted_by - - # TODO add __cmp__ - - @property - def score(self): - if self.signed_by and self.encrypted_by: - return 3 - elif self.signed_by: - return 2 - elif self.encrypted_by: - return 1 - else: - return 0 - - def __repr__(self): - return '' % ( - len(self.signed_by), len(self.encrypted_by), self.score) - - class MemoryHoleHeader(Header): def __init__(self, name, value): diff --git a/memoryhole/message.py b/memoryhole/message.py new file mode 100644 index 0000000..ea24bc7 --- /dev/null +++ b/memoryhole/message.py @@ -0,0 +1,124 @@ +from email.message import Message +from email.header import Header + + +class ProtectionLevel(object): + + def __init__(self, signed_by=None, encrypted_by=None): + if signed_by is None: + signed_by = set([]) + self.signed_by = signed_by + + if encrypted_by is None: + encrypted_by = set([]) + self.encrypted_by = encrypted_by + + @property + def score(self): + if self.signed_by and self.encrypted_by: + return 3 + elif self.signed_by: + return 2 + elif self.encrypted_by: + return 1 + else: + return 0 + + def __cmp__(self, other): + try: + return cmp(self.score, other.score) + except AttributeError: + raise TypeError('Tried to compare something that is ' + 'not a ProtectionLevel') + + def __eq__(self, other): + try: + return (not self.score < other.score and + not other.score < self.score) + except AttributeError: + raise TypeError('Not a ProtectionLevel') + + def __ne__(self, other): + try: + return (self.score < other.score or + other.score < self.score) + except AttributeError: + raise TypeError('Not a ProtectionLevel') + + def __gt__(self, other): + try: + return other.score < self.score + except AttributeError: + raise TypeError('Not a ProtectionLevel') + + def __ge__(self, other): + try: + return not self.score < other.score + except AttributeError: + raise TypeError('Not a ProtectionLevel') + + def __le__(self, other): + try: + return not other.score < self.score + except AttributeError: + raise TypeError('Not a ProtectionLevel') + + def __repr__(self): + return '' % ( + len(self.signed_by), len(self.encrypted_by), self.score) + + +class MemoryHoleHeader(Header): + + def __init__(self, name, value): + self._name = name + self._value = value + + self._h = Header(value, header_name=name) + + self.signed_by = set([]) + self.encrypted_by = set([]) + + self._firstlinelen = self._h._firstlinelen + self._chunks = self._h._chunks + self._continuation_ws = self._h._continuation_ws + self._charset = self._h._charset + + @property + def protection_level(self): + return ProtectionLevel(self.signed_by, self.encrypted_by) + + def __repr__(self): + return '' % ( + self.protection_level.score, self._name, self._value) + + +class MemoryHoleMessage(Message): + + def __init__(self, msg, gpg): + self._msg = msg + self._gpg = gpg + + verified = False + # verified = verify_signature(msg, gpg) + self.signed = verified.valid + + self._mh_headers = {} + # inner_headers = extract_wrapped_headers(msg) + inner_headers = {} + + for name, value in inner_headers.items(): + mhh = MemoryHoleHeader(name, value) + mhh.signed_by.add(verified.key_id) + self._mh_headers[name] = mhh + + self._charset = self._msg._charset + self._headers = self._msg._headers + self._payload = self._msg._payload + self.preamble = self._msg.preamble + + def get_protected_header(self, header_name): + return self._mh_headers.get(header_name) + + # TODO add is_tampered_header? + # TODO add __getattr__, lookup the protected headers first diff --git a/requirements.pip b/requirements.pip index b3d5230..a76ce78 100644 --- a/requirements.pip +++ b/requirements.pip @@ -36,3 +36,21 @@ zope.interface==4.2.0 \ --hash=sha256:817c7bef511e2ea6265629a95086741f12d878101ec554da3ae478a613db5ae3 \ --hash=sha256:cdd9e65a38656628accc7306edfd574028a992ff04c053b9285bc087e1682f3b \ --hash=sha256:1bc58a88af5271ca0371541e0c595cf5cb22133a5ef5c145b693014853c8f17c +psutil==4.3.0 \ + --hash=sha256:99c2ab6c8f0d60e0c86775f8e5844e266af48cc1d9ecd1be209cd407a3e9c9a1 \ + --hash=sha256:a91474d34bf1bc86a0d95e2c198a70723208f9dc9e50258c2060a1bab3796f81 \ + --hash=sha256:c987f0691c01cbe81813b0c895208c474240c96e26f7d1e945e8dabee5c85437 \ + --hash=sha256:233a943d3e6636d648f05515a4d21b4dda63499d8ca38d6890a57a3f78a9cceb \ + --hash=sha256:1893fe42b0fb5f11bf84ffe770be5b2e27fb7ec959ba8bf620b704552b738c72 \ + --hash=sha256:1345217075dd5bb4fecbf7cb0fe4c0c170e93ec57d48494756f4b617cd21b449 \ + --hash=sha256:c9c4274f5f95a171437c90f65c3e9b71a871753f0a827f930e1b14aa43041eab \ + --hash=sha256:5984ee7b2880abcdaa0819315f69a5f37da963863495c2294392cb3e98141a95 \ + --hash=sha256:86197ae5978f216d33bfff4383d5cc0b80f079d09cf45a2a406d1abb5d0299f0 \ + --hash=sha256:1ad0075b6c86c0ea5076149ec39dcecf0c692711c34317d43d73a4d8c4d4ec30 \ + --hash=sha256:02c042e1f6c68c807de5caf45547971cf02977abf4cd92c8961186af9c91c488 \ + --hash=sha256:2bcfeff969f3718bb31effea752d92511f375547d337687db1bd99ccd85b7ad7 \ + --hash=sha256:34736b91c9785ede9d859a79e28129390f609339014f904c276ad46d0a440730 \ + --hash=sha256:da6ee62fb5ffda188c39aacb0499d401c131046e922ba53fb4b908937e771f94 \ + --hash=sha256:6f36fa29aa9ca935405a3cebe03cfbc6dde27088f9ad3d9b2d3baa47d4b89914 \ + --hash=sha256:63b75c5374fafdaf3f389229b592f19b88a8c7951d1b973b9113df649ade5cb9 \ + --hash=sha256:6d0e1e9bbdab5a7d40b57d8f0841eb9e11c2395ac7ec0ddd396116240d733f46 diff --git a/tests/test_message.py b/tests/test_message.py new file mode 100644 index 0000000..025c3c4 --- /dev/null +++ b/tests/test_message.py @@ -0,0 +1,24 @@ +from memoryhole import message + +import pytest + + +def test_protection_level(): + pl0 = message.ProtectionLevel(signed_by=['alice'], encrypted_by=['alice']) + pl1 = message.ProtectionLevel(signed_by=['alice']) + pl2 = message.ProtectionLevel(encrypted_by=['alice']) + pl3 = message.ProtectionLevel() + assert pl0 > pl1 + assert pl1 > pl2 + assert pl2 > pl3 + assert pl0 == pl0 + assert pl1 == pl1 + assert pl2 == pl2 + assert pl2 < pl1 + assert pl1 < pl0 + + +def test_compare_wrong_types(): + pl0 = message.ProtectionLevel(signed_by=['alice']) + with pytest.raises(TypeError): + assert pl0 > 1 -- cgit v1.2.3