def test_attach_text(): mail = encoding.MailBase() mail.attach_text("This is some text.", 'text/plain') msg = encoding.to_message(mail) assert msg.get_payload(0).get_payload() == "This is some text." assert encoding.to_string(mail) mail.attach_text("<html><body><p>Hi there.</p></body></html>", "text/html") msg = encoding.to_message(mail) assert len(msg.get_payload()) == 2 assert encoding.to_string(mail)
def test_to_message_from_message_with_spam(): mb = mailbox.mbox("tests/spam") fails = 0 total = 0 for msg in mb: try: m = encoding.from_message(msg) out = encoding.to_message(m) assert repr(out) m2 = encoding.from_message(out) for k in m: if '@' in m[k]: assert_equal(parseaddr(m[k]), parseaddr(m2[k])) else: assert m[k].strip() == m2[k].strip(), "%s: %r != %r" % ( k, m[k], m2[k]) assert not m[k].startswith(u"=?") assert not m2[k].startswith(u"=?") assert m.body == m2.body, "Bodies don't match" assert_equal(len(m.parts), len(m2.parts), "Not the same number of parts.") for i, part in enumerate(m.parts): assert part.body == m2.parts[ i].body, "Part %d isn't the same: %r \nvs\n. %r" % ( i, part.body, m2.parts[i].body) total += 1 except encoding.EncodingError, exc: fails += 1
def test_to_message_from_message_with_spam(): mb = mailbox.mbox("tests/spam") fails = 0 total = 0 for msg in mb: try: m = encoding.from_message(msg) out = encoding.to_message(m) assert repr(out) m2 = encoding.from_message(out) for k in m: if '@' in m[k]: assert_equal(parseaddr(m[k]), parseaddr(m2[k])) else: assert m[k].strip() == m2[k].strip(), "%s: %r != %r" % (k, m[k], m2[k]) assert not m[k].startswith(u"=?") assert not m2[k].startswith(u"=?") assert m.body == m2.body, "Bodies don't match" assert_equal(len(m.parts), len(m2.parts), "Not the same number of parts.") for i, part in enumerate(m.parts): assert part.body == m2.parts[i].body, "Part %d isn't the same: %r \nvs\n. %r" % (i, part.body, m2.parts[i].body) total += 1 except encoding.EncodingError, exc: fails += 1
def test_MailBase(): the_subject = u'p\xf6stal' m = encoding.MailBase() m['To'] = "testing@localhost" m['Subject'] = the_subject assert m['To'] == "testing@localhost" assert m['TO'] == m['To'] assert m['to'] == m['To'] assert m['Subject'] == the_subject assert m['subject'] == m['Subject'] assert m['sUbjeCt'] == m['Subject'] msg = encoding.to_message(m) m2 = encoding.from_message(msg) assert_equal(len(m), len(m2)) for k in m: assert m[k] == m2[k], "%s: %r != %r" % (k, m[k], m2[k]) for k in m.keys(): assert k in m del m[k] assert not k in m
def test_attach_file(): mail = encoding.MailBase() png = open("tests/lamson.png").read() mail.attach_file("lamson.png", png, "image/png", "attachment") msg = encoding.to_message(mail) payload = msg.get_payload(0) assert payload.get_payload(decode=True) == png assert payload.get_filename() == "lamson.png", payload.get_filename()
def UPLOADPK(msg, address=None, host=None): res={} sender=collapse_rfc2231_value(msg['from']) m=sendere.match(sender) if m: res['sender_name'], res['sender_mail']=m.groups() else: res['sender_mail']=sender for mpart in msg.walk(): ispgp=False part=to_message(mpart) if part.get_content_type()=='text/plain': # cut of preamble inblock=False lines=part.get_payload(decode=True).split('\n') i=0 while i<len(lines): if not inblock: if lines[i].strip()=='-----BEGIN PGP PUBLIC KEY BLOCK-----': inblock=True i+=2 else: if lines[i].strip()=='-----END PGP PUBLIC KEY BLOCK-----': break i+=1 if i<len(lines): ispgp=True elif part.get_content_type()=='application/pgp-keys': ispgp=True if ispgp: res=getpgpmeta(part.get_payload(decode=True)) ret=gpg('--import', _err_to_out=True, _in=part.get_payload(decode=True)) #logging.info(ret) modifiers={'fresh': False, 'abbreved': False, 'singleid': False, 'tidy': False, } if res['datetime']>datetime.datetime.utcnow()-datetime.timedelta(days=10): modifiers['fresh']=True if len(res['ids'])<2: modifiers['singleid']=True if len(res['ids'][0]['email'].split('@')[0])<9: modifiers['abbreved']=True if len([1 for x in res['sigs'] if x['st'] not in ['Positive certification of a User ID and Public Key packet', 'Subkey Binding Signature']])==0: modifiers['tidy']=True res['award']=award("You uploaded your public key.\n%s" % '\n'.join(["%s [%s]" % (k,'X' if v else ' ') for k,v in modifiers.items()])) #logging.info(res) welcome = view.respond(res, "pkuploaded.msg", From=sendermail, To=sender, Subject="Welcome to the Privacy Challenge") view.attach(welcome, {}, "pubkey.asc", filename="my key", content_type="application/pgp-keys") relay.deliver(welcome)
def test_MIMEPart(): text1 = encoding.MIMEPart("text/plain") text1.set_payload("The first payload.") text2 = encoding.MIMEPart("text/plain") text2.set_payload("The second payload.") image_data = open("tests/lamson.png").read() img1 = encoding.MIMEPart("image/png") img1.set_payload(image_data) img1.set_param('attachment','', header='Content-Disposition') img1.set_param('filename','lamson.png', header='Content-Disposition') encoders.encode_base64(img1) multi = encoding.MIMEPart("multipart/mixed") for x in [text1, text2, img1]: multi.attach(x) mail = encoding.from_message(multi) assert mail.parts[0].body == "The first payload." assert mail.parts[1].body == "The second payload." assert mail.parts[2].body == image_data encoding.to_message(mail)
def test_MIMEPart(): text1 = encoding.MIMEPart("text/plain") text1.set_payload("The first payload.") text2 = encoding.MIMEPart("text/plain") text2.set_payload("The second payload.") image_data = open("tests/lamson.png").read() img1 = encoding.MIMEPart("image/png") img1.set_payload(image_data) img1.set_param('attachment', '', header='Content-Disposition') img1.set_param('filename', 'lamson.png', header='Content-Disposition') encoders.encode_base64(img1) multi = encoding.MIMEPart("multipart/mixed") for x in [text1, text2, img1]: multi.attach(x) mail = encoding.from_message(multi) assert mail.parts[0].body == "The first payload." assert mail.parts[1].body == "The second payload." assert mail.parts[2].body == image_data encoding.to_message(mail)
def doxer(msg, mailid=None, host=None): try: keyid=get_val('dox-mailid',":%s" % mailid, second)[:-(len(mailid)+1)] except TypeError: #print >>sys.stderr, 'nomailid' return # no such mailid pwd=get_state(keyid, 'prod.pdf.pass') #logging.info("pwd "+pwd) if not pwd: add_state(keyid, 'prod.pdf.err',"I got a mail, but i was not aware of the password at that time. try to resend it after telling me the password please.") return err = None for mpart in msg.walk(): part=to_message(mpart) #if part.get_content_maintype() == 'multipart' or len(part.get_payload(decode=True)) < 268125: if part.get_content_maintype() == 'multipart': #print >>sys.stderr, 'skip', len(part.get_payload(decode=True) or ''), part.get_content_maintype() continue size = len(part.get_payload(decode=True)) if (size < 200000 or size > 310000): continue hash=hashlib.sha256() def hupdate(data): # workaround for http://bugs.python.org/issue17481 hash.update(data) ret=gpg('-d', '--passphrase', pwd, _ok_code=[0,2], _in=part.get_payload(decode=True), _out=hupdate) if ret.exit_code!=0: add_state(keyid, 'prod.pdf.err',"got a mail, but gpg had problems, try fixing the problem and resend the mail. gpg said this\n"+err) break #logging.info('ret '+str(ret)) #logging.info('stderr '+ret.stderr) err=str(ret.stderr) # for flushing the process? #print >>sys.stderr, 'err', err if hash.hexdigest() == '658be96015645fe1d646fd167c1ac3bd372360530191d574ace5870c5aeb132f': add_state(keyid, 'prod.pdf.done','1') break else: add_state(keyid, 'prod.pdf.err',"got a mail, but it wasn't quite what i expected, so i dropped it.") break else: add_state(keyid, 'prod.pdf.err',"got a mail, but there was nothing found that looked like a reasonably sized pgp payload")
def test_content_encoding_headers_are_maintained(): inmail = encoding.from_file(open("tests/signed.msg")) ctype, ctype_params = inmail.content_encoding['Content-Type'] assert_equal(ctype, 'multipart/signed') # these have to be maintained for key in ['protocol', 'micalg']: assert key in ctype_params # these get removed for key in encoding.CONTENT_ENCODING_REMOVED_PARAMS: assert key not in ctype_params outmsg = encoding.to_message(inmail) ctype, ctype_params = encoding.parse_parameter_header(outmsg, 'Content-Type') for key in ['protocol', 'micalg']: assert key in ctype_params, key
def to_message(self): """ Figures out all the required steps to finally craft the message you need and return it. The resulting message is also available as a self.base attribute. What is returned is a Python email API message you can use with those APIs. The self.base attribute is the raw lamson.encoding.MailBase. """ del self.base.parts[:] if self.Body and self.Html: self.multipart = True self.base.content_encoding['Content-Type'] = ( 'multipart/alternative', {}) if self.multipart: self.base.body = None if self.Body: self.base.attach_text(self.Body, 'text/plain') if self.Html: self.base.attach_text(self.Html, 'text/html') for args in self.attachments: self._encode_attachment(**args) elif self.Body: self.base.body = self.Body self.base.content_encoding['Content-Type'] = ('text/plain', {}) elif self.Html: self.base.body = self.Html self.base.content_encoding['Content-Type'] = ('text/html', {}) return encoding.to_message(self.base)
def to_message(self): """ Figures out all the required steps to finally craft the message you need and return it. The resulting message is also available as a self.base attribute. What is returned is a Python email API message you can use with those APIs. The self.base attribute is the raw lamson.encoding.MailBase. """ del self.base.parts[:] if self.Body and self.Html: self.multipart = True self.base.content_encoding['Content-Type'] = ('multipart/alternative', {}) if self.multipart: self.base.body = None if self.Body: self.base.attach_text(self.Body, 'text/plain') if self.Html: self.base.attach_text(self.Html, 'text/html') for args in self.attachments: self._encode_attachment(**args) elif self.Body: self.base.body = self.Body self.base.content_encoding['Content-Type'] = ('text/plain', {}) elif self.Html: self.base.body = self.Html self.base.content_encoding['Content-Type'] = ('text/html', {}) return encoding.to_message(self.base)
def to_message(self): """ Converts this to a Python email message you can use to interact with the python mail APIs. """ return encoding.to_message(self.base)
def otrfp(msg, address=None, host=None): sender=collapse_rfc2231_value(msg['from']) m=sendere.match(sender) res={} if m: res['sender_name'], res['sender_mail']=m.groups() else: res['sender_mail']=sender for mpart in msg.walk(): part=to_message(mpart) # cut of preamble inblock=False lines=part.get_payload(decode=True).split('\n') i=0 #logging.info(lines) while i<len(lines): if not inblock: if lines[i].strip()=='-----BEGIN PGP SIGNED MESSAGE-----' or lines[i].strip()=='-----BEGIN PGP MESSAGE-----': inblock=True i+=2 else: if lines[i].strip()=='-----END PGP SIGNATURE-----' or lines[i].strip()=='-----END PGP MESSAGE-----': break i+=1 #logging.info(i) if i<len(lines): res.update(getpgpmeta(part.get_payload(decode=True))) ret=gpg('-d', _ok_code=[0,2], _in=part.get_payload(decode=True)) #logging.info('ret '+str(ret)) #logging.info('stderr '+ret.stderr) res['msg']='\n'.join(["> %s" % x for x in ret.stdout.split('\n')]) # extra points, # - no named recipient # - signed #logging.info(res['keys']) modifiers={'sekrit': False, 'signed': False} if len([x for x in res['keys'] if x['key_id']!="0000000000000000"])==0: modifiers['sekrit']=True else: logging.warn([x for x in res['keys'] if x['key_id']!="0000000000000000"]) signed={} for line in ret.stderr.split('\n'): if line.startswith('gpg: Signature made '): # gpg: Signature made Fri 11 May 2012 04:43:04 PM CEST using RSA key ID XXXXXX m=signed1re.match(line) if m: #logging.info(m.groups()) signed['date']=dparse(str(m.group(1))) signed['algo']=m.group(2) signed['key_id']=m.group(3) elif line.startswith('gpg: Good signature from '): # gpg: Good signature from "name <mail>" m=signed2re.match(line) if m: #logging.info(m.groups()) signed['name']=m.group(1) signed['mail']=m.group(2) modifiers['signed']=True if not signed: plssign = view.respond(res, "plssign.msg", From=sendermail, To=sender, Subject="OTR fingerprint help") relay.deliver(plssign) continue res['signed']=signed res['award']=award("you bootstrapped OTR trust using PGP.\n%s" % '\n'.join(["%s [%s]" % (k,'X' if v else ' ') for k,v in modifiers.items()])) #logging.info(res) jid=None fp=None secret=None for line in to_message(from_string(ret.stdout)).get_payload(decode=True).split('\n'): if not line.strip(): continue if line=='-- ': break if jid and fp: secret=line break #logging.info("line "+line) m=otrfpre.match(line) if m: #logging.info(m.groups()) jid, fp = m.group(1), m.group(2) if jid and fp: with FileLock('%s/otr/otr/%s.fpr' % (basepath, botjid)): fr=open('%s/otr/otr/%s.fpr' % (basepath, botjid), 'r') fw=open('%s/otr/otr/%s.fpr.new' % (basepath, botjid), 'w') for line in fr: #logging.info(line) #logging.info("%s\t%s\tjabber\t%s" % (jid, # botjid, # fp.lower().replace(' ',''))) if line.startswith("%s\t%s\tjabber\t%s" % (jid, botjid, fp.lower().replace(' ',''))): fw.write("%s\t%s\tjabber\t%s\ttrust\n" % (jid, botjid, fp.lower().replace(' ',''))) else: fw.write(line) fw.close() fr.close() os.unlink('%s/otr/otr/%s.fpr' % (basepath, botjid)) shutil.move('%s/otr/otr/%s.fpr.new' % (basepath, botjid), '%s/otr/otr/%s.fpr' % (basepath, botjid)) if secret: fs=open('%s/otr/otr/%s.s' % (basepath, jid), 'w') fs.write("%s %s" % (signed['key_id'], secret)) fs.close() welcome = view.respond(res, "otrtrust.msg", From=sendermail, To=sender, Subject="OTR fingerprint received") relay.deliver(welcome)
def test_to_message_encoding_error(mp_init): mp_init.side_effect = raises_TypeError test = encoding.from_file(open("tests/borked.msg")) msg = encoding.to_message(test)
def DECODER(msg, address=None, host=None): sender=collapse_rfc2231_value(msg['from']) m=sendere.match(sender) res={} if m: res['sender_name'], res['sender_mail']=m.groups() else: res['sender_mail']=sender for mpart in msg.walk(): part=to_message(mpart) # cut of preamble inblock=False lines=part.get_payload(decode=True).split('\n') i=0 #logging.info(lines) while i<len(lines): if not inblock: if lines[i].strip()=='-----BEGIN PGP MESSAGE-----': inblock=True i+=2 else: if lines[i].strip()=='-----END PGP MESSAGE-----': break i+=1 #logging.info(i) if i<len(lines): res.update(getpgpmeta(part.get_payload(decode=True))) ret=gpg('-d', _ok_code=[0,2], _in=part.get_payload(decode=True)) #logging.info('ret '+str(ret)) #logging.info('stderr '+ret.stderr) res['msg']='\n'.join(["> %s" % x for x in ret.stdout.split('\n')]) # extra points, # - no named recipient # - signed modifiers={'sekrit': False, 'signed': False} #logging.info(res['keys']) if len([x for x in res['keys'] if x['key_id']!="0000000000000000"])==0: modifiers['sekrit']=True signed={} for line in ret.stderr.split('\n'): if line.startswith('gpg: Signature made '): # gpg: Signature made Fri 11 May 2012 04:43:04 PM CEST using RSA key ID XXXXXX m=signed1re.match(line) if m: #logging.info(m.groups()) signed['date']=dparse(str(m.group(1))) signed['algo']=m.group(2) signed['key_id']=m.group(3) elif line.startswith('gpg: Good signature from '): # gpg: Good signature from "name <mail>" m=signed2re.match(line) if m: #logging.info(m.groups()) signed['name']=m.group(1) signed['mail']=m.group(2) modifiers['signed']=True if signed: res['signed']=signed res['award']=award("You sent an encrypted mail.\n%s" % '\n'.join(["%s [%s]" % (k,'X' if v else ' ') for k,v in modifiers.items()])) #logging.info(res) welcome = view.respond(res, "pgpmail.msg", From=sendermail, To=sender, Subject="Encrypted mail received") relay.deliver(welcome)