1.1 --- a/MoinMessage.py Wed Jan 08 01:55:57 2014 +0100
1.2 +++ b/MoinMessage.py Thu Jan 09 16:52:05 2014 +0100
1.3 @@ -8,6 +8,7 @@
1.4
1.5 from email import message_from_string
1.6 from email.encoders import encode_noop
1.7 +from email.generator import Generator
1.8 from email.mime.multipart import MIMEMultipart
1.9 from email.mime.application import MIMEApplication
1.10 from email.mime.base import MIMEBase
1.11 @@ -20,6 +21,11 @@
1.12 import httplib
1.13 import os
1.14
1.15 +try:
1.16 + from cStringIO import StringIO
1.17 +except ImportError:
1.18 + from StringIO import StringIO
1.19 +
1.20 def is_collection(message):
1.21 return message.get("Update-Type") == "collection"
1.22
1.23 @@ -279,8 +285,8 @@
1.24
1.25 # Verify the message.
1.26
1.27 - fingerprint, identity = self.verifyMessageText(signature.get_payload(decode=True), content.as_string())
1.28 - return fingerprint, identity, getOriginalContent(content)
1.29 + fingerprint, identity = self.verifyMessageText(signature.get_payload(decode=True), as_string(content))
1.30 + return fingerprint, identity, content
1.31
1.32 def signMessage(self, message, keyid):
1.33
1.34 @@ -288,18 +294,14 @@
1.35 Return a signed version of 'message' using the given 'keyid'.
1.36 """
1.37
1.38 - # Make a representation-insensitive container for the message.
1.39 -
1.40 - content = MIMEApplication(message.as_string())
1.41 -
1.42 # Sign the container's representation.
1.43
1.44 - signature = self.run(["--armor", "-u", keyid, "--detach-sig"], content.as_string())
1.45 + signature = self.run(["--armor", "-u", keyid, "--detach-sig"], as_string(message))
1.46
1.47 # Make the container for the message.
1.48
1.49 signed_message = MIMEMultipart("signed", protocol="application/pgp-signature")
1.50 - signed_message.attach(content)
1.51 + signed_message.attach(message)
1.52
1.53 signature_part = MIMEBase("application", "pgp-signature")
1.54 signature_part.set_payload(signature)
1.55 @@ -339,7 +341,7 @@
1.56 Return an encrypted version of 'message' using the given 'keyid'.
1.57 """
1.58
1.59 - text = message.as_string()
1.60 + text = as_string(message)
1.61 encrypted = self.run(["--armor", "-r", keyid, "--encrypt", "--trust-model", "always"], text)
1.62
1.63 # Make the container for the message.
1.64 @@ -450,6 +452,20 @@
1.65
1.66 return keys
1.67
1.68 +# Message serialisation functions, working around email module problems.
1.69 +
1.70 +def as_string(message):
1.71 +
1.72 + """
1.73 + Return the string representation of 'message', attempting to preserve the
1.74 + precise original formatting.
1.75 + """
1.76 +
1.77 + out = StringIO()
1.78 + generator = Generator(out, False, 0) # disable reformatting measures
1.79 + generator.flatten(message)
1.80 + return out.getvalue()
1.81 +
1.82 # Message decoding functions.
1.83
1.84 # Detect PGP/GPG-encoded payloads.
1.85 @@ -486,15 +502,6 @@
1.86 except ValueError:
1.87 raise MoinMessageMissingPart
1.88
1.89 -def getOriginalContent(content):
1.90 -
1.91 - """
1.92 - Extract the actual content inside the signed message. This reverses the
1.93 - wrapping up of signed content in a representation-insensitive container.
1.94 - """
1.95 -
1.96 - return Parser().parsestr(content.get_payload(decode=True))
1.97 -
1.98 # Communications functions.
1.99
1.100 def timestamp(message):
1.101 @@ -530,7 +537,7 @@
1.102 """
1.103
1.104 scheme, host, port, path = parseURL(url)
1.105 - text = message.as_string()
1.106 + text = as_string(message)
1.107
1.108 req = _getConnection(scheme)(host, port)
1.109 req.request(method, path, text)