带有TLS的扭曲邮件服务器-没有门户?
问题描述
因此,多亏了这里的几个用户,我现在有了一个(几乎)可以工作的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)。正如您可能猜到的那样,这是从Twisted的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.port,则该方法在退出if条件之前返回-但如果未定义,它将引发SMTPBadSender错误。并且在SMTP类定义中没有定义该门户。
我注意到self.portal是否在init方法中为SMTPFactory类定义了--我们是否应该以某种方式使用它--如果是这样的话,有人能解释一下这将如何影响我们的服务器代码吗?也就是说,即使这样似乎也没有将self.port设置为任何"有意义的"内容...
definit(自身,门户=无): Self.portal=门户
这可能是SMTP类定义中的错误?看起来不太可能。也许我们只需要创建我们自己的覆盖版本的valiateFrom,并删除代码以在self.portal未定义时引发错误?不过,我再次尝试了这一点--(删除了在if块之外生成错误的两行代码)--结果是"不寻常的"...mail from: me@localhost
250 Sender address accepted
rcpt to:you@somedomain.test
503 Must have sender before recipient
一如既往的感谢!
ESMTP
所以我找到了一个似乎很简单的答案--只需在我们的定制推荐答案类中为ValiateFrom和ValiateTo创建重载定义!效果很好..。但我不是百分之百相信这是最"正确"的解决方案--我现在可以提交我的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...我知道在这里,边回答边提问不是一种好的做法,所以我只会把它留为"如果有人有更好的建议,请一定要说!"
相关文章