#!/usr/bin/env python # A script to verify the email of type multipart signed # passed in from stdin # Want to handle pgp signatures attached to messages from evolution # (cf. RFC 2015, application/pgp-signature) from pprint import pprint import sys, re, mimetools, cStringIO, multifile # (1) read in entire message for safekeeping and then turn back into # file object with cStringIO inputbuf =sys.stdin.read() strfp = cStringIO.StringIO(inputbuf) # use mimetools to parse mime headers msg = mimetools.Message(strfp) email_type = msg.getmaintype() if email_type == 'multipart' and msg.getsubtype()=='signed': sys.stdout.write("This is a multipart/signed message. Let get busy\n") # plist = msg.getplist() # pprint(plist) # assume that it's protocol is correct for now boundary = msg.getparam('boundary') # print "boundary is %s" % boundary # now split message at boundaries mfile = multifile.MultiFile(strfp) mfile.push(msg.getparam("boundary")) while mfile.next(): submsg = mimetools.Message(mfile) try: data = cStringIO.StringIO() mimetools.decode(mfile, data, submsg.getencoding()) except ValueError: continue if submsg.gettype() == 'application/pgp-signature': print "This is the signature: " sys.stdout.write(data.getvalue() ) open("/tmp/body.asc", "wb").write(data.getvalue()) else: print "This is part of the body" sys.stdout.write(data.getvalue() ) open("/tmp/body.decoded", "wb").write(data.getvalue() ) mfile.seek(0) open("/home/clee/body", "wb").write(mfile.read()) mfile.pop() else: sys.stdout.write("Not a multipart/signed message\n") sys.stdout.write("The actual mime type is:\n") sys.stdout.write("getmaintype(): %s\n" % msg.getmaintype()) sys.stdout.write("getsubtype(): %s\n" % msg.getsubtype()) sys.stdout.write("getplist(): %s\n" % msg.getplist()) # [From RFC 2015] # # When the PGP digital signature is generated: # (1) The data to be signed must first be converted to its type/subtype # specific canonical form. For text/plain, this means conversion to an # appropriate character set and conversion of line endings to the # canonical sequence. # (2) An appropriate Content-Transfer-Encoding is then applied. Each line of # the encoded data MUST end with the canonical sequence. # (3) MIME content headers are then added to the body, each ending with the # canonical sequence. # (4) As described in [1], the digital signature MUST be calculated over both # the data to be signed and its set of content headers. # (5) The signature MUST be generated detached from the signed data so that # the process does not alter the signed data in any way.