繁体   English   中英

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

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

因此,感谢这里的几个用户,我现在有一个(几乎)正在运行的SMTP服务器,该服务器支持根据需要从纯文本切换到TLS连接。 基本服务器代码为:

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)

如您所见-我创建了类mySMTP的对象实例(myESMTP)。 您可能会猜到,这是从扭曲的mail.py中的ESMTP派生而来(在custom_esmtp.py中),而后者又是从SMTP类派生的。我们已经为myESMTP类编写了几个函数重载,并且还会有更多的功能重载。

但是,在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)

因此,如果定义了self.portal,则该方法将在退出if条件之前返回-但是,如果未定义,它将引发SMTPBadSender错误。 SMTP类定义中没有定义门户的地方。

我注意到self.portal 确实在SMTPFactory类的init方法中定义-我们是否应该以某种方式使用它-如果是这样,有人可以解释这将如何影响我们的服务器代码吗? 就是说,即使这似乎并未将self.portal设置为任何“有意义的” ...

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

也许这是SMTP类定义中的错误? 似乎不太可能...也许我们只需要创建自己的覆盖版本的validateFrom,并在self.portal未定义的情况下删除代码以引发错误? 不过,我再次尝试了这一点-(删除了在if块之外生成错误的两行代码)-结果是“异常”。

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

一如既往的感谢!

因此,我发现了一个简单的答案-在我们的自定义ESMTP类中为ValidateFrom和ValidateTo创建重载定义! 效果很好...但是我不是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

我仍然不知道我是否应该以某种方式使用SMTPFactory。...我知道在此处在答案中提出问题不是一个好习惯,因此我将其保留为“如果有人有更好的建议,请务必说!”

暂无
暂无

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

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