简体   繁体   English

带有TLS的扭曲邮件服务器-没有门户?

[英]Twisted mail server with TLS - no portal?

So thanks to a couple of users here, I now have a (almost) working SMTP Server that supports switching from plain text to TLS connection as required. 因此,感谢这里的几个用户,我现在有一个(几乎)正在运行的SMTP服务器,该服务器支持根据需要从纯文本切换到TLS连接。 Basic server code is: 基本服务器代码为:

from twisted.internet import ssl, protocol, defer, task, endpoints
from twisted.protocols.basic import LineReceiver
from twisted.python.modules import getModule
from OpenSSL.crypto import load_privatekey, load_certificate, FILETYPE_PEM
from custom_esmtp import mySMTP

def main(reactor):
    caCertFile = open("/opt/tesa/etc/certs/CA/cacert.pem","r")
    certFile = open("/opt/tesa/etc/certs/server/server.crt","r")
    keyFile = open("/opt/tesa/etc/certs/server/server.key","r")
    caCertData = caCertFile.read()
    pKeyData = keyFile.read()
    certData = certFile.read()
    caCert = ssl.Certificate.loadPEM(caCertData)
    cert = load_certificate(FILETYPE_PEM, certData)
    pKey = load_privatekey(FILETYPE_PEM, pKeyData)
    sslCtxFactory = ssl.CertificateOptions(privateKey=pKey, certificate=cert, trustRoot=caCert)
    myESMTP = mySMTP(contextFactory=sslCtxFactory)
    factory = protocol.Factory.forProtocol(lambda: mySMTP(contextFactory=sslCtxFactory))
    endpoint = endpoints.TCP4ServerEndpoint(reactor, 8001)
    endpoint.listen(factory)
    return defer.Deferred()

if __name__ == '__main__':
    import starttls_server
    task.react(starttls_server.main)

As you can see - I create an object instance (myESMTP) of class mySMTP. 如您所见-我创建了类mySMTP的对象实例(myESMTP)。 This as you can probably guess is derived (in custom_esmtp.py) from ESMTP in twisted's mail.py - which is in turn derived from the SMTP class - we have written a couple of function overloads for the myESMTP class, with more to come. 您可能会猜到,这是从扭曲的mail.py中的ESMTP派生而来(在custom_esmtp.py中),而后者又是从SMTP类派生的。我们已经为myESMTP类编写了几个函数重载,并且还会有更多的功能重载。

However, in twisted's mail.py, the SMTP class definition has a method "validateFrom": 但是,在twisted的mail.py中,SMTP类定义具有方法“ validateFrom”:

def validateFrom(self, helo, origin):
    <<snip>>
    if self.portal:

        result = self.portal.login(
            cred.credentials.Anonymous(),
            None,
            IMessageDeliveryFactory, IMessageDelivery)

        def ebAuthentication(err):
            """
            Translate cred exceptions into SMTP exceptions so that the
            protocol code which invokes C{validateFrom} can properly report
            the failure.
            """
            if err.check(cred.error.UnauthorizedLogin):
                print ("Unauth Login")
                exc = SMTPBadSender(origin)
            elif err.check(cred.error.UnhandledCredentials):
                exc = SMTPBadSender(
                    origin, resp="Unauthenticated senders not allowed")
            else:
                return err
            return defer.fail(exc)

        result.addCallbacks(
            self._cbAnonymousAuthentication, ebAuthentication)

        def continueValidation(ignored):
            """
            Re-attempt from address validation.
            """
            return self.validateFrom(helo, origin)

        result.addCallback(continueValidation)
        return result

    raise SMTPBadSender(origin)

So if self.portal is defined, then the method returns before exiting the if condition - but if it is undefined, it will raise an SMTPBadSender error. 因此,如果定义了self.portal,则该方法将在退出if条件之前返回-但是,如果未定义,它将引发SMTPBadSender错误。 And there is nowhere in the SMTP class definition that portal is defined. SMTP类定义中没有定义门户的地方。

I've noticed that self.portal does get defined in the init method for the SMTPFactory class - should we be using this somehow - if so, can someone explain how this would affect our server code? 我注意到self.portal 确实在SMTPFactory类的init方法中定义-我们是否应该以某种方式使用它-如果是这样,有人可以解释这将如何影响我们的服务器代码吗? That said, even this doesn't seem to set self.portal to anything "meaningful"... 就是说,即使这似乎并未将self.portal设置为任何“有意义的” ...

def init (self, portal = None): self.portal = portal def init (自我,门户=无):self.portal =门户

Perhaps this a bug in the SMTP class definition? 也许这是SMTP类定义中的错误? Seems unlikely... Perhaps we just need to create our own overridden version of validateFrom, and remove the code to raise an error if self.portal is undefined? 似乎不太可能...也许我们只需要创建自己的覆盖版本的validateFrom,并在self.portal未定义的情况下删除代码以引发错误? Again though, I've tried this - (removing the 2 lines of code that generate the error outside of the if block) - and the result was "unusual".... 不过,我再次尝试了这一点-(删除了在if块之外生成错误的两行代码)-结果是“异常”。

mail from: me@localhost
250 Sender address accepted
rcpt to:you@somedomain.test
503 Must have sender before recipient

Thanks as ever! 一如既往的感谢!

So I've found what seems to be a simple answer - simply create overloaded definitions for ValidateFrom and ValidateTo in our custom ESMTP class! 因此,我发现了一个简单的答案-在我们的自定义ESMTP类中为ValidateFrom和ValidateTo创建重载定义! Works nicely enough... but I'm not 100% convinced this is the most "correct" solution - I can now submit my ehlo, mail from, and rcpt to... but when I try to submit "data": 效果很好...但是我不是100%确信这是最“正确”的解决方案-我现在可以提交ehlo,邮件发件和rcpt到...但是当我尝试提交“数据”时:

2014-10-15 09:49:40+0000 [mySMTP,0,127.0.0.1] Unhandled Error
        Traceback (most recent call last):
          File "/usr/lib64/python2.6/site-packages/twisted/internet/tcp.py", line 220, in _dataReceived
            rval = self.protocol.dataReceived(data)
          File "/usr/lib64/python2.6/site-packages/twisted/protocols/basic.py", line 454, in dataReceived
            self.lineReceived(line)
          File "/usr/lib64/python2.6/site-packages/twisted/mail/smtp.py", line 568, in lineReceived
            return getattr(self, 'state_' + self.mode)(line)
          File "/usr/lib64/python2.6/site-packages/twisted/mail/smtp.py", line 582, in state_COMMAND
            method('')
        --- <exception caught here> ---
          File "/usr/lib64/python2.6/site-packages/twisted/mail/smtp.py", line 733, in do_DATA
            msg = msgFunc()
        exceptions.AttributeError: User instance has no __call__ method

I still wonder if I should be using SMTPFactory in some way.... I know it's not good practice here to ask a question within an answer, so I'll just leave it as "if anyone has a better suggestion, please do say!" 我仍然不知道我是否应该以某种方式使用SMTPFactory。...我知道在此处在答案中提出问题不是一个好习惯,因此我将其保留为“如果有人有更好的建议,请务必说!”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM