繁体   English   中英

扭曲的Python ESMTP邮件服务器/带有TLS的转储

[英]Twisted Python ESMTP mail server / dump with TLS

就像你们中有些人最近看到的那样,我正在努力建立和运行简单的Client / Server TCP连接,根据https://twistedmatrix.com/上的Twisted示例,我可以在发出命令时切换到TLS。 document / 14.0.0 / core / howto / ssl.html#starttls-server ,但已修改为使用证书身份验证。 好吧,好消息是,现在可以使用了! 感谢@ Jean-PaulCalderone和@Glyph的帮助。

但是,我现在想将服务器端代码扩展/转换为ESMTP服务器-即,让客户端连接,服务器随后将STARTTLS公布为EHLO响应的一部分,如果客户端随后以STARTTLS响应,则协商并切换到安全连接。 相信我需要修改下面我的服务器代码中的“ TLSServer”类,以继承自twisted.mail.smtp.ESMTP而不是twisted.protocols.basic.LineReceiver-但不是100%肯定。 此外, http: //twistedmatrix.com/documents/12.1.0/api/twisted.mail.smtp.ESMTP.html上找到的tmsESMTP的API文档在地面上有些薄(很多未记录的方法)。

任何人都可以a)告诉我关于修改现有服务器代码的继承是否正确,以及b)提供诸如do_EHLO和ext_STARTTLS之类的方法的一些解释吗?

最终,我正在寻找一种SMTP服务器,该服务器将接受(安全的)客户端连接,从客户端接收邮件,并将邮件转储到文件中。

我现有的服务器代码:

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

class TLSServer(LineReceiver):
    def lineReceived(self, line):
        print("received: " + line)
        if line == "STARTTLS":
            print("-- Switching to TLS")
            self.sendLine('READY')
            self.transport.startTLS(self.factory.options)

def main(reactor):
    caCertFile = open("/some/path/to/cacert.pem","r")
    certFile = open("/some/path/to/server.crt","r")
    keyFile = open("/some/path/to/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)
    factory = protocol.Factory.forProtocol(TLSServer)
    factory.options = ssl.CertificateOptions(privateKey=pKey, certificate=cert, trustRoot=caCert)
    endpoint = endpoints.TCP4ServerEndpoint(reactor, 8000)
    endpoint.listen(factory)
    return defer.Deferred()

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

提前致谢!

您不应该拥有自己的TLSServer类。 而是直接将ESMTP用作服务器类。 您已经将ext_STARTTLS方法标识为有趣的方法-基本上,它已经实现了TLSServerlineReceived方法中具有的逻辑。

而不是执行factory.options = ... ,您将需要在构造时向ESMTP传递一个contextFactory参数。 简单地说,您可以执行以下操作:

sslCtxFactory = ssl.CertificateOptions(...)
factory = Factory.forProtocol(lambda: ESMTP(contextFactory=sslCtxFactory))

相信 ESMTP默认将STARTTLS作为扩展名进行宣传-至少,这就是对ESMTP.extensions()方法的实现的快速阅读对我说的。

暂无
暂无

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

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