# Twisted, the Framework of Your Internet # Copyright (C) 2001-2002 Matthew W. Lefkowitz # # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public # License as published by the Free Software Foundation. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Protocol support for twisted.mail.""" # twisted imports from twisted.protocols import pop3, smtp from twisted.internet import protocol # system imports import string class DomainSMTP(smtp.SMTP): """SMTP server that uses twisted.mail service's domains.""" def validateTo(self, user, success, failure): if not self.service.domains.has_key(user.dest.domain): failure(user) return self.service.domains[user.dest.domain].exists(user, success, failure) def startMessage(self, users): ret = [] for user in users: ret.append(self.service.domains[user.dest.domain].startMessage(user)) return ret class SMTPFactory(smtp.SMTPFactory): """A protocol factory for SMTP.""" def __init__(self, service): self.service = service def buildProtocol(self, addr): p = DomainSMTP() p.service = self.service p.factory = self return p class VirtualPOP3(pop3.POP3): """Virtual hosting POP3.""" domainSpecifier = '@' # Gaagh! I hate POP3. No standardized way # to indicate user@host. '@' doesn't work # with NS, e.g. def authenticateUserAPOP(self, user, digest): try: user, domain = string.split(user, self.domainSpecifier, 1) except ValueError: domain = '' if not self.service.domains.has_key(domain): raise pop3.POP3Error("no such domain %s" % domain) domain = self.service.domains[domain] mbox = domain.authenticateUserAPOP(user, self.magic, digest, domain) if mbox is None: raise pop3.POP3Error("bad authentication") return mbox class POP3Factory(protocol.ServerFactory): """POP3 protocol factory.""" def __init__(self, service): self.service = service def buildProtocol(self, addr): p = VirtualPOP3() p.service = self.service p.factory = self return p