1

Trying to filter mails through a Sieve function.

I would like to fetch an e-mail address indicated inside the body of the message, and not in the header. This address is (like the one in the header) after a From: field. After that, a copy of the email should be sent to this address. Messages filtered must also have Returned mail inside their subject.

This is my code, but not working...

        require ["body","copy","variables"];

        if header :contains "Subject" "Returned mail"
            {
            if body :content "text" :matches "From: *"
                {
                redirect :copy "${1}";
                }
            }

Can you please help me to fix that code ? Thank's !!

4

2 回答 2

2

切换回旧的 procmail

Procmail 确实支持在消息正文中进行匹配,如下所示:

:0H
* ^Subject: .*Returned mail
{
 :0B
 * ^From: \/.+@.+
 {
  ADDR=$MATCH
  :0 c
  * ADDR ?? ^[a-z0-9_-+.]+@[a-z0-9-+.]+$
  | $ADDR
 }
}

这涵盖了消息正文中以“发件人:”开头的行之后的所有内容。

:0B意味着必须在消息正文上进行下一次匹配

\/在表达式中开始记录到 $MATCH(内置变量)

匹配存储在 Procmail 变量 $ADDR 中,然后可以在后续的 procmail 脚本执行中永久访问。在子块中,它将:0 c消息传递(arbon 复制)到新匹配的目标地址。但请注意,此时无法安全地检查它是否真的是电子邮件地址。这也可能为远程代码执行留下漏洞。

还必须手动应用任何 X-Loop 保护技术,此示例未涵盖此技术

于 2017-11-09T20:31:48.017 回答
1

无法直接从消息正文中提取内容以进行进一步处理。Sieve 不会像${1}身体匹配那样填充变量。

RFC明确指出这绝不可能。

然而,有可能通过提供(过滤)消息来解决这个问题,该消息引发了一个单独的应用程序,如下所示,将所需的信息放入标题中。

想象一下原来的消息是:

To: my@second.tld
Subject: Test
From: other@example.tld
Date: Wed, 25 Oct 2017 16:22:05 +0200

Hi guy, here starts the body
This mail contains a important dynamic address

From: important@match.tld

wich has to be matched und processed by sieve

然后你的筛子可能看起来像这样:

require ["copy","variables","vnd.dovecot.filter"];

if header :contains "Subject" "Returned mail" {
    filter "bleed_from.py";
    if header :matches "Bleeded-From" "*" {
        redirect :copy "${1}";
    }
}

过滤器脚本“bleed_from.py”:

#!/usr/bin/python
import re
import email

# Read the mail from stdin
parser = email.FeedParser.FeedParser()
mail = None
for line in sys.stdin.readlines():
    parser.feed(line)
mail = parser.close()

# Grep the From out of the body and add it to the header
ret = re.findall("From: (.*)", mail.get_payload())
mail.add_header("Bleeded-From", ret[0])

# Return the message
print(mail.as_string())

这是一个非常简单的概念证明,仅适用于没有特殊字符的非多部分消息。否则此应用程序将崩溃。处理字符集会破坏这个例子的边缘。

于 2017-11-07T03:50:39.510 回答