summaryrefslogtreecommitdiff
path: root/src/leap/email/smtp/smtprelay.py
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2012-10-31 11:57:08 -0200
committerdrebs <drebs@leap.se>2012-10-31 11:58:55 -0200
commit196ec0e1eefbd50860771de0c8d2b488c30c6506 (patch)
treeb899dd42bb6825a53ee9bfda052c5e8480773583 /src/leap/email/smtp/smtprelay.py
parent148f81aa9214eeae6a870912e252c119a4c6472c (diff)
relay loops forever with twistd
Diffstat (limited to 'src/leap/email/smtp/smtprelay.py')
-rw-r--r--src/leap/email/smtp/smtprelay.py156
1 files changed, 0 insertions, 156 deletions
diff --git a/src/leap/email/smtp/smtprelay.py b/src/leap/email/smtp/smtprelay.py
deleted file mode 100644
index cbcff43a..00000000
--- a/src/leap/email/smtp/smtprelay.py
+++ /dev/null
@@ -1,156 +0,0 @@
-from zope.interface import implements
-from twisted.mail import smtp
-from twisted.internet.protocol import ServerFactory
-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):
- """
- Factory for an SMTP server with encrypted relaying capabilities.
- """
-
- def buildProtocol(self, addr):
- "Return a protocol suitable for the job."
- smtpProtocol = smtp.SMTP(SMTPDelivery())
- smtpProtocol.factory = self
- return smtpProtocol
-
-
-class SMTPDelivery(object):
- """
- Validate email addresses and handle message delivery.
- """
-
- implements(smtp.IMessageDelivery)
-
- def receivedHeader(self, helo, origin, recipients):
- myHostname, clientIP = helo
- headerValue = "by %s from %s with ESMTP ; %s" % (
- myHostname, clientIP, smtp.rfc822date( ))
- # email.Header.Header used for automatic wrapping of long lines
- return "Received: %s" % Header(headerValue)
-
- def validateTo(self, user):
- """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)
-
- def validateFrom(self, helo, originAddress):
- # accept mail from anywhere. To reject an address, raise
- # smtp.SMTPBadSender here.
- return originAddress
-
-
-class EncryptedMessage():
- """
- 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):
- self.user = user
- self.getSMTPInfo()
- self.lines = []
- self.gpg = GPGWrapper()
-
- def lineReceived(self, line):
- """Store email DATA lines as they arrive."""
- self.lines.append(line)
-
- def eomReceived(self):
- """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):
- print "Connection lost unexpectedly!"
- # unexpected loss of connection; don't save
- del(self.lines)
-
- def sendSuccess(self, r):
- print r
- reactor.stop()
-
- def sendError(self, e):
- print e
- reactor.stop()
-
- def sendMail(self):
- 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,
- self.smtp_username,
- self.user.dest.addrstr,
- StringIO(msg),
- d)
- # the next call is TSL-powered!
- reactor.connectTCP(self.SMTP_HOSTNAME, self.SMTP_PORT, factory)
- d.addCallback(self.sendSuccess)
- d.addErrback(self.sendError)
- 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('/media/smtp-info.txt', 'r')
- self.smtp_host = f.readline().rstrip()
- self.smtp_port = f.readline().rstrip()
- self.smtp_username = f.readline().rstrip()
- self.smtp_password = f.readline().rstrip()
- 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(2500, SMTPFactory())
- reactor.run()