为什么 procmail 不符合该规则?

为什么 procmail 不符合该规则?

我有以下规则,将所有带有可疑附件的电子邮件发送到专用文件夹:

# Emails with attachments
:0
* ^Content-Type: multipart/
{
  :0 B
  * ^Content-Type: application/(zip|x-zip-compressed)|\
    ^Content-Type:.*name=.*\.(zip|exe|rar|rtf|docm)|\
    ^Content-.*attachment.*name=.*\.(zip|exe|rar|rtf|docm)|\
    ^Content-.*application.octet-stream.*name=.*\.(zip|exe|rar|rtf|docm)
  $L/.3_my._quarantine/
}

然而,我刚刚注意到一封带有 zip 附件的电子邮件从中溜了出来,我不知道为什么(my@email 和 myemail 包含我的电子邮件和我混淆的主机):

X-Priority: 3 (Normal)
From: [email protected]
To: "[email protected]"
 <[email protected]>
Subject: Attached File
Date:Mon, 16 May 2016 17:16:47 +0530
Message-Id: <272843899191709486.0001.scannerTxNo.0051@scannerF04EF6.myemail.com>
Mime-Version: 1.0
Content-Type: multipart/mixed;
 boundary="53594271E1EBE7BBDAF4BBA9"

--53594271E1EBE7BBDAF4BBA9
Content-Type: application/x-compressed;
 name="[email protected]_3602848_97891076672132.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="[email protected]_3602848_97891076672132.zip"

AFAICS^Content-Type:.*name=.*\.(zip|exe|rar|rtf|docm)应该匹配吗?是因为引号吗?

答案1

您链接的帖子确实指出折叠标题处理得正确,但这个配方检查的是主体,而不是标题。

Procmail 的一个缺陷是它不能正确识别 MIME 结构;这对于现代邮件过滤器来说是一个重要的补充;但遗憾的是,Procmail 的开发早在 21 世纪初就停止了(而且在那之前就已经停止了一次,当时原来的开发人员放弃了)。

作为一种粗略的解决方法,您可以在 MIME 边界上临时拆分 MIME 多部分消息,并将每个部分提供给单独的 Procmail 配方,但这很快变得脆弱和复杂(理论上,MIME 消息可以任意深度嵌套,但对于大多数实际目的,您只需要向下递归一到两级 - 超出此范围的任何内容可能都是反弹或类似的东西,而不是您正在检查的消息的直接特征)。

由于您的正则表达式只有几个可能的(现实的!)分割点,因此您可以重构它以考虑可能的换行符:

:0
* ^Content-type: multipart/
{
  :0B
  * ^Content-Type: application/(zip|x-zip-compressed)|\
    ^Content-Type:.*(($)[   ].*)*name=.*\.(zip|exe|rar|rtf|docm)|\
    ^Content-.*attachment.*(($)[    ].*)*name=.*\.(zip|exe|rar|rtf|docm)|\
    ^Content-.*application.octet-stream.*(($)[  ].*)*name=.*\.(zip|exe|rar|rtf|docm)
  $L/.3_my._quarantine/
}

您会注意到(($)[ ].*)*在几个地方添加了一个字符。这表示可能有一个换行符 ( ($)),后面跟着一个空白字符(制表符或空格,[ ]),后面跟着任意字符,重复零次或多次。

(顺便说一句,通过评分来调试这可能会稍微容易一些:

  :0 B
  * 1^1 ^Content-Type: application/(zip|x-zip-compressed)
  * 1^1 ^Content-Type:.*(($)[   ].*)*name=.*\.(zip|exe|rar|rtf|docm)
  * 1^1 ^Content-.*attachment.*(($)[    ].*)*name=.*\.(zip|exe|rar|rtf|docm)
  * 1^1 ^Content-.*application.octet-stream.*(($)[  ].*)*name=.*\.(zip|exe|rar|rtf|docm)
  ...

通过它,您可以在日志中看到VERBOSE=yes此复杂的多正则表达式配方中每个单独的正则表达式的结果。)

如果您需要完全无懈可击的配方,也许可以用 Python 或 Perl(或 Ruby 或……随便什么)编写一个简单的脚本来规范化 MIME 结构。我记得emil很久以前有一个工具可以做这样的事情,但它从来没有很完善,更不用说有很好的文档了。(事实上,如果我没记错的话,它是专门为插入 pre-MIME 而设计的sendmail,几乎不可能用于其他任何事情。)

相关内容