2014-10-06 41 views
1

正如你可能最近看到我一直在努力获得一个简单的客户端/服务器TCP连接并运行,我可以切换到TLS的命令问题,根据Twisted示例为https://twistedmatrix.com/documents/14.0.0/core/howto/ssl.html#starttls-server,但已修改为使用证书身份验证。那么好消息是,现在起作用了!感谢@ Jean-PaulCalderone和@Glyph的帮助。扭曲的Python ESMTP邮件服务器/转储与TLS

但是,我现在想要将我的服务器端代码扩展/转换成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找到的t.m.s.ESMTP的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) 

提前感谢!

+0

https://twistedmatrix.com/documents/current/_downloads/emailserver.tac可能很有趣 – 2014-10-07 01:09:56

+0

很可能......您能否提醒,如何覆盖默认的服务器响应 - 例如,当客户端连接或250个来自客户端的EHLO响应? – 2014-10-07 15:20:51

+1

其中一些东西可以通过重写'ESMTP'的方法来定制。例如,对于220消息的文本有'greeting'方法。为了能够覆盖其他内容,您可能需要提交功能请求。 – 2014-10-08 00:15:06

回答

2

你不应该有你自己的TLSServer类。相反,直接使用ESMTP作为您的服务器类。您已经将ext_STARTTLS方法识别为有趣的 - 基本上,它已经实现了您的TLSServer在其方法lineReceived中具有的逻辑。

而不是做factory.options = ...,你会想在施工时通过ESMTP a contextFactory一个参数。在最简单的,你可以做这样的事情:

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

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

+0

再次感谢@Glyph - 我们现在正在进行我们需要的调整/定制! – 2014-10-13 08:45:15

+0

非常欢迎。听到那个消息很开心! – Glyph 2014-10-14 20:12:57