所以,多亏了几个用户在这里,我现在有一个(几乎)工作的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
感谢如初!