From 148f81aa9214eeae6a870912e252c119a4c6472c Mon Sep 17 00:00:00 2001 From: drebs Date: Mon, 29 Oct 2012 11:49:15 -0200 Subject: send encrypted mail --- src/leap/email/smtp/smtprelay.py | 62 +++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/leap/email/smtp/smtprelay.py b/src/leap/email/smtp/smtprelay.py index 10020a54..cbcff43a 100644 --- a/src/leap/email/smtp/smtprelay.py +++ b/src/leap/email/smtp/smtprelay.py @@ -5,6 +5,8 @@ from twisted.internet import reactor from twisted.internet import defer from email.Header import Header from StringIO import StringIO +import gnupg +import re class SMTPFactory(ServerFactory): @@ -26,9 +28,6 @@ class SMTPDelivery(object): implements(smtp.IMessageDelivery) - def __init__(self): - self.gpgkey = '' - def receivedHeader(self, helo, origin, recipients): myHostname, clientIP = helo headerValue = "by %s from %s with ESMTP ; %s" % ( @@ -40,7 +39,7 @@ class SMTPDelivery(object): """Assert existence of GPG public key for a recipient.""" # for now just accept any receipient print "Accepting mail for %s..." % user.dest - return lambda: EncryptedMessage(user, self.gpgkey) + return lambda: EncryptedMessage(user) def validateFrom(self, helo, originAddress): # accept mail from anywhere. To reject an address, raise @@ -50,19 +49,19 @@ class SMTPDelivery(object): class EncryptedMessage(): """ - Receive plaintext from client, encrypt it and send message to - recipients. + Receive plaintext from client, encrypt it and send message to a + recipient. """ implements(smtp.IMessage) SMTP_HOSTNAME = "mail.riseup.net" SMTP_PORT = 25 - def __init__(self, user, gpgkey): + def __init__(self, user): self.user = user - self.gpgkey = gpgkey self.getSMTPInfo() self.lines = [] + self.gpg = GPGWrapper() def lineReceived(self, line): """Store email DATA lines as they arrive.""" @@ -72,6 +71,9 @@ class EncryptedMessage(): """Encrypt and send message.""" print "Message data complete." self.lines.append('') # add a trailing newline + self.received = self.lines[0] + self.lines = self.lines[1:] + self.encrypt() return self.sendMail() def connectionLost(self): @@ -88,11 +90,11 @@ class EncryptedMessage(): reactor.stop() def sendMail(self): - self.lines = [self.lines[0]] + \ - ["From: %s" % self.user.orig.addrstr] + \ - ["To: %s" % self.user.dest.addrstr] + \ - self.lines[1:] - msg = '\n'.join(self.lines) + lines = [self.received] + \ + ["From: %s" % self.user.orig.addrstr] + \ + ["To: %s" % self.user.dest.addrstr] + \ + [self.cyphertext] + msg = '\n'.join(lines) d = defer.Deferred() factory = smtp.ESMTPSenderFactory(self.smtp_username, self.smtp_password, @@ -104,14 +106,16 @@ class EncryptedMessage(): reactor.connectTCP(self.SMTP_HOSTNAME, self.SMTP_PORT, factory) d.addCallback(self.sendSuccess) d.addErrback(self.sendError) - #reactor.run() return d + def encrypt(self): + fp = self.gpg.get_fingerprint(self.user.dest.addrstr) + self.cyphertext = str(self.gpg.encrypt('\n'.join(self.lines), [fp])) # this will be replaced by some other mechanism of obtaining credentials # for SMTP server. def getSMTPInfo(self): - f = open('/var/tmp/smtp-info.txt', 'r') + f = open('/media/smtp-info.txt', 'r') self.smtp_host = f.readline().rstrip() self.smtp_port = f.readline().rstrip() self.smtp_username = f.readline().rstrip() @@ -119,8 +123,34 @@ class EncryptedMessage(): f.close() +class GPGWrapper(): + """ + This is a temporary class for handling GPG requests, and should be + replaced by a more general class used throughout the project. + """ + + GNUPG_HOME = "~/.config/leap/gnupg" + GNUPG_BINARY = "/usr/bin/gpg" # this has to be changed based on OS + + def __init__(self): + self.gpg = gnupg.GPG(gnupghome=self.GNUPG_HOME, gpgbinary=self.GNUPG_BINARY) + + def get_fingerprint(self, email): + """ + Find user's fingerprint based on their email. + """ + for key in self.gpg.list_keys(): + for uid in key['uids']: + if re.search(email, uid): + return key['fingerprint'] + + def encrypt(self, data, recipient): + return self.gpg.encrypt(data, recipient) + + + # run server if __name__ == "__main__": import sys - reactor.listenTCP(25, SMTPFactory()) + reactor.listenTCP(2500, SMTPFactory()) reactor.run() -- cgit v1.2.3