summaryrefslogtreecommitdiff
path: root/src/leap/mail/imap/service/imap-server.tac
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/mail/imap/service/imap-server.tac')
-rw-r--r--src/leap/mail/imap/service/imap-server.tac178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/leap/mail/imap/service/imap-server.tac b/src/leap/mail/imap/service/imap-server.tac
new file mode 100644
index 0000000..1a4661b
--- /dev/null
+++ b/src/leap/mail/imap/service/imap-server.tac
@@ -0,0 +1,178 @@
+import ConfigParser
+import os
+
+from xdg import BaseDirectory
+
+from twisted.application import internet, service
+from twisted.internet.protocol import ServerFactory
+from twisted.mail import imap4
+from twisted.python import log
+
+from leap.common.check import leap_assert, leap_assert_type
+from leap.mail.imap.server import SoledadBackedAccount
+from leap.mail.imap.fetch import LeapIncomingMail
+from leap.soledad import Soledad
+
+# Some constants
+# XXX Should be passed to initializer too.
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+IMAP_PORT = 9930
+# The port in which imap service will run
+
+INCOMING_CHECK_PERIOD = 10
+# The period between succesive checks of the incoming mail
+# queue (in seconds)
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+class LeapIMAPServer(imap4.IMAP4Server):
+ """
+ An IMAP4 Server with mailboxes backed by soledad
+ """
+ def __init__(self, *args, **kwargs):
+ # pop extraneous arguments
+ soledad = kwargs.pop('soledad', None)
+ user = kwargs.pop('user', None)
+ leap_assert(soledad, "need a soledad instance")
+ leap_assert_type(soledad, Soledad)
+ leap_assert(user, "need a user in the initialization")
+
+ # initialize imap server!
+ imap4.IMAP4Server.__init__(self, *args, **kwargs)
+
+ # we should initialize the account here,
+ # but we move it to the factory so we can
+ # populate the test account properly (and only once
+ # per session)
+
+ # theAccount = SoledadBackedAccount(
+ # user, soledad=soledad)
+
+ # ---------------------------------
+ # XXX pre-populate acct for tests!!
+ # populate_test_account(theAccount)
+ # ---------------------------------
+ #self.theAccount = theAccount
+
+ def lineReceived(self, line):
+ log.msg('rcv: %s' % line)
+ imap4.IMAP4Server.lineReceived(self, line)
+
+ def authenticateLogin(self, username, password):
+ # all is allowed so far. use realm instead
+ return imap4.IAccount, self.theAccount, lambda: None
+
+
+class IMAPAuthRealm(object):
+ """
+ Dummy authentication realm. Do not use in production!
+ """
+ theAccount = None
+
+ def requestAvatar(self, avatarId, mind, *interfaces):
+ return imap4.IAccount, self.theAccount, lambda: None
+
+
+class LeapIMAPFactory(ServerFactory):
+ """
+ Factory for a IMAP4 server with soledad remote sync and gpg-decryption
+ capabilities.
+ """
+
+ def __init__(self, user, soledad):
+ self._user = user
+ self._soledad = soledad
+
+ theAccount = SoledadBackedAccount(
+ user, soledad=soledad)
+ self.theAccount = theAccount
+
+ def buildProtocol(self, addr):
+ "Return a protocol suitable for the job."
+ imapProtocol = LeapIMAPServer(
+ user=self._user,
+ soledad=self._soledad)
+ imapProtocol.theAccount = self.theAccount
+ imapProtocol.factory = self
+ return imapProtocol
+
+
+def initialize_soledad_mailbox(user_uuid, soledad_pass, server_url,
+ server_pemfile, token):
+ """
+ Initializes soledad by hand
+
+ :param user_uuid:
+ :param soledad_pass:
+ :param server_url:
+ :param server_pemfile:
+ :param token:
+
+ :rtype: Soledad instance
+ """
+
+ base_config = BaseDirectory.xdg_config_home
+ secret_path = os.path.join(
+ base_config, "leap", "soledad", "%s.secret" % user_uuid)
+ soledad_path = os.path.join(
+ base_config, "leap", "soledad", "%s-mailbox.db" % user_uuid)
+
+ _soledad = Soledad(
+ user_uuid,
+ soledad_pass,
+ secret_path,
+ soledad_path,
+ server_url,
+ server_pemfile,
+ token)
+
+ return _soledad
+
+
+#######################################################################
+# XXX STUBBED! We need to get this in the instantiation from the client
+
+config = ConfigParser.ConfigParser()
+config.read([os.path.expanduser('~/.config/leap/mail/mail.conf')])
+
+userID = config.get('mail', 'address')
+privkey = open(os.path.expanduser('~/.config/leap/mail/privkey')).read()
+nickserver_url = ""
+
+d = {}
+
+for key in ('uid', 'passphrase', 'server', 'pemfile', 'token'):
+ d[key] = config.get('mail', key)
+
+soledad = initialize_soledad_mailbox(
+ d['uid'],
+ d['passphrase'],
+ d['server'],
+ d['pemfile'],
+ d['token'])
+
+# import the private key ---- should sync it from remote!
+from leap.common.keymanager.openpgp import OpenPGPScheme
+opgp = OpenPGPScheme(soledad)
+opgp.put_ascii_key(privkey)
+
+from leap.common.keymanager import KeyManager
+keym = KeyManager(userID, nickserver_url, soledad, d['token'])
+
+
+factory = LeapIMAPFactory(userID, soledad)
+
+application = service.Application("LEAP IMAP4 Local Service")
+imapService = internet.TCPServer(IMAP_PORT, factory)
+imapService.setServiceParent(application)
+
+fetcher = LeapIncomingMail(
+ keym,
+ soledad,
+ factory.theAccount)
+
+
+internet.TimerService(
+ INCOMING_CHECK_PERIOD,
+ fetcher.fetch).setServiceParent(application)