Почему 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 прекратилась еще в начале 2000-х (и уже один раз до этого, когда ушел первоначальный разработчик).

В качестве грубого решения вы можете временно разделить составное сообщение 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давным-давно существовал инструмент под названием , который делал что-то вроде этого, но он никогда не был хорошо известен, не говоря уже о хорошей документации. (На самом деле, IIRC он был разработан специально для подключения к pre-MIME sendmailи его было почти невозможно использовать для чего-либо еще.)

Связанный контент