扭曲的邮件服务器使用TLS - 没有门?(Twisted mail server with TLS

2019-10-21 03:35发布

所以,多亏了几个用户在这里,我现在有一个(几乎)工作的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)。 这你可能也从ESMTP猜测是派生(在custom_esmtp.py)在扭曲的mail.py - 这是依次由SMTP类派生的 - 我们已经写了几个函数重载为myESMTP类,有更多的惊喜。

然而,在扭曲的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定义,则该方法退出,如果条件之前返回 - 但如果它是不确定的,它会引发一个SMTPBadSender错误。 而无处在SMTP类定义门户的定义。

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

DEF 的init(自,门户=无):self.portal =门户

也许在SMTP类定义这个错误? 似乎不太可能。也许我们只需要创建自己的覆盖validateFrom的版本,并删除代码,如果self.portal未定义引发错误? 再次,虽然,我已经试过这 - (除去2行代码生成如果块之外的误差) - ,结果为“异常” ....

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

感谢如初!

Answer 1:

所以,我发现了什么似乎是一个简单的答案 - 只是我们自定义的ESMTP类创建ValidateFrom和ValidateTo超载的定义! 作品很好足够了...但我不是100%确信这是最“正确”的解决方案 - 我现在可以提交我的EHLO,从邮件,和RCPT TO ......但是当我试图提交“数据”:

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 ....我知道这不是好习惯这里的答案中问一个问题,所以我就离开它,因为“如果任何人有更好的建议,请不要说!”



文章来源: Twisted mail server with TLS - no portal?