dnl dnl Проверка поля Content-Transfer-Encoding в multipart сообщениях dnl dnl данные правила применяется в acl_smtp_mime, доступном, начиная с exiscan-acl-4.30-16 dnl dnl для описания поведения MTA используется файл confCONFDIR/access-transfer-encodings dnl в нем хранится информация трех типов: dnl 1. какие charset'ы будут маскироваться звездочкой dnl 2. кодирование различных X-Mailer dnl 3. собственно правила для разных триплетов charset/transfer-encoding/mailer dnl dnl charset'ы указываются в виде: dnl charset=<название charset'а> dnl dnl например: dnl charset=koi8-r dnl charset=windows-1251 dnl dnl для сообщений с этими charset'ами будут использованы правила, у которых в качестве charset dnl будет указана звездочка. обычно необходимо перечислить все кириллические (8-битные) charset'ы dnl dnl значение полей X-Mailer кодируется в виде регулярного выражения с префиксом "mailer=": dnl \N^(?i)mailer=$\N : dnl dnl кодовое название мейлера mailer_name не должно содержать пробельных символов и символа ":" dnl dnl пример: dnl \N^(?i)mailer=SquirrelMail\s*\(.+\)$\N : squirrelmail dnl dnl т. е. для сообщений со значением X-Mailer, соответствующим регулярному выражению dnl /^SquirrelMail\s*\(.+\)$/, будут применяться все правила, у которых в триплете в качестве dnl mailer'а будет указано "squirrelmail" dnl dnl собственно, сами правила указываются в виде: dnl || : <действие> : <сообщение> dnl dnl 1. в качестве charset может быть указан либо конкретный charset, либо звездочка. тогда dnl правило будет применено для charset'ов, указанных с префиксом "charset=" dnl 2. в качестве transfer-encoding'а можно использовать "7bit", "8bit" или пустое значение, dnl которое воспринимается как отсутствие поля Content-Transfer-Encoding dnl 3. в качестве mailer'а указывается то кодовое название mailer'а, которое было описано с dnl префиксом "mailer=" dnl указание mailer'а может быть опущено вместе с предшествующим разделителем "|". тогда правило dnl будет применено ко сообщениям без учета поля X-Mailer dnl dnl в качестве "действия" могут выступать: dnl ok - принимать сообщения с данным transfer-encoding-ом dnl warn - добавлять в заголовки сообщения поле X-Warn-Charset dnl текст значения поля может быть указан через двоеточие dnl reject - не принимать сообщения с данным charset-ом dnl текст сообщения об ошибке может быть указан через двоеточие dnl deny - синоним для reject dnl fakereject - возврат отправителю ошибки 5xx с продолжением обработки сообщения dnl quarantine - сообщение будет сохранено в карантине и не будет доставлено получателю dnl dnl действие quarantine можно указывать вместе с reject или deny через пробел dnl dnl примеры: dnl dnl отвергнуть все сообщения с charset=windows-1251 и Content-Transfer-Encoding: 7bit dnl для остальных проверяемых charset-ов добавляется поле X-Warn-Encoding:, dnl кроме собщений, отосланных с помощью X-Mailer: PocoMail dnl \N^(?i)mailer=PocoMail\s.+$\N : pocomail dnl *|7bit|pocomail : ok dnl windows-1251|7bit : deny : 5.7.1 broken Content-Transfer-Encoding detected dnl *|7bit : warn dnl dnl отвергать все сообщения с charset=windows-1251 без поля Content-Transfer-Encoding dnl для остальных проверяемых charset-ов вставлять поле X-Warn-Encoding: со значением dnl этого поля по умолчанию dnl для сообщений с X-Mailer: SquirrelMail вставляется поле X-Warn-Encoding: с отдельным dnl значением dnl dnl \N^(?i)mailer=SquirrelMail\s*\(.+\)$\N : squirrelmail dnl *||squirrelmail : warn : squirrelmail does not add field Content-Transfer-Encoding :-( dnl windows-1251| : deny : 5.7.1 Content-Transfer-Encoding field expected dnl *| : warn : Content-Transfer-Encoding field expected dnl define(`confFAKE_REJECT', `YES')dnl # Проверка поля Content-Transfer-Encoding # в multipart сообщениях # правила приведены в access-transfer-encodings # если Content-Type соответствует text/plain или text/html warn set acl_m0 = skip condition = ${if or{\ {eq{$mime_content_type}{text/plain}}\ {eq{$mime_content_type}{text/html}}\ }{yes}{no}} # ищем charset в списке проверяемых condition = ${lookup{charset=${lc:$mime_charset}}\ lsearch{CONFDIR/access-transfer-encodings}{yes}{no}} set acl_m0 = check # ищем название mailer set acl_m2 = ${if eq{$h_X-Mailer:}{}{$h_User-Agent:}{$h_X-Mailer:}} # определяем mailer и ищем для него кодовое название set acl_m1 = ${lookup{mailer=${acl_m2}}\ wildlsearch{CONFDIR/access-transfer-encodings}{$value}{\ ${lookup{mailer=$h_User-Agent:}\ wildlsearch{CONFDIR/access-transfer-encodings}{$value}{}}\ }} # ищем действие по триплету charset|transfer-encoding|mailer # порядок поиска: # charset|transfer-encoding|mailer # *|transfer-encoding|mailer # charset|transfer-encoding # *|transfer-encoding warn condition = ${if eq{$acl_m0}{check}{yes}{no}} set acl_m1 = ${lookup{${lc:$mime_charset}|$mime_content_transfer_encoding|$acl_m1}\ lsearch{CONFDIR/access-transfer-encodings}{$value}{\ ${lookup{*|$mime_content_transfer_encoding|$acl_m1}\ lsearch{CONFDIR/access-transfer-encodings}{$value}{\ ${lookup{${lc:$mime_charset}|$mime_content_transfer_encoding}\ lsearch{CONFDIR/access-transfer-encodings}{$value}{\ ${lookup{*|$mime_content_transfer_encoding}\ lsearch{CONFDIR/access-transfer-encodings}{$value}{\ }}\ }}\ }}\ }} set acl_m2 = ${lc:${extract{1}{:}{$acl_m1}}} set acl_m2 = ${sg{${sg{$acl_m2}{\N^\s+\N}{}}}{\N\s*$\N}{}} set acl_m1 = ${extract{2}{:}{$acl_m1}} set acl_m1 = ${sg{${sg{$acl_m1}{\N^\s+\N}{}}}{\N\s*$\N}{}} # если для данного триплета выбрано действие warn warn condition = ${if eq{$acl_m0}{check}{yes}{no}} condition = ${if eq{$acl_m2}{warn}{yes}{no}} log_message = ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected (charset: $mime_charset; X-Mailer: ${acl_m2}; multipart)}\ {broken Content-Transfer-Encoding detected (charset: $mime_charset; X-Mailer: ${acl_m2}; multipart)}\ } message = X-Warn-Encoding: \ ${if eq{$acl_m1}{}\ {${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected}\ {broken Content-Transfer-Encoding detected}\ }}\ {${sg{$acl_m1}{\N^\d+\.\d+\.\d+\s*\N}{}}}\ } # если для данного триплета выбрано действие deny или reject без quarantine deny condition = ${if eq{$acl_m0}{check}{yes}{no}} condition = ${if match{$acl_m2}{\N^.*(deny|reject)\N}{yes}{no}} condition = ${if eq{$acl_m2}{fakereject}{no}{yes}} condition = ${if match{$acl_m2}{\N^.*quarantine\N}{no}{yes}} log_message = ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected (charset: $mime_charset; X-Mailer: ${acl_m2}; multipart)}\ {broken Content-Transfer-Encoding detected (charset: $mime_charset;\ Content-Transfer-Encoding: $mime_content_transfer_encoding; X-Mailer: ${acl_m2}; multipart)}\ } message = ${if eq{$acl_m1}{}\ {5.7.1 ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected}\ {broken Content-Transfer-Encoding detected}\ }}\ {$acl_m1}\ } (${message_id}) logwrite = original recipients: $recipients # если для данного триплета выбрано действие deny или reject с quarantine warn condition = ${if eq{$acl_m0}{check}{yes}{no}} condition = ${if match{$acl_m2}{\N^.*(deny|reject)\N}{yes}{no}} condition = ${if eq{$acl_m2}{fakereject}{no}{yes}} condition = ${if match{$acl_m2}{\N^.*quarantine\N}{yes}{no}} set acl_m6 = message quarantined: \ ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected \ (charset: $mime_charset; X-Mailer: ${acl_m2}; multipart)}\ {broken Content-Transfer-Encoding detected \ (charset: $mime_charset; Content-Transfer-Encoding: $mime_content_transfer_encoding; \ X-Mailer: ${acl_m2}; multipart)}\ }\ |X-Quarantine-Encoding: \ ${if eq{$acl_m1}{}\ {${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected}\ {broken Content-Transfer-Encoding detected}\ }}\ {${sg{$acl_m1}{\N^\d+\.\d+\.\d+\s*\N}{}}}\ }\ |${if eq{$acl_m1}{}\ {5.7.1 ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected}\ {broken Content-Transfer-Encoding detected}\ }}\ {$acl_m1}\ } (${message_id}) set acl_m17 = quarantined # если для данного триплета выбрано действие fakereject warn condition = ${if eq{$acl_m0}{check}{yes}{no}} condition = ${if eq{$acl_m2}{fakereject}{yes}{no}} set acl_m6 = fakerejected: \ ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected \ (charset: $mime_charset; X-Mailer: ${acl_m2}; multipart)}\ {broken Content-Transfer-Encoding detected \ (charset: $mime_charset; Content-Transfer-Encoding: $mime_content_transfer_encoding; \ X-Mailer: ${acl_m2}; multipart)}\ }\ |X-Warn-Encoding: \ ${if eq{$acl_m1}{}\ {${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected}\ {broken Content-Transfer-Encoding detected}\ }}\ {${sg{$acl_m1}{\N^\d+\.\d+\.\d+\s*\N}{}}}\ }\ |${if eq{$acl_m1}{}\ {5.7.1 ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected}\ {broken Content-Transfer-Encoding detected}\ }}\ {$acl_m1}\ } (${message_id}) # если для данного триплета выбрано действие quarantine без reject или deny warn condition = ${if eq{$acl_m0}{check}{yes}{no}} condition = ${if match{$acl_m2}{\N^.*(deny|reject)\N}{no}{yes}} condition = ${if eq{$acl_m2}{quarantine}{yes}{no}} log_message = message quarantined: \ ${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected (charset: $mime_charset; X-Mailer: ${acl_m2}; multipart)}\ {broken Content-Transfer-Encoding detected (charset: $mime_charset;\ Content-Transfer-Encoding: $mime_content_transfer_encoding; X-Mailer: ${acl_m2}; multipart)}\ } message = X-Quarantine-Encoding: \ ${if eq{$acl_m1}{}\ {${if eq{$mime_content_transfer_encoding}{}\ {Content-Transfer-Encoding field expected}\ {broken Content-Transfer-Encoding detected}\ }}\ {${sg{$acl_m1}{\N^\d+\.\d+\.\d+\s*\N}{}}}\ } set acl_m17 = quarantined