summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKali Kaneko (leap communications) <kali@leap.se>2016-07-07 16:48:46 +0200
committerKali Kaneko (leap communications) <kali@leap.se>2016-07-07 16:48:46 +0200
commit1bf85b44bcf97f13e2e63dfe35cc1ec2fe80c80a (patch)
tree05f05de41276fe120dc71c9a0ebbc1ecf48cd4a5
parent65814f87d5fff167528455e29edc8bf99c2e3575 (diff)
ProtectionLevel object
-rw-r--r--memoryhole/memoryhole.old.py25
-rw-r--r--memoryhole/message.py124
-rw-r--r--requirements.pip18
-rw-r--r--tests/test_message.py24
4 files changed, 166 insertions, 25 deletions
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 '<ProtectionLevel: sig(%s) encr(%s) score:%s>' % (
- 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 '<ProtectionLevel: sig(%s) encr(%s) score:%s>' % (
+ 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 '<MemoryHoleHeader(%s) [%s: %s]>' % (
+ 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