先贴一段 twisted 框架下实现 Milter 协议解析的核心函数 :)
-
class MilterServer(Protocol):
-
def init_dataReceived(self):
-
self.lastdata = ""
-
self.len = 0
-
-
def __init__(self):
-
self.init_dataReceived()
-
-
# 注意:实践中发现一次 recv 中包括了两个完整的 packet; 而且理论上存在
-
# 一个 packet 需要两次 recv 才能取出来的可能
-
def dataReceived(self, data):
-
if len(data): print len(data)
-
if self.lastdata != "":
-
data = self.lastdata + data
-
if self.len != 0:
-
if self.len <= len(data):
-
next = data[self.len:]
-
self.proc(data[:self.len])
-
self.init_dataReceived()
-
if len(next) > 0:
-
self.dataReceived(next)
-
else: #继续等待输入
-
self.lastdata = data
-
else:
-
if len(data) < 4:
-
self.lastdata = data
-
else:
-
self.len = struct.unpack(">i", data[:4])[0]
-
self.lastdata = data[4:]
-
print self.len, len(self.lastdata)
-
self.dataReceived("")
-
-
def proc(self, data):
-
...
-
...
上述代码在线上曾短时间的跑了跑,协议解析的逻辑部分应该是没有问题滴(稳妥起见,目前我们实际用的还是 libmilter 的 python binding)
实现 Milter Server 需要注意的一个事情就是:和 SMTP 一样,是要能支持在一次
connection 中完成多次 transaction 的!!还有 abort 命令,实际上就是一次 RSET 请求。
由于相当然的以为 eom (EndOfMessage) 事件后会话就应该结束了,结果碰到了问题怎么也想不出头绪,绕了一个多星期的弯路才找到程序的毛病所在。
另外在 Postfix 实现里面,自定义的 replymsg 的格式要求严格遵循 RFC,格式是:
"%s %s %s" % (code, Enhanced-Status-Code, msg)
E-S-C 的第一个数字要和 code 的第一个数字保持一致,见 postfix 源代码 milter8.c 里 SMFIR_REPLYCODE 的处理
仔细阅读了一下 sendmail 的 Milter Technical Overview,原来在 DATA 阶段,MTA 是需要把信件整个接受下来以后,再依次发给各个 Milter 的,而且是给一个 Milter 完整的传送完一个 message 后,再接着向下一个 Milter 发送。以前一直理解有误,觉得应该是 on-the-fly 的把数据依次传递给 Milter,这样效率最高.
评论
Hi, 请问能提供一下libmilter 的
Hi,
请问能提供一下libmilter 的 python binding 的资料吗?我亦很想学习一下milter, 谢谢!
就是 pymilter 吧.
就是 pymilter 吧.
Hi, 请问是不是指http://www.bmsi.com
Hi,
请问是不是指http://www.bmsi.com/python/milter.html#overview?搞了半天,这个项目看来是挺难安装的,blog主能否指点一下?
另发现一个类似的项目http://code.google.com/p/ppymilter/,可惜文档不够丰富,主要是对python 了解不深,还是不懂用。
Milter 完整的传送完一个 message
Milter 完整的传送完一个 message 后,再接着向下一个 Milter 发送,我想这是要配合Milter 能修改邮件内容这个功能。
你说的很有道理... 请问是在那里工作啊? hehe
你说的很有道理... 请问是在那里工作啊? hehe
hahah.......
hahah....... 小弟目前乃是下岗人仕,我想用Milter 实现一个功能,如下:
本域用户发来的邮件,return-path 与 from 要一致,否则拒绝。外域用户发来的邮件,return-path 与 from 不一致时,在邮件头做标记,SA 然后根据标记加分。
请问您认为以上想法,有否实现价值?
return-path 是在 MDA
return-path 是在 MDA 投递到本地的时候,加上去的 Header,通常在用户看到的信内容第一行。在 MTA 处理的过程中,照理是不会出现 Return-Path 的
简历一份给我?qiuyingbo@sohu-inc.com
你说的没错。我主要意思是在smtp
你说的没错。我主要意思是在smtp 会话阶段,利用milter 对mail from: reply-to: from: 进行一定的限制,以克制一下那种被利用作退信攻击的情况。
简历的事没有问题,下午我整理一下发给你,谢谢您!
已发送,请查收。
已发送,请查收。