| | 1 | # encoding: utf-8 |
| | 2 | |
| | 3 | """TurboMail extension API.""" |
| | 4 | |
| | 5 | import logging |
| | 6 | log = logging.getLogger("turbomail.utf8qp") |
| | 7 | |
| | 8 | import turbomail, os |
| | 9 | from email.mime.multipart import MIMEMultipart |
| | 10 | from email.mime.application import MIMEApplication |
| | 11 | |
| | 12 | __all__ = ['start'] |
| | 13 | |
| | 14 | |
| | 15 | |
| | 16 | class Message(turbomail.Message): |
| | 17 | def __init__(self, **kw): |
| | 18 | super(Message, self).__init__(**kw) |
| | 19 | |
| | 20 | self.sign = kw.get("sign", turbomail.config.get("mail.message.sign", False)) |
| | 21 | self.encrypt = kw.get("encrypt", turbomail.config.get("mail.message.encrypt", False)) |
| | 22 | self.force = kw.get("force", turbomail.config.get("mail.smime.force", False)) |
| | 23 | |
| | 24 | def process_mime_message(self, message): |
| | 25 | newmessage = message |
| | 26 | |
| | 27 | if self.sign: |
| | 28 | from M2Crypto import BIO, Rand, SMIME |
| | 29 | |
| | 30 | # Make a MemoryBuffer of the message. |
| | 31 | buf = BIO.MemoryBuffer(str(message)) |
| | 32 | |
| | 33 | # Seed the PRNG. |
| | 34 | Rand.load_file('randpool.dat', -1) |
| | 35 | |
| | 36 | # Instantiate an SMIME object; set it up; sign the buffer. |
| | 37 | s = SMIME.SMIME() |
| | 38 | s.load_key( |
| | 39 | os.path.join(turbomail.config.get("mail.smime.keystore", "./"), str(self.author.addresses[0]) + '.key'), |
| | 40 | os.path.join(turbomail.config.get("mail.smime.keystore", "./"), str(self.author.addresses[0]) + '.x509'), |
| | 41 | ) |
| | 42 | p7 = s.sign(buf) |
| | 43 | |
| | 44 | # I'm assuming -a-lot- here. There's got to be a better way to do this, but the M2Crypto lib sucks ass from this PoV. |
| | 45 | newmessage = MIMEMultipart("signed", protocol='application/x-pkcs7-signature', micalg="sha1") |
| | 46 | newmessage.attach(message) |
| | 47 | |
| | 48 | buf = BIO.MemoryBuffer() |
| | 49 | p7.write_der(buf) |
| | 50 | signature = MIMEApplication(buf.read(), "x-pkcs7-signature") |
| | 51 | signature.set_param("name", "smime.p7s") |
| | 52 | del signature['Content-Disposition'] |
| | 53 | signature.add_header("Content-Disposition", "attachment", filename="smime.p7s") |
| | 54 | |
| | 55 | newmessage.attach(signature) |
| | 56 | |
| | 57 | # Save the PRNG's state. |
| | 58 | Rand.save_file('randpool.dat') |
| | 59 | |
| | 60 | return newmessage |