一次,一个简单,直截了当的问题!有人可以建议我如何访问" p.startedTLS"在下面的ConsoleSmtpFactory代码中,来自ConsoleMessage类?
我希望能够转发到文件,作为邮件的一部分,是否通过TLS传递...
所以换句话说 - 在Twisted中,您的应用程序代码可以访问协议属性吗? (我认为这就是我想要问的问题?!?
我甚至尝试过使用全局变量(让我们暂时忽略编码标准问题!)......没有快乐。 " buildProtocol"我在下面的CustomSmtpFactory中调用p.StartedTLS设置为true - 我认为事后很明显 - 它构建了工厂,并且在收到" STARTTLS"后,在ext_STARTTLS(在ESMTP类中)中设置了startsTLS。来自客户的命令。
所以我想我的问题更准确的是 - 如何在协议建立之后访问协议属性?
谢谢!
class ConsoleMessageDelivery:
implements(custom_esmtp.IMessageDelivery)
def receivedHeader(self, helo, origin, recipients):
by = helo[1]
from_ = origin
target = ""
for u in recipients:
target = target + u.__str__() + "\n"
"""
Want to add something here like:
tls=protcol.startTLS
then add "tls" to the returned string below
"""
return "Client: %s\nFrom: %s\nTo: %s\n\n" % (by, from_, target)
def validateFrom(self, helo, origin):
return origin
def validateTo(self, user):
return lambda: ConsoleMessage()
#return None
class ConsoleMessage:
implements(custom_esmtp.IMessage)
def __init__(self):
self.lines = []
def lineReceived(self, line):
self.lines.append(line)
def dumpMsgToFile(self, msgData):
inx = 0
filePrefix = datetime.datetime.utcnow().strftime("%Y%m%d%H%M%S%f")
while os.path.exists(filePrefix + "-" + str(inx)):
inx = inx + 1
fileName = filePrefix + "-" + str(inx)
msgFile = open("./" + fileName,"a")
msgFile.writelines(msgData)
msgFile.write ("\n----------------------\n")
msgFile.close()
def eomReceived(self):
print "\n".join(self.lines)
self.dumpMsgToFile(self.lines)
self.lines = None
return defer.succeed(None)
def connectionLost(self):
# There was an error, throw away the stored lines
self.lines = None
class ConsoleSMTPFactory(custom_esmtp.SMTPFactory):
protocol = custom_esmtp.mySMTP
def __init__(self, *a, **kw):
custom_esmtp.SMTPFactory.__init__(self, *a, **kw)
self.delivery = ConsoleMessageDelivery()
def buildProtocol(self, addr):
try:
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()
except IOError as e:
print "Failed in reading files({0}): {1}".format(e.strerrror)
except:
print "Unknown error"
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)
p = custom_esmtp.SMTPFactory.buildProtocol(self, addr)
p.delivery = self.delivery
# p.challengers = {"LOGIN": LOGINCredentials, "PLAIN": PLAINCredentials}
p.ctx=sslCtxFactory
print (p.startedTLS) # << returns true / false depending on if switched to TLS
return p
class SimpleRealm:
implements(IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if smtp.IMessageDelivery in interfaces:
return smtp.IMessageDelivery, ConsoleMessageDelivery(), lambda: None
raise NotImplementedError()
def main():
from twisted.application import internet
from twisted.application import service
portal = Portal(SimpleRealm())
checker = InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("guest", "password")
portal.registerChecker(checker)
a = service.Application("Console SMTP Server")
internet.TCPServer(5000, ConsoleSMTPFactory(portal)).setServiceParent(a)
return a
application = main()
答案 0 :(得分:1)
这可能是SMTP实施中缺少的一项功能。我认为origin
是一个字符串的IP地址。它可能应该是一个功能更全面的地址对象,不仅代表客户端的对等地址,还代表用于与客户端通信的传输。
或者它可能是SMTP协议实现与门户(或交付对象或交付工厂对象)交互的方式更加普遍的失败。也许它应该暴露更多的信息开始(而不是一个解决方案,它保持这一点,直到,例如,receivedHeader
被调用)。
无论如何,基本答案是这是一个不受支持的功能(它会在Twisted问题跟踪器中提出一个好的功能请求)。您可以通过覆盖receivedHeader
子类上的ESMTP
(阅读基本实现)来找到一种方法来破解您想要的功能,以便为交付对象提供必要的额外信息。