Twisted SMTP服务器,添加SSL支持,2个工厂?

时间:2014-10-17 11:37:01

标签: ssl smtp twisted factory

最近问过Twisted mail server with TLS - no portal?看来我正在咆哮错误的树 - 所以现在提出一个新的修订问题似乎是恰当和恰当的。

所以我试图扩展在http://twistedmatrix.com/documents/current/_downloads/emailserver.tac找到的基本SMTP服务器示例以支持SSL连接。我可以创建一个ssl Context Factory,如下所示(代码取消了之前的努力:

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)

所以现在我有来自emailserver.tac的SMTP工厂和我上面的sslCtxFactory。在我的旧代码中,我创建了一个ESMTP类的对象,如下所示:

myESMTP = ESMTP(contextFactory=sslCtxFactory)
factory = protocol.Factory.forProtocol(lambda: mySMTP(contextFactory=sslCtxFactory))
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8001)
endpoint.listen(factory)

但由于此代码不使用门户等,因此ESMTP的类定义中的某些方法/函数由于未定义各种属性而失败(例如self.delivery,self.portal)。

所以我试图了解如何在mailserver.tac代码中实现我的sslCtxFactory - 同时仍按照mailserver.tac使用portal / realm,以确保扭曲的ESMTP中的方法上课没有失败。

但我怎样才能把这两家工厂和#34;一起带来?

由于

1 个答案:

答案 0 :(得分:1)

这看起来很奇怪:

myESMTP = ESMTP(contextFactory=sslCtxFactory)
factory = protocol.Factory.forProtocol(lambda: mySMTP(contextFactory=sslCtxFactory))

Twisted提供的ESMTP类的实例不可调用。我想你一定有这样的意思:

from functools import partial

myESMTP = partial(ESMTP, contextFactory=sslCtxFactory)
factory = protocol.Factory.forProtocol(mySMTP)

假设......

ESMTP类尊重self.portal属性的身份验证和授权行为。你需要做的就是设置它。

SMTPFactorySMTP个实例的工厂,它将协议的portal属性设置为其自身(工厂的)portal属性的值。唯一的问题是它会使SMTP个实例而不是ESMTP个实例。

幸运的是,它(工厂)尊重其实例化类的protocol属性。

如果你要写:

portal = Portal(...)
myESMTP = partial(ESMTP, contextFactory=...)
factory = SMTPFactory.forProtocol(protocol=myESMTP, portal=portal)
那么你会有一个工厂:

  • 创建ESMTP的实例
  • 在实例化contextFactory=...时将ESMTP传递给初始化程序
  • portal实例实例化之后设置ESMTP属性,使用传递给forProtocol的值。