[exim-conf] dlfunc: проба пера

Victor Ustugov victor на corvax.kiev.ua
Пн Дек 25 19:59:20 EET 2006


приветствую

ввиду хронической зацикленности противников exim на его монолитности
появилась идея реализовать новый для exim'а функционал с помощью dlfunc

после прочтения документации, примеров с http://www.ols.es/exim/dlext/,
была реализована динамически загружаемая библиотека для работы из exim с
демонизированным вариантом DSPAM из acl_smtp_data:
http://mta.org.ua/exim/dlfunc/dspam/dspam.c

отличия от patch'а
http://mta.org.ua/exim/patches/exim-4.63-dspam/patch-src::dspam-4.63.patch
заключаются в том, что нет необходимости пересобирать exim для
добавления нового функционала.

правда, с двумя "но":

1. exim нужно один раз пересобрать с EXPAND_DLFUNC=yes

для RedHat/Fedora в моем последнем spec файле
http://mta.org.ua/exim-4.63-conf/redhat/exim-4.63-6.corvax/specs/exim.spec
есть специальная опция. нужно либо указать "--with dlfunc" в командной
строке для rpmbuild либо (при сборке exim с помощью набора скриптов из
каталога redhat конфигуратора) добавить в файл
redhat/exim-4.63-6.corvax/Makefile.local строку
RPMBUILD_OPTIONS+= --with dlfunc

для сборки порта FreeBSD с EXPAND_DLFUNC=yes нужно в
/usr/ports/mail/exim/files скопировать
http://mta.org.ua/exim-4.63-conf/patches/exim-4.63-dlfunc/patch-src::EDITME-DLFUNC.patch
и пересобрать порт. необходимость накладывания этого патча состоит в
том, что в /usr/ports/mail/exim/Makefile нет пока опции для управления
EXPAND_DLFUNC

2. у меня не было особого желания писать набор функций для записи и
чтения из TCP и UNIX domain сокетов по LTMP. поэтому я использовал код,
написанный Хазелем. для этого надо в двух файлах немного изменить
описание трех функций.

для RedHat/Fedora при сборке пакета с вышеуказанным spec файлом нужно
использовать параметр
--with lmtp_extern

для FreeBSD есть патч:
http://mta.org.ua/exim-4.63-conf/patches/exim-4.63-lmtp-extern/patch-src::lmtp-extern-4.63.patch

данный патч конфликтует с патчем
http://mta.org.ua/exim-4.63-conf/patches/exim-4.63-dspam/patch-src::dspam-4.63.patch
т. к. в нем производятся те же самые действия над описаниями функций.
делить patch-src::dspam-4.63.patch на два патча мне было лениво.
при сборке пакета на RedHat/Fedora конфликт устраняется автоматически,
при сборке порта FreeBSD с патчем patch-src::dspam-4.63.patch нужно
удалить из каталога с патчами файл patch-src::lmtp-extern-4.63.patch
с другой стороны, необходимость таких действий маловероятна, т. к. она
возникнет только при желании собрать exim как с поддержкой dlfunc для
работы с dspam из динамически загружаемой библиотеки так и с поддержкой
работы с dspam непосредсвенно из exiscan_acl.


! специально для использующих sendmail/postfix/qmail/other MTA и
зацикленных на монолитности exim'а повторюсь:

первый патч - это просто включение в Makefile один раз возможности
работы с функциями из динамически загружаемых бибилиотек, а второй - это
результат моей лени при реализации конкретной библиотеки. если вопрос о
возможности реализации в exim принципиально нового функционала без
пересборки бинарника встанет ребром, я таки перенесу ручками функции
работы с LTMP непосредственно в код своей библиотеки.


итак, с приготовлениями вроде все ясно. теперь сборка самой библиотеки.

для сборки библиотеки нужен путь на исходные тексты exim'а
тут лежит простенький Makefile:
http://mta.org.ua/exim/dlfunc/dspam/Makefile

тестовая сборка проводилась на Fedora, поэтому в первой строке Makefile
путь вычисляется исходя из специфики этой OS


использование функции dspam из динамически загружаемой библиотеки
exim-ext-dspam.so:

тут лежит пример:
http://mta.org.ua/exim/dlfunc/dspam/configure-example

привожу его в отдельном файле, т. к. в письме длинные строки наверняка
будут перенесены

итак, сначала выполняем функцию dspam из библиотеки
/usr/local/libexec/exim/exim-ext-dspam.so, передавая ей четыре
параметра: параметры сокета (в случае UNIX domain сокета просто
указывается путь к файлу сокета), DSPAM ident, признак игнорирования
временных ошибок при работе с DSPAM и имя DSPAM пользователя:

 warn set acl_m0 = ${dlfunc{/usr/local/libexec/exim/exim-ext-dspam.so}\
      {dspam}{127.0.0.1 24}{dspam на corvax.falbi.kiev.ua}{1}{dspam}}

далее (если было указано игнорирование временных ошибок при работе с
DSPAM) проверяем результат выполнения функции и выводим соответствующие
сообщения в лог:
 warn condition = ${if eq{$acl_m0}{}{yes}{no}}
  logwrite = DSPAM check failed
 warn condition = ${if match{$acl_m0}{\N^dspam dlfunc:\s*\N}{yes}{no}}
  logwrite = DSPAM check defer: ${sg{$acl_m0}{\N^dspam dlfunc:\s*\N}{}}
  set acl_m0      =


далее парсим возвращенное значение и извлекаем из него различные
составляющие ответа DSPAM:

 warn condition = ${if eq{$acl_m0}{}{no}{yes}}
  set acl_m1 = ${if match{$acl_m0}\
  {\N^DSPAM answer:
(.+\r?\n)*X-Daemon-Classification:\s*(\S+)(.*\r?\n)*.*$\N}{$2}{}}
  logwrite = DSPAM check: X-Daemon-Classification value ${if
eq{$acl_m1}{}{not found}{is $acl_m1}}
 warn condition = ${if eq{$acl_m0}{}{no}{yes}}
  set acl_m1 = ${if match{$acl_m0}\
  {\N^DSPAM answer:
(.+\r?\n)*X-DSPAM-Signature:\s*(\S+)(.*\r?\n)*.*$\N}{$2}{}}
  logwrite = DSPAM check: X-DSPAM-Signature value ${if eq{$acl_m1}{}{not
found}{is $acl_m1}}
 warn condition = ${if eq{$acl_m0}{}{no}{yes}}
  set acl_m1 = ${if match{$acl_m0}\
  {\N^DSPAM answer:
(.+\r?\n)*X-DSPAM-Factors:\s*(.+(\n\s+.+)*)((\r?\n)?.*\r?\n)*.*$\N}{$2}{}}
  logwrite = DSPAM check: X-DSPAM-Factors value ${if eq{$acl_m1}{}{not
found}{is $acl_m1}}

в файле configure-example все это указано в более читабельносм виде (по
крайней мере, текст выровнен).

тут указаны примеры получения значений трех полей, в том числе
многострочного.


таким образом, в exim был добавлен функционал, отсутствующий в релизе.

специально для любителей libmilter подчеркиваю, сама функция dspam не
принимает решений о приеме или неприеме письма, она лишь возвращает
результат работы DSPAM в acl и позволяет в самом конфиге MTA принять
решение о дальнейшей судьбе письма.

p. s. если кто-то из C разработчиков захочет оптимизировать код функции,
welcome. я уже давно не разработчик, да и на C почти не писал. и эту
библиотеку не буду использовать, т. к. использую другой механизм работы
с DSPAM. все это лишь "наш ответ Чемберлену" для тех, кто считает, что
exim монолитен настолько, что невозможно расширять его функционал без
выхода нового релиза...

p. p. s. для тех, кому интересно, гляньте примеры других более простых
функций на
http://www.ols.es/exim/dlext/

-- 
Best wishes Victor Ustugov   mailto:victor на corvax.kiev.ua
public GnuPG/PGP key:        http://victor.corvax.kiev.ua/corvax.asc
ICQ: 77186900, 32418694      CRV2-RIPE, CRV-UANIC




Подробная информация о списке рассылки exim-conf