Subversion Repositories sa-exim

Compare Revisions

Ignore whitespace Rev 60 → Rev 61

/tags/4.2.1-12/debian/changelog
0,0 → 1,312
sa-exim (4.2.1-12) unstable; urgency=low
 
* Debconf templates and debian/control reviewed by the debian-l10n-
english team as part of the Smith review project (Closes: #517169).
* Corresponding Debconf translation updates:
* Brazilian Portuguese from Adriano Rafael Gomes. (Closes: #519422).
* Czech from Miroslav Kure (Closes: #518989).
* Finnish from Esko Arajärvi (Closes: #518200).
* German from Matthias Julius (Closes: #518332).
* Galician from Marce Villarino. (Closes: #519487).
* Italian from Luca Monducci (Closes: #519177).
* Japanese from Hideki Yamane (Closes: #518502).
* Portuguese from Miguel Figueiredo. (Closes: #519002).
* Swedish from Martin Bagge (Closes: #518325).
* Vietnamese from Clytie Siddall (Closes: #517813).
* French from Christian Perrier (Closes: #532560).
The following translations have not been updated yet: da, es, fr, nl.
* Add Russian Debconf translation (Closes: #529808). Thanks to Yuri Kozlov.
* debian/postinst: Don't call mv with a prepended path.
* debian/control: Put back ${misc:Depends} in Depends.
* debian/copyright: Point to the GPL 2.0 license text since this package
is licensed under that version only.
* Bump Standards-Version to 3.8.1.
* Increase Debhelper compat level to 5.
* Override Lintian warning about depending on exim4-localscanapi-1.1
without a real package as a primary alternative, since adding that
would defeat the purpose of not having to keep track of which version
of Exim provides which API/ABI version.
 
-- Magnus Holmgren <holmgren@debian.org> Sat, 01 Aug 2009 13:55:21 +0200
 
sa-exim (4.2.1-11) unstable; urgency=low
 
* Add Brazilian Portuguese Debconf template translation (Closes:
#484986). Thanks to Adriano Rafael Gomes and Felipe Augusto van de
Wiel.
* Don't ignore make clean errors.
* README.Debian: Remove outdated information about patching pre-3.0
SpamAssassin. Add information regarding auto-expire problems
(Closes: #461219).
* Stop including the SA 2.x greylisting patches altogether (due to a
typo only of them was included anyway).
* This package seems to comply with policy 3.8.0 already.
 
-- Magnus Holmgren <holmgren@debian.org> Wed, 25 Jun 2008 19:11:02 +0200
 
sa-exim (4.2.1-10) unstable; urgency=low
 
* Add Finnish Debconf template translation (Closes: #472788). Thanks to
Esko Arajärvi.
* New maintainer email address.
* Use modern fields in debian/control (Homepage; Vcs-* fields without
XS-).
* Greylisting.pm: Bail out if a non-IPv4 address is encountered
(Closes: #300103, #479955).
* Greylisting.pm: Simplify the sender address so that senders using
VERP, SRS, etc. hopefully won't be greylisted each and every time
(Closes: #347590).
* Increase Standards-Version to 3.7.3; no changes.
 
-- Magnus Holmgren <holmgren@debian.org> Tue, 03 Jun 2008 23:01:19 +0200
 
sa-exim (4.2.1-9) unstable; urgency=high
 
* Fix ugly bug caused by expanding $primary_hostname to the
non-permanent memory pool, where it will be overwritten when
receiveing multiple messages over the same connection (strangely
enough, nobody noticed).
* Depend on the local_scan ABI version returned by
exim4-localscan-plugin-config instead of all exim4-daemon-* variants
(Closes: #426425).
* debian/control: Indent Homepage: line and add XS-Vcs-* fields.
 
-- Magnus Holmgren <magnus@kibibyte.se> Tue, 21 Aug 2007 22:28:01 +0200
 
sa-exim (4.2.1-8) unstable; urgency=medium
 
* Urgency medium to reach testing before exim4.
* Since version 4.67-1, exim4 only exports those symbols that are part
of the official local_scan API. Unfortunately, sa-exim cheated and
declared three extern variables by itself:
· primary_hostname: Now retrieved by expanding "$primary_hostname".
· smtp_out: Use smtp_fflush() to get error indication.
· body_linecount: No workaround; $body_linecount simply won't be
updated. I'm working to get Exim to update it along with other
variables such as $message_size.
(Closes: #420443, #420555, #420736)
 
-- Magnus Holmgren <magnus@kibibyte.se> Thu, 26 Apr 2007 16:05:26 +0200
 
sa-exim (4.2.1-7) unstable; urgency=low
 
* Don't depend on debconf in postrm; if we can't prompt the user,
leave the spool directory alone (Closes: #417027).
* Do not pass a '-u' parameter to spamc if SAspamcUser expands to the
empty string.
 
-- Magnus Holmgren <magnus@kibibyte.se> Tue, 3 Apr 2007 13:02:48 +0200
 
sa-exim (4.2.1-6) unstable; urgency=low
 
* Added Portuguese Debconf template translation (Closes: #415537).
Thanks to Pedro Ribeiro.
* It is now possible to pass a username to spamc. See the SAspamcUser
option in sa-exim.conf.
* Build-depend on exim4-dev.
 
-- Magnus Holmgren <magnus@kibibyte.se> Tue, 20 Mar 2007 14:25:31 +0100
 
sa-exim (4.2.1-5) unstable; urgency=low
 
* Added Italian debconf template translation (Closes: #411396). Thanks
to Luca Monducci.
* Added Galician Debconf template translation (Closes: #412804).
Thanks to Jacobo Tarrio.
* Added Dutch debconf template translation (Closes: #413702). Thanks
to Bart Cornelis.
* Added debian/watch.
 
-- Magnus Holmgren <magnus@kibibyte.se> Wed, 7 Mar 2007 15:46:16 +0100
 
sa-exim (4.2.1-4) unstable; urgency=low
 
* Added Spanish debconf template translation (Closes: #404490).
Thanks to Rudy Godoy.
 
-- Magnus Holmgren <magnus@kibibyte.se> Tue, 9 Jan 2007 16:39:43 +0100
 
sa-exim (4.2.1-3) unstable; urgency=low
 
* New maintainer (Closes: #352533).
* Updated package description to explain what SA-Exim can do that
exim-daemon-heavy can't, and vice versa (Closes: #378732).
* Added German debconf template translation (Closes: #399963).
Thanks to Matthias Julius.
* Updated Swedish debconf templates.
* Encourage use of ACL variables in sa-exim.conf. Also exclude ::1
from SA scanning.
* Removed unnecessary question in long description of debconf
template.
* Upgraded to Standards-Version 3.7.2. No changes needed.
* Moved greylistclean to /usr/share/sa-exim. If you have modified
the crontab file, you have to update it manually.
* Added Recommends: perl (needed by greylistclean, but greylistclean
isn't completely necessary.
 
-- Magnus Holmgren <magnus@kibibyte.se> Sun, 3 Dec 2006 00:41:01 +0100
 
sa-exim (4.2.1-2) unstable; urgency=medium
 
* Fixed rights on /var/spool/sa-exim. Closes: #297623
+ Content-type bug closed by 4.2.1-1: Closes: #286069
* Fixed README.greylisting Closes: #325335
+ Added cs, sv, vi translations Closes: #315995, #332363, #317869
+ Added note about unsupported linecontinuation to README
sa-exim.conf already has note Closes: #276080
+ Removed SAtempreject from default sa-exim.conf Closes: #281567
-- Sander Smeenk <ssmeenk@debian.org> Mon, 27 Mar 2006 13:42:06 +0200
sa-exim (4.2.1-1) unstable; urgency=high
 
* SECURITY: new upstream does a better job at being safe when deleting
greylisting tuplets Closes: #345071
* Fixed sa-exim.conf typo Closes: #305890
* Disable former insecure /etc/cron.daily/greylistclean
 
-- Sander Smeenk <ssmeenk@debian.org> Mon, 09 Jan 2006 09:01:25 -0800
 
sa-exim (4.2-1) unstable; urgency=high
 
* New upstream version
* Ship new SA-Exim Greylisting plugin for SA 3.0 or better
* Ship new /etc/cron.daily/greylistclean
* Updated README.Debian
 
-- Marc MERLIN <marc_soft@merlins.org> Mon, 17 Dec 2005 00:14:03 -0800
 
sa-exim (4.1-1) unstable; urgency=high
 
* New upstream version
* SECURITY: new upstream provides SA greylisting patch with shell safe
filenames and directories (only affected users who use the SA greylisting
patch _and_ an unsafe shell cron job to delete old files and directories)
* Updated README.debian to warn that the SA 2.4 greylisting patch is out
of date and unmaintained.
 
-- Marc MERLIN <marc_soft@merlins.org> Mon, 16 Aug 2004 08:32:36 -0700
 
sa-exim (4.0-3) unstable; urgency=low
 
+ Changed hard depend on spamc, since that's all sa-exim needs.
You have to choose to install spamassassin, or run spamc to
another host. This entry closes: #253393
+ Documentation was assed to explain about sa-exim defaulting
to exim4 configured to use exim4/use_split_config. Devine
intervention is needed when using monolithic configs. One day
sa-exim might detect this and act on it?
This entry closes: #251755, #265820
+ Incorrect scoring of messages due to incorrect last-Received:
header is now fixed by newer versions of the exim4 package.
Dependencies have been changed. This entry closes: #250726, #246715
+ Updated Japanese translations of debconf templates. A typo in the
english templates has been fixed too. This entry closes: #252341
 
-- Sander Smeenk <ssmeenk@debian.org> Wed, 15 Aug 2004 19:40:05 +0200
sa-exim (4.0-2) unstable; urgency=low
 
* Clarified SA-greylisting patches in README.Debian
Closes: #245573
+ Added Danish translations
+ Added French translations
Closes: #238537, #239258
 
-- Sander Smeenk <ssmeenk@debian.org> Sat, 24 Apr 2004 11:34:35 +0200
 
sa-exim (4.0-1) unstable; urgency=low
 
* New upstream version
* Added new docs (README.greylisting / SA patches)
* Create /var/spool/sa-exim/tuplets for the new greylisting support
 
-- Marc MERLIN <marc_soft@merlins.org> Tue, 03 Mar 2004 08:52:49 -0800
 
sa-exim (3.1-4) unstable; urgency=low
 
* Fixed minor packaging bugs.
* Debconf gettextized for translators (Closes: #237105)
 
-- Sander Smeenk <ssmeenk@debian.org> Sun, 07 Mar 2004 15:38:47 +0100
 
sa-exim (3.1-3) unstable; urgency=low
 
* Clean up properly on purge, asking per debconf about removing saved mails
in spool-directory if necessary.
* Update to work with exim4 running as Debian-exim (don't include
/var/spool/sa-exim in deb, generate it in postinst; stricter
dependencies).
* sa-exim uses spamc - Correct depends accordingly.
 
-- Sander Smeenk <ssmeenk@debian.org> Sun, 22 Feb 2004 10:32:03 +0100
 
sa-exim (3.1-2) unstable; urgency=low
 
* Minor updates to control suggested by Andreas Metzler
* Minor updates on upstream source (INSTALL / sa-exim.conf)
* Uploaded to Debian (Closes: #196100)
 
-- Marc MERLIN <marc_soft@merlins.org> Wed, 20 Aug 2003 09:18:42 -0700
 
sa-exim (3.1-1) unstable; urgency=low
 
* Upstream update
 
-- Marc MERLIN <marc_soft@merlins.org> Tue, 19 Aug 2003 09:48:13 -0700
 
sa-exim (3.0+cvs-20030802) unstable; urgency=low
 
* Updated sa-exim to cvs version
* Restored plugin location to /usr/lib/exim4/local_scan/
* Added contrib contents to docs
 
-- Marc MERLIN <marc_soft@merlins.org> Sat, 02 Aug 2003 20:57:50 -0700
 
sa-exim (3.0+cvs-20030728) unstable; urgency=low
 
* Updated sa-exim to cvs version
 
-- Marc MERLIN <marc_soft@merlins.org> Mon, 28 Jul 2003 21:08:24 -0500
 
sa-exim (3.0+cvs-1) unstable; urgency=low
 
* Updated sa-exim to cvs version (and new sa-exim.conf config file)
 
-- Marc MERLIN <marc_soft@merlins.org> Mon, 08 Jun 2003 23:19:11 -0700
 
sa-exim (3.0-3) unstable; urgency=low
 
* Taken over from Andreas, thanks for the template
* Rewrote description in control
* Updated docs to contain all the documentation files
* /var/spool/sa-exim will contain the saved mails and is 770/mail.mail
* Do not patch sample sa-exim.conf, run sed during the install
* Removed ${misc:Depends} from control, my dpkg-gencontrol says it's unknown
* Fixes to debian/control, debian/rules and debian/copyright for policy
compliance and to make lintian more happy. Increased Standards-Version to
3.5.10. (Andreas Metzler)
* Add some magic to maintainerscripts, disabling the sa-exim part of exim's
main configuration file when sa-exim is uninstalled. (Andreas Metzler)
 
-- Marc MERLIN <marc_soft@merlins.org> Mon, 26 May 2003 23:22:56 -0700
 
sa-exim (3.0-2) unstable; urgency=low
 
* Small fixes
 
-- Andreas Metzler <ametzler@debian.org> Fri, 2 May 2003 20:20:11 +0200
 
sa-exim (3.0-1) unstable; urgency=low
 
* renamed package to sa-exim
* upgrade to 3.0
 
-- Andreas Metzler <ametzler@debian.org> Fri, 2 May 2003 17:36:28 +0200
 
exim4-sa-plugin (2.2-1) unstable; urgency=low
 
* Initial Release.
 
-- Andreas Metzler <ametzler@debian.org> Thu, 13 Mar 2003 17:16:46 +0100
 
/tags/4.2.1-12/debian/po/fr.po
0,0 → 1,69
# Translation of sa-exim debconf screen to French
# Copyright (C) 2004-2009 Debian French l10n team <debian-l10n-french@lists.debian.org>
# This file is distributed under the same license as the sa-exim package.
#
# Translators:
# Eric Madesclair <eric-m@wanadoo.fr>, 2004
# Christian Perrier <bubulle@debian.org>, 2009.
msgid ""
msgstr ""
"Project-Id-Version: fr\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-03-02 07:25+0100\n"
"PO-Revision-Date: 2009-06-10 00:08+0200\n"
"Last-Translator: Christian Perrier <bubulle@debian.org>\n"
"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
#| msgid "Remove saved mails in spool directory?"
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr ""
"Supprimer les courriers sauvegardés du répertoire d'attente (« spool ») de sa-"
"exim ?"
 
#. Type: boolean
#. Description
#: ../templates:2001
#| msgid ""
#| "There are some saved mails in subdirectories of /var/spool/sa-exim. "
#| "Depending on the configuration sa-exim will save mails matching specific "
#| "criterias (an error occured, rejected as spam, passed through although "
#| "recognized as spam, ...) in subdirectories of /var/spool/sa-exim."
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Plusieurs courriers sauvegardés existent dans les sous-répertoires de /var/"
"spool/sa-exim. Selon la configuration, sa-exim sauvegarde les courriers qui "
"correspondent à des critères spécifiques (p. ex. « an error occurred » -une "
"erreur est survenue-, « rejected as spam » - rejeté comme spam -, « passed "
"through although recognized as spam » - passé à travers, reconnu comme spam -) "
"dans ces répertoires."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Veuillez choisir si vous souhaitez conserver ces courriers pour analyse "
"ultérieure ou si vous préférez les supprimer maintenant."
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Vous pouvez les garder pour des analyses approfondies et les supprimer "
#~ "par la suite ou vous pouvez décider de les effacer maintenant."
 
#~ msgid "Should they be removed?"
#~ msgstr "Vous pouvez les supprimer maintenant."
/tags/4.2.1-12/debian/po/ru.po
0,0 → 1,49
# translation of ru.po to Russian
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Yuri Kozlov <yuray@komyakino.ru>, 2009.
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1-12\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-03-02 07:25+0100\n"
"PO-Revision-Date: 2009-05-10 10:31+0400\n"
"Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
"Language-Team: Russian <debian-l10n-russian@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Удалить сохранённую почту в буферном каталоге sa-exim?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"В подкаталогах /var/spool/sa-exim обнаружены почтовые сообщения. "
"В зависимости от настройки, sa-exim может сохранить эту почту в "
"подкаталогах, если она удовлетворяет критериям (например, \"возникла "
"ошибка\", \"отвергнуто как спам\", или \"передано, хотя считается спамом\")."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Укажите, нужно ли сохранить эту почту для дальнейшего анализа или "
"удалить её прямо сейчас."
 
/tags/4.2.1-12/debian/po/gl.po
0,0 → 1,58
# Galician translation of sa-exim's debconf templates
# This file is distributed under the same license as the sa-exim package.
# Jacobo Tarrio <jtarrio@debian.org>, 2007.
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2007-02-28 10:34+0100\n"
"Last-Translator: Jacobo Tarrio <jtarrio@debian.org>\n"
"Language-Team: Galician <proxecto@trasno.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid "Remove saved mails in spool directory?"
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "¿Borrar as mensaxes gravadas do directorio de traballo?"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid ""
#| "There are some saved mails in subdirectories of /var/spool/sa-exim. "
#| "Depending on the configuration sa-exim will save mails matching specific "
#| "criterias (an error occured, rejected as spam, passed through although "
#| "recognized as spam, ...) in subdirectories of /var/spool/sa-exim."
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Hai algunhas mensaxes gravadas nos subdirectorios de /var/spool/sa-exim. "
"Dependendo da configuración, sa-exim ha gravar as mensaxes que encaixen en "
"determinados criterios (houbo un erro, rexeitada coma spam, pasada aínda que "
"se recoñeceu coma spam, ...) en subdirectorios de /var/spool/sa-exim."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Pode conservalas para seguir analizándoas e eliminalas despois "
#~ "manualmente ou decidir eliminalas agora."
/tags/4.2.1-12/debian/po/cs.po
0,0 → 1,64
#
# Translators, if you are not familiar with the PO format, gettext
# documentation is worth reading, especially sections dedicated to
# this format, e.g. by running:
# info -n '(gettext)PO Files'
# info -n '(gettext)Header Entry'
#
# Some information specific to po-debconf are available at
# /usr/share/doc/po-debconf/README-trans
# or http://www.debian.org/intl/l10n/po-debconf/README-trans
#
# Developers do not need to manually edit POT or PO files.
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-03-07 20:53+0100\n"
"Last-Translator: Miroslav Kure <kurem@debian.cz>\n"
"Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Odstranit maily v adresáři /var/spool/sa-exim?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"V podadresářích adresáře /var/spool/sa-exim se nachází nějaké uložené maily. "
"Podle nastavení může sa-exim ukládat do těchto adresářů maily, které se "
"shodují s danými kritérii (jako např. „výskyt chyby“, „odmítnuto jako spam“, "
"„předáno dále, přestože vypadá jako spam“)."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Zvolte si, zda chcete maily ponechat pro další analýzu, nebo je rovnou "
"smazat."
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Maily si můžete ponechat pro budoucí analýzu a poté je smazat ručně, nebo "
#~ "je můžete smazat přímo teď."
 
#~ msgid "Should they be removed?"
#~ msgstr "Mají se odstranit?"
/tags/4.2.1-12/debian/po/pt_BR.po
0,0 → 1,55
# sa-exim Brazilian Portuguese translation.
# Copyright (C) 2008 THE sa-exim'S COPYRIGHT HOLDER
# This file is distributed under the same license as the sa-exim package.
# Adriano Rafael Gomes <adrianorg@gmail.com>, 2008-2009.
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1-12\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-03-09 08:33-0300\n"
"Last-Translator: Adriano Rafael Gomes <adrianorg@gmail.com>\n"
"Language-Team: Brazilian Portuguese <debian-l10n-portuguese@lists.debian."
"org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"pt_BR utf-8\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Remover os e-mails salvos no diretório spool do sa-exim?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Há alguns e-mails salvos em subdiretórios de /var/spool/sa-exim. Dependendo "
"da configuração, o sa-exim pode salvar e-mails que atendam a critérios "
"específicos (como \"ocorreu um erro\", \"rejeitado como spam\", ou \"aceito "
"apesar de reconhecido como spam\") nestes diretórios."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Por favor, escolha se você quer manter estes e-mails para uma análise mais "
"aprofundada ou se quer excluí-los agora."
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Você pode mantê-los para uma análise mais aprofundada e mais tarde removê-"
#~ "los manualmente ou decidir excluí-los agora."
/tags/4.2.1-12/debian/po/es.po
0,0 → 1,83
# sa-exim po-debconf translation to spanish
# Copyright (C) 2004 Software in the Public Interest
# This file is distributed under the same license as the sa-exim package.
#
# Changes:
# - Initial translation
# Rudy Godoy <rudy@kernel-panik.org>, 2006
#
#
# Traductores, si no conoce el formato PO, merece la pena leer la
# documentación de gettext, especialmente las secciones dedicadas a este
# formato, por ejemplo ejecutando:
# info -n '(gettext)PO Files'
# info -n '(gettext)Header Entry'
#
# Equipo de traducción al español, por favor lean antes de traducir
# los siguientes documentos:
#
# - El proyecto de traducción de Debian al español
# http://www.debian.org/intl/spanish/coordinacion
# especialmente las notas de traducción en
# http://www.debian.org/intl/spanish/notas
#
# - La guía de traducción de po's de debconf:
# /usr/share/doc/po-debconf/README-trans
# o http://www.debian.org/intl/l10n/po-debconf/README-trans
#
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2006-12-25 11:42-0500\n"
"Last-Translator: Rudy Godoy <rudy@kernel-panik.org>\n"
"Language-Team: Debian l10n Spanish <debian-l10n-spanish@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid "Remove saved mails in spool directory?"
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "¿Desea eliminar los correos guardados en el directorio «spool»?"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid ""
#| "There are some saved mails in subdirectories of /var/spool/sa-exim. "
#| "Depending on the configuration sa-exim will save mails matching specific "
#| "criterias (an error occured, rejected as spam, passed through although "
#| "recognized as spam, ...) in subdirectories of /var/spool/sa-exim."
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Existen algunos correos guardados en subdirectorios de «/var/spool/sa-exim». "
"Dependiendo de la configuración, sa-exim guardará los correos que cumplan "
"con un criterio específico (si ha ocurrido un fallo, rechazado como spam, "
"aceptado aunque se ha reconocido como spam, ...) en los subdirectorios de «/"
"var/spool/sa-exim»."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Puede conservarlos para un análisis posterior, y eliminarlos de forma "
#~ "manual más tarde, o decidir eliminarlos ahora."
/tags/4.2.1-12/debian/po/nl.po
0,0 → 1,60
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2007-02-28 19:43+0100\n"
"Last-Translator: Bart Cornelis <cobaco@skolelinux.no>\n"
"Language-Team: debian-l10n-dutch <debian-l10n-dutch@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid "Remove saved mails in spool directory?"
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Wilt u dat opgeslagen e-mails verwijderd worden uit de spool-map?"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid ""
#| "There are some saved mails in subdirectories of /var/spool/sa-exim. "
#| "Depending on the configuration sa-exim will save mails matching specific "
#| "criterias (an error occured, rejected as spam, passed through although "
#| "recognized as spam, ...) in subdirectories of /var/spool/sa-exim."
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Er zijn een aantal opgeslagen e-mails in de submappen van /var/spool/sa-"
"exim. Afhankelijk van de configuratie slaat sa-exim e-mails die aan "
"specifieke criteria voldoen (bv. fout opgetreden, geweigerd als spam, "
"doorgelaten maar gemarkeerd als spam, ...) op in submappen van /var/spool/sa-"
"exim ."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "U kunt deze behouden voor verdere analyse, en ze dan later handmatig "
#~ "verwijderen, of u kunt ze nu laten verwijderen."
/tags/4.2.1-12/debian/po/it.po
0,0 → 1,46
# Italian (it) translation of debconf templates for sa-exim
# Copyright (C) 2007 Free Software Foundation, Inc.
# This file is distributed under the same license as the sa-exim package.
# Luca Monducci <luca.mo@tiscali.it>, 2007-2009.
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1 italian debconf templates\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-03-02 07:25+0100\n"
"PO-Revision-Date: 2009-03-10 21:41+0100\n"
"Last-Translator: Luca Monducci <luca.mo@tiscali.it>\n"
"Language-Team: Italian <debian-l10n-italian@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Eliminare le mail salvate nella directory di spool di sa-exim?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Nelle sottodirectory di /var/spool/sa-exim sono state salvate delle mail. A "
"seconda della configurazione di sa-exim le mail vengono salvate in queste "
"sottodirectory quando verificano determinati criteri (si è verificato un "
"errore, rifiutata per spam, passata nonostante identificata come spam, ecc.)."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Scegliere se tenere queste mail per una successiva analisi oppure eliminarle "
"adesso."
/tags/4.2.1-12/debian/po/vi.po
0,0 → 1,47
# Vietnamese translation for sa-exim.
# Copyright © 2009 Free Software Foundation, Inc.
# Clytie Siddall <clytie@riverland.net.au>, 2005-2009.
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1-12\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-03-02 19:08+1030\n"
"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: LocFactoryEditor 1.8\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Gỡ bỏ các thư đã lưu khỏi thư mục ống chỉ của sa-exim ?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Có một số thư đã lưu nằm trong thư mục con của « /var/spool/sa-exim ». Phụ "
"thuộc vào cấu hình, sa-exim có thể lưu mỗi thư tương ứng với tiêu chuẩn "
"riêng (v.d. gặp lỗi, bị từ chối do thư rác, tán thành dù nhận ra là thư rác) "
"vào các thư mục này."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Hãy chọn nếu bạn muốn giữ lại các thư này để phân tích về sau, hoặc xoá "
"chúng ngay bây giờ."
/tags/4.2.1-12/debian/po/templates.pot
0,0 → 1,40
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-04-04 15:41+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr ""
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
/tags/4.2.1-12/debian/po/pt.po
0,0 → 1,53
# Portuguese translation for sa-exim debconf messages.
# Copyright (C) 2007 Pedro Ribeiro <p.m42.ribeiro@gmail.com>
# This file is distributed under the same license as the sa-exim package.
# Pedro Ribeiro <p.m42.ribeiro@gmail.com>, 2007-2009
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1-12\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-03-09 19:58+0000\n"
"Last-Translator: Pedro Ribeiro <p.m42.ribeiro@gmail.com>\n"
"Language-Team: Portuguese <traduz@debianpt.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Remover os mails guardados no directório de spool do sa-exim ?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Existem alguns mails guardados em sub-directórios de /var/spool/sa-exim. "
"Dependendo da configuração, o sa-exim guarda os mails que obedecem a certos "
"critérios (tais como \"ocorreu um erro\", \"rejeitado como spam\", \"aceite "
"mas marcada como spam\", ...) nesses directórios."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Escolha, por favor, se quer manter estes mails para análise futura ou apagá-"
"los agora."
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Pode mantê-las para análise posterior e removê-las mais tarde manualmente "
#~ "ou apagá-las agora."
/tags/4.2.1-12/debian/po/da.po
0,0 → 1,73
# translation of sa-exim_3.1-4-da.po to Danish
# translation of sa-exim_3.1-4_templates.po to Danish
#
# Translators, if you are not familiar with the PO format, gettext
# documentation is worth reading, especially sections dedicated to
# this format, e.g. by running:
# info -n '(gettext)PO Files'
# info -n '(gettext)Header Entry'
# Some information specific to po-debconf are available at
# /usr/share/doc/po-debconf/README-trans
# or http://www.debian.org/intl/l10n/po-debconf/README-trans#
# Developers do not need to manually edit POT or PO files.
# Claus Hindsgaul <claus_h@image.dk>, 2004.
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim_3.1-4-da\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2004-11-19 17:21+0100\n"
"Last-Translator: Claus Hindsgaul <claus_h@image.dk>\n"
"Language-Team: Danish <dansk@klid.dk>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.9.1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid "Remove saved mails in spool directory?"
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Fjern gemte breve fra spool-mappen?"
 
#. Type: boolean
#. Description
#: ../templates:2001
#, fuzzy
#| msgid ""
#| "There are some saved mails in subdirectories of /var/spool/sa-exim. "
#| "Depending on the configuration sa-exim will save mails matching specific "
#| "criterias (an error occured, rejected as spam, passed through although "
#| "recognized as spam, ...) in subdirectories of /var/spool/sa-exim."
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Der er nogle gemte breve i mapperne under /var/spool/sa-exim. Afhængig af "
"opsætningen vil sa-exim gemme breve, der opfylder bestemte kriterier (der "
"opstod en fejl, afvist som spam, lod brevet passere på trods af at det blev "
"genkendt som spam,...) gemme breve i mapperne under /var/spool/sa-exim."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Du kan beholde dem til yderligere efterforskning og selv fjerne dem "
#~ "senere eller vælge at få dem slettet nu."
 
#~ msgid "Should they be removed?"
#~ msgstr "Skal de slettes?"
/tags/4.2.1-12/debian/po/de.po
0,0 → 1,48
# translation of po-debconf template to German
# This file is distributed under the same license as the sa-exim package.
# Copyright (C):
#
# Matthias Julius <mdeb@julius-net.net>, 2006, 2009.
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1-13\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-03-02 07:25+0100\n"
"PO-Revision-Date: 2009-03-02 21:29-0500\n"
"Last-Translator: Matthias Julius <mdeb@julius-net.net>\n"
"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Gespeicherte E-Mails im Spool-Verzeichnis von Sa-Exim löschen?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. Depending "
"on the configuration, sa-exim may save mails matching specific criteria (such "
"as \"an error occurred\", \"rejected as spam\", or \"passed through although "
"recognized as spam\") in these directories."
msgstr ""
"Es befinden sich einige gespeicherte E-Mails in Unterverzeichnissen von /var/"
"spool/sa-exim. Abhängig von der Konfiguration kann Sa-Exim E-Mails, die "
"bestimmte Kriterien erfüllen (wie »ein Fehler trat auf«, »als Spam abgewiesen« "
"oder »durchgelassen, obwohl als Spam erkannt«), in diesen Unterverzeichnissen "
"speichern."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Bitte wählen Sie, ob Sie diese E-Mails zur späteren Analyse behalten oder "
"jetzt löschen möchten."
/tags/4.2.1-12/debian/po/sv.po
0,0 → 1,65
# Translators, if you are not familiar with the PO format, gettext
# documentation is worth reading, especially sections dedicated to
# this format, e.g. by running:
# info -n '(gettext)PO Files'
# info -n '(gettext)Header Entry'
# Some information specific to po-debconf are available at
# /usr/share/doc/po-debconf/README-trans
# or http://www.debian.org/intl/l10n/po-debconf/README-trans
# Developers do not need to manually edit POT or PO files.
# , fuzzy
#
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2-2\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-04-04 15:47+0200\n"
"Last-Translator: Martin Bagge <brother@bsnet.se>\n"
"Language-Team: Swedish <debian-l10n-swedish@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Swedish\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Ta bort sparad e-post i sa-exims spool-mapp?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Det finns sparade e-postmeddelanden i undermappar till /var/spool/sa-"
"exim. Beroende på konfigurationen kan sa-exim spara e-postmeddelanden som "
"matchar specifika kriterier (exempelvis \"ett fel inträffade\", \"avvisat "
"som spam\", \"genomsläppt trots att det blev spam-klassat\") i dessa "
"kataloger."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Ange om du vill spara eller radera dessa meddelanden. Vill du kunna göra "
"analyser av meddelandena senare ska de sparas nu."
 
#~ msgid ""
#~ "You can keep them for further analysis and later remove them manually or "
#~ "decide to delete them now."
#~ msgstr ""
#~ "Du kan spara dom för vidare analys och senare ta bort dom manuellt eller "
#~ "välja att ta bort dom nu."
 
#~ msgid "Should they be removed?"
#~ msgstr "Ska de tas bort?"
/tags/4.2.1-12/debian/po/ja.po
0,0 → 1,55
#
# Translators, if you are not familiar with the PO format, gettext
# documentation is worth reading, especially sections dedicated to
# this format, e.g. by running:
# info -n '(gettext)PO Files'
# info -n '(gettext)Header Entry'
#
# Some information specific to po-debconf are available at
# /usr/share/doc/po-debconf/README-trans
# or http://www.debian.org/intl/l10n/po-debconf/README-trans
#
# Developers do not need to manually edit POT or PO files.
#
#
msgid ""
msgstr ""
"Project-Id-Version: sa-exim 4.2.1-12\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-03-07 15:21+0900\n"
"Last-Translator: Hideki Yamane (Debian-JP) <henrich@debian.or.jp>\n"
"Language-Team: Japanese <debian-japanese@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "sa-exim のスプールディレクトリに保存したメールを削除しますか?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"/var/spool/sa-exim のサブディレクトリ以下に保存されたメールがあります。sa-"
"exim の設定によって、sa-exim は特定の項目 (「エラーが起きた」、「spamとして拒"
"否された」、「spam と認識されたにも関わらず通り抜けた」など) にマッチしたメー"
"ルを各ディレクトリに保存します。"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"後ほど分析するためにこのメールを保存しておくか、それともここで削除するかを選"
"んでください。"
/tags/4.2.1-12/debian/po/fi.po
0,0 → 1,44
msgid ""
msgstr ""
"Project-Id-Version: sa-exim\n"
"Report-Msgid-Bugs-To: sa-exim@packages.debian.org\n"
"POT-Creation-Date: 2009-04-04 15:40+0200\n"
"PO-Revision-Date: 2009-03-04 20:56+0200\n"
"Last-Translator: Esko Arajärvi <edu@iki.fi>\n"
"Language-Team: Finnish <debian-l10n-finnish@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Finnish\n"
"X-Poedit-Country: FINLAND\n"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Remove saved mails in sa-exim's spool directory?"
msgstr "Poistetaanko tallennetut sähköpostit sa-eximin spool-hakemistosta?"
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"There are some saved mails in subdirectories of /var/spool/sa-exim. "
"Depending on the configuration, sa-exim may save mails matching specific "
"criteria (such as \"an error occurred\", \"rejected as spam\", or \"passed "
"through although recognized as spam\") in these directories."
msgstr ""
"Hakemiston /var/spool/sa-exim alihakemistoissa on joitain tallennettuja "
"sähköposteja. Riippuen sa-eximin asetuksista, tietyt ehdot täyttäviä "
"sähköposteja saatetaan tallentaa hakemiston /var/spool/sa-exim "
"alihakemistoihin (kuten virheen aiheuttaneet, roskapostina hylätyt tai "
"roskapostiksi tunnistetut, mutta edelleen lähetetyt)."
 
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"Please choose whether you want to keep these mails for further analysis or "
"delete them now."
msgstr ""
"Valitse haluatko säilyttää nämä viestit jatkotutkimuksia varten vai poistaa "
"ne nyt."
/tags/4.2.1-12/debian/po/POTFILES.in
0,0 → 1,0
[type: gettext/rfc822deb] templates
/tags/4.2.1-12/debian/rules
0,0 → 1,88
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
 
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
 
CFLAGS = -Wall -g
 
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
 
configure: configure-stamp
configure-stamp:
dh_testdir
touch configure-stamp
 
build: build-stamp
build-stamp: configure-stamp
dh_testdir
$(MAKE) BUILDCFLAGS='-I/usr/include/exim4 -fPIC $$(CFLAGS)'
touch build-stamp
 
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
$(MAKE) clean
dh_clean
 
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
install -m755 sa-exim-*so \
$(CURDIR)/debian/sa-exim/usr/lib/exim4/local_scan/sa-exim.so
install -m755 accept*so \
$(CURDIR)/debian/sa-exim/usr/lib/exim4/local_scan/accept.so
sed "s/\/var\/spool\/exim/\/var\/spool\/sa-exim/" < sa-exim.conf > \
$(CURDIR)/debian/sa-exim/etc/exim4/sa-exim.conf
chmod 644 $(CURDIR)/debian/sa-exim/etc/exim4/sa-exim.conf
install -m644 debian/15_sa-exim_plugin_path \
$(CURDIR)/debian/sa-exim/etc/exim4/conf.d/main
install -m644 Greylisting.pm \
$(CURDIR)/debian/sa-exim/usr/share/perl5/Mail/SpamAssassin/Plugin/Greylisting.pm
install -m644 greylistclean.cron \
$(CURDIR)/debian/sa-exim/etc/cron.d/greylistclean
install -m755 greylistclean \
$(CURDIR)/debian/sa-exim/usr/share/sa-exim/greylistclean
 
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
 
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs Changelog.html
dh_installdocs
dh_installexamples
dh_installdebconf
dh_installman
install -d debian/sa-exim/usr/share/lintian/overrides
install -m 644 debian/sa-exim.lintian-overrides \
debian/sa-exim/usr/share/lintian/overrides/sa-exim
dh_link
dh_strip
dh_compress
dh_fixperms -Xvar/spool/sa-exim
dh_perl
dh_installdeb
dh_shlibdeps
echo "exim:Depends=exim4-localscanapi-`exim4-localscan-plugin-config --localscan-apiversion`" \
>> debian/sa-exim.substvars
dh_gencontrol
dh_md5sums
dh_builddeb
 
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure
Property changes:
Added: svn:executable
Index: 4.2.1-12/debian/sa-exim.lintian-overrides
===================================================================
--- 4.2.1-12/debian/sa-exim.lintian-overrides (nonexistent)
+++ 4.2.1-12/debian/sa-exim.lintian-overrides (revision 61)
@@ -0,0 +1 @@
+sa-exim: virtual-package-depends-without-real-package-depends depends: exim4-localscanapi-1.1
Index: 4.2.1-12/debian/control
===================================================================
--- 4.2.1-12/debian/control (nonexistent)
+++ 4.2.1-12/debian/control (revision 61)
@@ -0,0 +1,28 @@
+Source: sa-exim
+Section: mail
+Priority: optional
+Maintainer: Magnus Holmgren <holmgren@debian.org>
+Build-Depends: debhelper (>= 5), links, exim4-dev
+Standards-Version: 3.8.1
+Vcs-Svn: svn://svn.kibibyte.se/sa-exim/trunk
+Vcs-Browser: http://svn.kibibyte.se/sa-exim
+Homepage: http://marc.merlins.org/linux/exim/sa.html
+
+Package: sa-exim
+Architecture: any
+Depends: ${exim:Depends}, spamc, ${shlibs:Depends}, ${misc:Depends},
+ debconf (>= 1.2.0) | debconf-2.0
+Recommends: ${perl:Depends}
+Suggests: spamassassin
+Description: SpamAssassin filter for Exim
+ SA-Exim integrates SpamAssassin filtering at SMTP time with the Exim
+ v4 MTA. It may be used to reject incoming mails before they arrive, or
+ even to tie up the sender's resources by slowing down the connection
+ ("teergrubing").
+ .
+ Most of the functionality of this package can also be achieved
+ using the exiscan ACL conditions built into the "heavy" Exim daemon,
+ exim-daemon-heavy. Use this package if you need SpamAssassin's
+ report_safe feature, or if you want to have easier control over the
+ header fields added, without using the report template to add multiple
+ fields.
Index: 4.2.1-12/debian/compat
===================================================================
--- 4.2.1-12/debian/compat (nonexistent)
+++ 4.2.1-12/debian/compat (revision 61)
@@ -0,0 +1 @@
+5
Index: 4.2.1-12/debian/copyright
===================================================================
--- 4.2.1-12/debian/copyright (nonexistent)
+++ 4.2.1-12/debian/copyright (revision 61)
@@ -0,0 +1,34 @@
+This package was adopted by the current Debian maintainer,
+Magnus Holmgren <magnus@debian.org>, on Fri, 1 Dec 2006 19:05:58 +0100.
+
+Before that, it was maintained by Sander Smeenk <ssmeenk@debian.org>, who
+adopted it on Tue, 24 Feb 2004 19:47:11 +0100.
+
+The package was originally debianized by Andreas Metzler
+<ametzler@debian.org> on Thu, 13 Mar 2003 17:16:46 +0100.
+
+Upstream Author: Marc MERLIN <marc_soft@merlins.org>
+
+It was downloaded from http://marc.merlins.org/linux/exim/sa.html
+
+Copyright © 2004-2006 Marc Merlin
+
+License:
+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 dated June, 1991.
+
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301, USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL-2'.
+
Index: 4.2.1-12/debian/postinst
===================================================================
--- 4.2.1-12/debian/postinst (nonexistent)
+++ 4.2.1-12/debian/postinst (revision 61)
@@ -0,0 +1,55 @@
+#!/bin/sh
+set -e
+
+. /usr/share/debconf/confmodule
+
+LOCALSCANCONF=/etc/exim4/conf.d/main/15_sa-exim_plugin_path
+DISABLELOCALSCANTEXT='# sa-exim plugin is disabled, because it was uninstalled'
+DISABLELOCALSCANMD5=`echo "${DISABLELOCALSCANTEXT}" | md5sum | cut -d\ -f1`
+
+OLDCRONJOB=/etc/cron.hourly/greylistclean
+OLDCRONJOBREN=/etc/cron.hourly/.greylistclean.insecure.deleteme
+if test -f $OLDCRONJOB; then
+ echo "disabling old insecure $OLDCRONJOB"
+ echo "(renamed to $OLDCRONJOBREN)"
+ echo "See new cronjob in /etc/cron.d/greylistclean"
+ mv $OLDCRONJOB $OLDCRONJOBREN
+fi
+
+case "$1" in
+ configure)
+ if [ ! -e /var/spool/sa-exim ] ; then
+ # Debian-exim should exist as we depend on exim4-base
+ install -d -m771 -oDebian-exim -gDebian-exim \
+ /var/spool/sa-exim
+ elif [ -d /var/spool/sa-exim ]; then
+ # Fix permissions
+ chmod 771 /var/spool/sa-exim
+ chown Debian-exim:Debian-exim /var/spool/sa-exim
+ fi
+ # Support for greylisting tuplets (written as nobody by spamd)
+ if [ ! -e /var/spool/sa-exim/tuplets ] ; then
+ install -d -m750 -onobody -gDebian-exim \
+ /var/spool/sa-exim/tuplets
+ elif [ -d /var/spool/sa-exim/tuplets ]; then
+ # Fix permissions
+ chmod 771 /var/spool/sa-exim/tuplets
+ chown nobody:Debian-exim /var/spool/sa-exim/tuplets
+ fi
+ # clean up temporary file generated by postrm uninstall
+ if [ -e "${LOCALSCANCONF}.rul" ] && \
+ [ "`md5sum ${LOCALSCANCONF}.rul | cut -d\ -f1`" = "${DISABLELOCALSCANMD5}" ]; then
+ rm ${LOCALSCANCONF}.rul
+ fi
+ if [ -x /etc/init.d/exim4 ]; then
+ if [ -x /usr/sbin/invoke-rc.d ]; then
+ invoke-rc.d exim4 reload || true
+ else
+ /etc/init.d/exim4 reload || true
+ fi
+ fi
+ ;;
+
+esac
+
+#DEBHELPER#
Index: 4.2.1-12/debian/templates
===================================================================
--- 4.2.1-12/debian/templates (nonexistent)
+++ 4.2.1-12/debian/templates (revision 61)
@@ -0,0 +1,20 @@
+# These templates have been reviewed by the debian-l10n-english
+# team
+#
+# If modifications/additions/rewording are needed, please ask
+# debian-l10n-english@lists.debian.org for advice.
+#
+# Even minor modifications require translation updates and such
+# changes should be coordinated with translators and reviewers.
+
+Template: sa-exim/purge_spool
+Type: boolean
+Default: false
+_Description: Remove saved mails in sa-exim's spool directory?
+ There are some saved mails in subdirectories of /var/spool/sa-exim.
+ Depending on the configuration, sa-exim may save mails matching specific
+ criteria (such as "an error occurred", "rejected as spam", or "passed
+ through although recognized as spam") in these directories.
+ .
+ Please choose whether you want to keep these mails for further analysis
+ or delete them now.
Index: 4.2.1-12/debian/dirs
===================================================================
--- 4.2.1-12/debian/dirs (nonexistent)
+++ 4.2.1-12/debian/dirs (revision 61)
@@ -0,0 +1,5 @@
+usr/lib/exim4/local_scan
+etc/exim4/conf.d/main
+usr/share/perl5/Mail/SpamAssassin/Plugin
+usr/share/sa-exim
+etc/cron.d
Index: 4.2.1-12/debian/README.Debian
===================================================================
--- 4.2.1-12/debian/README.Debian (nonexistent)
+++ 4.2.1-12/debian/README.Debian (revision 61)
@@ -0,0 +1,169 @@
+********************************
+* SHOULD YOU USE THIS PACKAGE? *
+********************************
+
+Since version 4.50, Exim has the content-scanning extension formerly
+known as "exiscan" built-in. It has a number of advantages and
+disadvantages compared to SA-Exim.
+
+Advantages of built-in content-scanning interface:
+
+ * One less configuration file to edit.
+ * Spam control policy integrates better with Exim's ACL system.
+ * It's possible to tell SA which user to scan for (the -u parameter of
+ spamc). SA-Exim can't do that (yet).
+ * Finer control over the mail header is possible, but not in a clean
+ way (it involves putting all header fields you might possibly want
+ to add in the report template, and using rather complicated
+ expansion expressions to extract the wanted ones from
+ $spam_report). At any rate, you can choose a prefix different from
+ "X-Spam-".
+
+Advantages of SA-Exim:
+
+ * It is possible to use the report_safe feature, which turns mail
+ deemed to be spam into a message/rfc822 attachment of a report
+ message. (Note however that if you do, then any X-SA-* fields added
+ to help the greylisting module can't be removed.)
+ * All the add_header and rewrite_header options in
+ /etc/spamassassin/local.cf will be obeyed. In other words,
+ everything will be *almost* as if you filtered the mail through
+ spamassassin on the command line.
+ * So-called teergrubing ("tarpitting") is possible in a way that
+ isn't possible with exiscan (I'm not in any way saying that it
+ works as a counterattack against spammers).
+ * You can simply add the sa-exim package to a standard exim4
+ installation and it should, in principle, instantly work (except
+ you have to uncomment one line in sa-exim.conf).
+
+Both alternatives enable you to defer, greylist, reject, and blackhole
+mail, optionally saving copies, at configurable score levels.
+
+*****************
+* CONFIGURATION *
+*****************
+
+This version of the sa-exim package defaults to placing a configuration
+sniplet in /etc/exim4/conf.d/. Depending on what you have answered to the
+DebConf questions while configuring Exim4, the module will be loaded
+automatically, or human intervention is required.
+
+To find out what configuration file Exim4 is using, issue:
+
+ $ exim4 -bV | tail -1
+ Configuration file is /path/to/configfile
+
+If /path/to/configfile shows:
+
+ - /etc/exim4/exim4.conf
+ You are using the hand-crafted configuration file.
+ See the 'HAND-CRAFTED' section below.
+
+ - /var/lib/exim4/config.autogenerated
+ You are using the debianized configuration scheme - with either
+ 'split' or 'unsplit' configuration file.
+ See the 'DEBIANIZED' section below.
+
+
+HAND-CRAFTED
+------------
+
+Use 'grep "local_scan_path" /etc/exim4/exim4.conf" to see if the sa-exim
+line is included in the configuration. If grep returns something, check
+if it matches the following line. If grep returns nothing, you have to
+manually add the following line to the exim4.conf file and restart exim4.
+
+ local_scan_path = /usr/lib/exim4/local_scan/sa-exim.so
+
+Change or add the line above and manually restart exim4 by issuing
+'invoke-rc.d exim4 reload' or '/etc/init.d/exim4 reload' as root.
+
+
+DEBIANIZED
+----------
+
+Use 'grep "local_scan_path" /var/lib/exim4/config.autogenerated' to
+see if the sa-exim line is included in the configuration. If grep
+returns something, you're set and already using the sa-exim module. If
+grep returns nothing, we need to figure out a few things:
+
+Issue:
+ $ grep "use_split_config" /etc/exim4/update-exim4.conf.conf
+ dc_use_split_config='true'
+
+If your result shows 'false' where mine shows 'true', then you're
+using the unsplit configuration, generated from
+/etc/exim4/exim4.conf.template. If you haven't customized that file
+you could edit /etc/exim4/update-exim4.conf.conf by hand, change the
+'false' to 'true' and issue 'update-exim4.conf' as root. Then, check
+again if the sa-exim module line is included. It should. If it still
+isn't: mail me. If it is, restart exim4 by issuing 'invoke-rc.d exim4
+restart' or '/etc/init.d/exim4 restart' as root. If you *have*
+customized /etc/exim4/exim4.conf.template, then you'd better stick
+with the unsplit configuration scheme and add the local_scan_path
+setting by hand, like with the hand-crafted configuration file.
+
+Next, read all about greylisting and sa-exim:
+
+***************
+* GREYLISTING *
+***************
+Notes on greylisting with sa-exim.
+
+If you use SpamAssassin 3.0 or better, you do not need to patch it, you
+can just use the Greylisting module shipped with sa-exim.
+The only thing you need to do to enable it, is to copy the 4 lines below
+loadplugin in the greylisting README, and adjust the score if you wish (see
+README.Greylisting for details).
+
+***********************************
+* PROBLEMS WITH BAYES AUTO-EXPIRY *
+***********************************
+
+When scanning mail during the SMTP dialogue there is somewhat limited
+time before the remote host gives up, even if they should wait for at
+least ten minutes. To avoid Exim returning a temporary error status,
+or the remote host giving up prematurely and in some cases for good,
+SA-Exim overrides Exim's timeout handler and accepts the message if
+SpamAssassin takes too long, by default 240 seconds.
+
+Using SpamAssassin's Bayesian learning module means that it will
+automatically expire old tokens when its database has grown too large.
+That can take several minutes. If it takes too long, SA-Exim will
+abort it, meaning that SpamAssassin will run auto-expiry again next
+time, and be aborted, and so on...
+
+If this happens, you have a few remedies:
+
+1) Set SAtimeout to a higher value in /etc/exim4/sa-exim.conf.
+
+2) Run sa-learn --force-expire periodically. How you run it depends on
+ how you've configured SpamAssassin. Running it as Debian-exim may
+ be sufficient.
+
+2 a) In addition, you can add
+
+ bayes_auto_expire 0
+
+ to /etc/spamassassin/local.cf. This may not be a good idea if
+ SpamAssassin, for whatever reason, is also used as a more
+ traditional filter from e.g. .procmailrc, as all users will need to
+ run sa-learn --force-expire then.
+
+2 b) If you get a lot of mail, consider adding
+
+ bayes_learn_to_journal 1
+
+ to local.cf. See the Mail::SpamAssassin::Conf(3) manual page for
+ more information.
+
+**********************************
+* NOTICE ABOUT SPAMC CONFIG FILE *
+**********************************
+
+Recent versions of spamc can read command-line parameters and switches
+from a configuration file called /etc/spamassassin/spamc.conf. If that
+file specifies conflicting options, it will prevent SA-Exim from
+working. For now, you'll have to make sure that it doesn't.
+
+ -- Magnus Holmgren <holmgren@debian.org>, Tue, 24 Jun 2008 14:27:59 +0200
Index: 4.2.1-12/debian/NEWS
===================================================================
--- 4.2.1-12/debian/NEWS (nonexistent)
+++ 4.2.1-12/debian/NEWS (revision 61)
@@ -0,0 +1,18 @@
+sa-exim (4.2.1-8) unstable; urgency=medium
+
+ * Since version 4.67-1, exim4 only exports those symbols that are part
+ of the official local_scan API. Unfortunately, sa-exim has all along
+ cheated and declared some "extern" variables by itself, something that
+ no longer works. For one of these, body_linecount, no workaround is
+ currently possible, meaning that it will not be updated if the message
+ body is rewritten (by way of SpamAssassin's report_safe together with
+ SARewriteBody: 1 in sa-exim.conf. This means that if you use
+ $body_linecount or $message_linecount in string expansions in your
+ Exim configuration, they will refer to the line count before rewriting
+ the message body.
+
+ This change will hopefully be restored soon, either by extending the
+ local_scan API or by making Exim count the lines.
+
+ -- Magnus Holmgren <magnus@kibibyte.se> Thu, 26 Apr 2007 16:22:49 +0200
+
Index: 4.2.1-12/debian/postrm
===================================================================
--- 4.2.1-12/debian/postrm (nonexistent)
+++ 4.2.1-12/debian/postrm (revision 61)
@@ -0,0 +1,57 @@
+#!/bin/sh
+set -e
+
+if [ -f /usr/share/debconf/confmodule ]; then
+ . /usr/share/debconf/confmodule
+fi
+
+LOCALSCANCONF=/etc/exim4/conf.d/main/15_sa-exim_plugin_path
+DISABLELOCALSCANTEXT='# sa-exim plugin is disabled, because it was uninstalled'
+DISABLELOCALSCANMD5=`echo "${DISABLELOCALSCANTEXT}" | md5sum | cut -d\ -f1`
+
+case "$1" in
+ remove)
+ # disable local_scan_path directive to exim working
+ if [ -e "$LOCALSCANCONF" ] && [ ! -e "${LOCALSCANCONF}.rul" ]; then
+ echo "${DISABLELOCALSCANTEXT}" > ${LOCALSCANCONF}.rul
+ fi
+ if [ -x /etc/init.d/exim4 ]; then
+ if [ -x /usr/sbin/invoke-rc.d ]; then
+ invoke-rc.d exim4 reload || true
+ else
+ /etc/init.d/exim4 reload || true
+ fi
+ fi
+ ;;
+
+ purge)
+ # clean up temporary file generated by postrm uninstall
+ if [ -e "${LOCALSCANCONF}.rul" ] && \
+ [ "`md5sum ${LOCALSCANCONF}.rul | cut -d\ -f1`" = "${DISABLELOCALSCANMD5}" ]; then
+ rm ${LOCALSCANCONF}.rul
+ fi
+ if [ -x /etc/init.d/exim4 ]; then
+ if [ -x /usr/sbin/invoke-rc.d ]; then
+ invoke-rc.d exim4 reload || true
+ else
+ /etc/init.d/exim4 reload || true
+ fi
+ fi
+ # In the rather uncommon event that debconf has been removed before
+ # us, we have no choice but leaving the spool directory alone.
+ if [ -e /var/spool/sa-exim ] &&
+ ! rmdir /var/spool/sa-exim 2>/dev/null &&
+ [ -f /usr/share/debconf/confmodule ]; then
+ db_version 2.0
+ db_input medium sa-exim/purge_spool || true
+ db_go || true
+ db_get sa-exim/purge_spool
+ purge_spool="$RET"
+ if [ "x${purge_spool}" = "xtrue" ] ; then
+ rm -rf /var/spool/sa-exim
+ fi
+ fi
+ ;;
+esac
+
+#DEBHELPER#
Index: 4.2.1-12/debian/watch
===================================================================
--- 4.2.1-12/debian/watch (nonexistent)
+++ 4.2.1-12/debian/watch (revision 61)
@@ -0,0 +1,3 @@
+version=3
+
+http://marc.merlins.org/linux/exim/sa.html files/sa-exim-(\d+(?:\.\d+)*)\.tar\.gz
Index: 4.2.1-12/debian/15_sa-exim_plugin_path
===================================================================
--- 4.2.1-12/debian/15_sa-exim_plugin_path (nonexistent)
+++ 4.2.1-12/debian/15_sa-exim_plugin_path (revision 61)
@@ -0,0 +1,9 @@
+# This will enable sa-exim, but it won't actually scan and possibly reject
+# messsages before you enable this in sa-exim.conf (see SAEximRunCond)
+#
+# For a starter, you'd probably want to read the documentation at:
+# /usr/share/doc/sa-exim/README.Debian
+# and
+# /usr/share/doc/sa-exim/README.gz
+#
+local_scan_path = /usr/lib/exim4/local_scan/sa-exim.so
Index: 4.2.1-12/debian/config
===================================================================
--- 4.2.1-12/debian/config (nonexistent)
+++ 4.2.1-12/debian/config (revision 61)
@@ -0,0 +1,5 @@
+#!/bin/sh -e
+
+. /usr/share/debconf/confmodule
+
+exit 0
Index: 4.2.1-12/debian/docs
===================================================================
--- 4.2.1-12/debian/docs (nonexistent)
+++ 4.2.1-12/debian/docs (revision 61)
@@ -0,0 +1,8 @@
+ACKNOWLEDGEMENTS
+Acknowledgements.html
+README
+README.greylisting
+sa.html
+TODO
+contrib/sa-exim-stats.txt
+contrib/spam_resend.txt
Index: 4.2.1-12/Greylisting.pm
===================================================================
--- 4.2.1-12/Greylisting.pm (nonexistent)
+++ 4.2.1-12/Greylisting.pm (revision 61)
@@ -0,0 +1,301 @@
+package Greylisting;
+#
+# $Id: Greylisting.pm,v 1.4 2006/01/11 17:17:28 marcmerlin Exp $
+#
+
+# General Greylisting Plugin, written by Marc MERLIN <marc_soft@merlins.org>
+# (Kristopher Austin gets the credit for the original port to an SA 3.0 plugin)
+#
+# This was originally written to implement greylisting in SA-Exim, although
+# I have tried to make it more general and allow for reuse in other MTAs
+# (although they will need to
+# 1) be running SA at SMTP time
+# 2) Provide the list of rcpt to and env from in some headers for SA to read
+# 3) Provide the IP of the connecting host )
+#
+# This rule should get a negative score so that if we've already seen the
+# greylisting tuplet before, we lower the score, which hopefully brings us from
+# a tempreject to an accept (at least that's how sa-exim does it)
+#
+# -- Marc 2004/01/19
+
+use strict;
+use Mail::SpamAssassin::Plugin;
+our @ISA = qw(Mail::SpamAssassin::Plugin);
+
+sub new
+{
+ my ($class, $mailsa) = @_;
+ $class = ref($class) || $class;
+ my $self = $class->SUPER::new($mailsa);
+ bless ($self, $class);
+ $self->register_eval_rule ("greylisting");
+ return $self;
+}
+
+
+sub check_end
+{
+ my ($self, $permsgstatus) = @_;
+
+ if (not $self->{'rangreylisting'})
+ {
+ Mail::SpamAssassin::Plugin::dbg("GREYLISTING: greylisting didn't run since the configuration wasn't setup to call us");
+ }
+}
+
+# Greylisting happens depending on the SA score, so we want to run it last,
+# which is why we give it a high priority
+sub greylisting
+{
+ my ($self, $permsgstatus, $optionhash) = @_;
+
+ my $connectip;
+ my $envfrom;
+ my $rcptto;
+ my @rcptto;
+ my $iswhitelisted=0;
+ my $err;
+ my $mesgid = $permsgstatus->get('Message-Id')."\n";
+ my $mesgidfn;
+ my $tuplet;
+ my $sascore = $permsgstatus->get_score();
+ my $dontcheckscore;
+ my %option;
+
+ Mail::SpamAssassin::Plugin::dbg("GREYLISTING: called function");
+
+ $optionhash =~ s/;/,/g;
+ # This is safe, right? (users shouldn't be able to set it in their config)
+ %option=eval $optionhash;
+ $self->{'rangreylisting'}=1;
+
+ foreach my $reqoption (qw ( method greylistsecs dontgreylistthreshold
+ connectiphdr envfromhdr rcpttohdr greylistnullfrom greylistfourthbyte ))
+ {
+ die "Greylist option $reqoption missing from SA config" unless (defined $option{$reqoption});
+ }
+
+ $dontcheckscore = $option{'dontgreylistthreshold'};
+
+
+ # No newlines, thank you (yes, you need this twice apparently)
+ chomp ($mesgid);
+ chomp ($mesgid);
+ # Newline in the middle mesgids, are you serious? Get rid of them here
+ $mesgid =~ s/\012/|/g;
+
+ # For stuff that we know is spam, don't greylist the host
+ # (that might help later spam with a lower score to come in)
+ if ($sascore >= $dontcheckscore)
+ {
+ Mail::SpamAssassin::Plugin::dbg("GREYLISTING: skipping greylisting on $mesgid, since score is already $sascore and you configured greylisting not to bother with anything above $dontcheckscore");
+ return 0;
+ }
+ else
+ {
+ Mail::SpamAssassin::Plugin::dbg("GREYLISTING: running greylisting on $mesgid, since score is too low ($sascore) and you configured greylisting to greylist anything under $dontcheckscore");
+ }
+
+ if (not $connectip = $permsgstatus->get($option{'connectiphdr'}))
+ {
+ warn "Couldn't get Connecting IP header $option{'connectiphdr'} for message $mesgid, skipping greylisting call\n";
+ return 0;
+ }
+ chomp($connectip);
+ # Clean up input (for security, if you use files/dirs)
+ $connectip =~ /([\d.:]+)/;
+ $connectip = ($1 or "");
+
+ # Account for a null envelope from
+ if (not defined ($envfrom = $permsgstatus->get($option{'envfromhdr'})))
+ {
+ warn "Couldn't get Envelope From header $option{'envfromhdr'} for message $mesgid, skipping greylisting call\n";
+ return 0;
+ }
+ chomp($envfrom);
+ # Clean up input (for security, if you use files/dirs)
+ $envfrom =~ s#/#-#g;
+ if (not $envfrom)
+ {
+ $envfrom="<>";
+ return 0 if (not $option{'greylistnullfrom'});
+ }
+
+ if (not $rcptto = $permsgstatus->get($option{'rcpttohdr'}))
+ {
+ warn "Couldn't get Rcpt To header $option{'rcpttohdr'} for message $mesgid, skipping greylisting call\n";
+ return 0;
+ }
+ chomp($rcptto);
+ # Clean up input (for security, if you use files/dirs)
+ $rcptto =~ s#/#-#g;
+ @rcptto = split(/, /, $rcptto);
+
+
+ umask 0007;
+
+ foreach $rcptto (@rcptto)
+ {
+ # The dir method is easy to fiddle with and expire records in (with
+ # a find | rm) but it's probably more I/O extensive than a real DB
+ # and suffers from directory size problems if a specific IP is sending
+ # generating tens of thousands of tuplets. -- Marc
+ # That said, I prefer formats I can easily tinker with, and not having
+ # to worry about buggy locking and so forth
+
+ if ($option{'method'} eq "dir")
+ {
+ my $tmpvar;
+
+ # The clean strings are hardcoded because it's hard to do a variable
+ # substitution within a tr (and using the eval solution is too
+ # resource expensive)
+ # envfrom could be cleaned outside of the loop, but the other method
+ # options might now want that
+ $envfrom =~ tr/!#%()*+,-.0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~/_/c;
+ # clean variables to run properly under -T
+ $envfrom =~ /(.+)/;
+ $tmpvar = ($1 or "");
+ # work around bug in perl untaint in perl 5.8
+ $envfrom=undef;
+ $envfrom=$tmpvar;
+ $envfrom =~ s/^([a-z0-9._]*)[^@]*/$1/i;
+
+ $rcptto =~ tr/!#%()*+,-.0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~/_/c;
+ $rcptto =~ /(.+)/;
+ $tmpvar = ($1 or "");
+ $rcptto=undef;
+ $rcptto=$tmpvar;
+
+ die "greylist option dir not passed, even though method was set to dir" unless ($option{'dir'});
+
+ # connectip is supposed to be untainted now, but I was still getting
+ # some insecure dependecy error messages sometimes (perl 5.8 problem apparently)
+ unless ($connectip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) {
+ warn "Can only handle IPv4 addresses; skipping greylisting call for message $mesgid\n";
+ return 0;
+ }
+
+ my $ipdir1 = "$option{'dir'}/$1";
+ my $ipdir2 = "$ipdir1/$2";
+ my $ipdir3 = "$ipdir2/$3";
+ my $ipdir4;
+ my $tupletdir;
+
+ $ipdir4 = "$ipdir3";
+ $ipdir4 .= "/$4" if ($option{'greylistfourthbyte'});
+ $tupletdir = "$ipdir4/$envfrom";
+
+ $tuplet = "$tupletdir/$rcptto";
+
+ # make directory whether it's there or not (faster than test and set)
+ mkdir $ipdir1;
+ mkdir $ipdir2;
+ mkdir $ipdir3;
+ mkdir $ipdir4;
+ mkdir $tupletdir;
+
+ if (not -e $tuplet)
+ {
+ # If the tuplets aren't there, we create them and continue in
+ # case there are other ones (one of them might be whitelisted
+ # already)
+ $err="creating $tuplet";
+ open (TUPLET, ">$tuplet") or goto greylisterror;
+ print TUPLET time."\n";
+ print TUPLET "Status: Greylisted\n";
+ print TUPLET "Last Message-Id: $mesgid\n";
+ print TUPLET "Whitelisted Count: 0\n";
+ print TUPLET "Query Count: 1\n";
+ print TUPLET "SA Score: $sascore\n";
+ $err="closing first-written $tuplet";
+ close TUPLET or goto greylisterror;
+ }
+ else
+ {
+ my $time;
+ my $status;
+ my $whitelistcount;
+ my $querycount;
+
+ # Take into account race condition of expiring deletes and us
+ # running
+ $err="reading $tuplet";
+ open (TUPLET, "<$tuplet") or goto greylisterror;
+ $err="Couldn't read time";
+ defined ($time=<TUPLET>) or goto greylisterror;
+ chomp ($time);
+
+ $err="Couldn't read status";
+ defined ($status=<TUPLET>) or goto greylisterror;
+ chomp ($status);
+ $err="Couldn't extract Status from $status";
+ $status =~ s/^Status: // or goto greylisterror;
+
+ # Skip Mesg-Id
+ $err="Couldn't skip Mesg-Id";
+ defined ($_=<TUPLET>) or goto greylisterror;
+
+ $err="Couldn't read whitelistcount";
+ defined ($whitelistcount=<TUPLET>) or goto greylisterror;
+ chomp ($whitelistcount);
+ $err="Couldn't extract Whitelisted Count from $whitelistcount";
+ $whitelistcount =~ s/^Whitelisted Count: // or goto greylisterror;
+
+ $err="Couldn't read querycount";
+ defined ($querycount=<TUPLET>) or goto greylisterror;
+ chomp ($querycount);
+ $err="Couldn't extract Query Count from $querycount";
+ $querycount =~ s/^Query Count: // or goto greylisterror;
+ close (TUPLET);
+
+ $querycount++;
+ if ((time - $time) > $option{'greylistsecs'})
+ {
+ $status="Whitelisted";
+ $whitelistcount++;
+ }
+
+ $err="re-writing $tuplet";
+ open (TUPLET, ">$tuplet") or goto greylisterror;
+ print TUPLET "$time\n";
+ print TUPLET "Status: $status\n";
+ print TUPLET "Last Message-Id: $mesgid\n";
+ print TUPLET "Whitelisted Count: $whitelistcount\n";
+ print TUPLET "Query Count: $querycount\n";
+ print TUPLET "SA Score: $sascore\n";
+ $err="closing re-written $tuplet";
+ close TUPLET or goto greylisterror;
+
+ # We continue processing the other recipients, to setup or
+ # update their counters
+ if ($status eq "Whitelisted")
+ {
+ $iswhitelisted=1;
+ }
+ }
+ }
+ elsif ($option{'method'} eq "file")
+ {
+ warn "codeme (file greylisting)\n";
+ }
+ elsif ($option{'method'} eq "db")
+ {
+ warn "codeme (db greylisting)\n";
+ }
+ }
+
+ Mail::SpamAssassin::Plugin::dbg("GREYLISTING: computed greylisting on tuplet, saved info in $tuplet and whitelist status is $iswhitelisted");
+ return $iswhitelisted;
+
+ greylisterror:
+ warn "Reached greylisterror: $err / $!";
+ # delete tuplet since it apparently had issues but don't check for errors
+ # in case it was a permission denied on write
+ unlink ($tuplet);
+ return $iswhitelisted;
+}
+
+
+1;
Index: 4.2.1-12/sa-exim.c
===================================================================
--- 4.2.1-12/sa-exim.c (nonexistent)
+++ 4.2.1-12/sa-exim.c (revision 61)
@@ -0,0 +1,1541 @@
+/* Spamassassin in local_scan by Marc MERLIN <marc_soft@merlins.org> */
+/* $Id: sa-exim.c,v 1.71 2005/03/08 20:39:51 marcmerlin Exp $ */
+/*
+
+The inline comments and minidocs were moved to the distribution tarball
+
+You can get the up to date version of this file and full tarball here:
+http://sa-exim.sourceforge.net/
+http://marc.merlins.org/linux/exim/sa.html
+The discussion list is here:
+http://lists.merlins.org/lists/listinfo/sa-exim
+*/
+
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <ctype.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "sa-exim.h"
+
+/* Exim includes */
+#include <local_scan.h>
+//extern int body_linecount; /* Line count in body */
+
+#ifdef DLOPEN_LOCAL_SCAN
+
+/* Karsten Engelke <me@kaeng.org> says this is missing on openbsd */
+#ifndef RTLD_NOW
+#define RTLD_NOW 0x002
+#endif
+
+/* Return the verion of the local_scan ABI, if being compiled as a .so */
+int local_scan_version_major(void)
+{
+ return LOCAL_SCAN_ABI_VERSION_MAJOR;
+}
+
+int local_scan_version_minor(void)
+{
+ return LOCAL_SCAN_ABI_VERSION_MINOR;
+}
+
+/* Left over for compatilibility with old patched exims that didn't have
+ a version number with minor an major. Keep in mind that it will not work
+ with older exim4s (I think 4.11 is required) */
+#ifdef DLOPEN_LOCAL_SCAN_OLD_API
+int local_scan_version(void)
+{
+ return 1;
+}
+#endif
+#endif
+
+#ifndef SAFEMESGIDCHARS
+#define SAFEMESGIDCHARS "!#%( )*+,-.0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~";
+#endif
+
+
+/******************************/
+/* Compile time config values */
+/******************************/
+#ifndef SPAMC_LOCATION
+#define SPAMC_LOCATION "/usr/bin/spamc"
+#endif
+
+#ifndef SPAMASSASSIN_CONF
+#define SPAMASSASSIN_CONF "/etc/exim4/sa-exim.conf"
+#endif
+static const char conffile[]=SPAMASSASSIN_CONF;
+
+
+/********************/
+/* Code starts here */
+/********************/
+static const char nospamstatus[]="<error finding status>";
+
+static char *buffera[4096];
+static char *buffer=(char *)buffera;
+static int SAEximDebug=0;
+static int SAPrependArchiveWithFrom=1;
+static jmp_buf jmp_env;
+
+static char *where="Error handler called without error string";
+static int line=-1;
+static char *panicerror;
+
+#define MIN(a,b) (a<b?a:b)
+
+#define CHECKERR(mret, mwhere, mline) \
+ if (mret < 0) \
+ { \
+ where=mwhere; \
+ line=mline; \
+ goto errexit; \
+ }
+
+#define PANIC(merror) \
+ panicerror=merror; \
+ goto panicexit;
+
+
+static void alarm_handler(int sig)
+{
+ sig = sig; /* Keep picky compilers happy */
+ longjmp(jmp_env, 1);
+}
+
+
+/* Comparing header lines isn't fun, especially since the comparison has to
+ be caseless, so we offload this to this function
+ You can scan on partial headers, just give the root to scan for
+ Return 1 if the header was found, 0 otherwise */
+static int compare_header(char *buffertocompare, char *referenceheader)
+{
+ int idx;
+ int same=1;
+
+ for (idx=0; idx<strlen(referenceheader); idx++)
+ {
+ if ( tolower(referenceheader[idx]) != tolower(buffertocompare[idx]) )
+ {
+ same=0;
+ break;
+ }
+ }
+
+ if (SAEximDebug > 7)
+ {
+ if (same)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug8: Found %s in %s", referenceheader, buffertocompare);
+ }
+ else if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: Did not find %s in %s", referenceheader, buffertocompare);
+ }
+ }
+
+ return same;
+}
+
+
+/* returns a header from a buffer line */
+static char *get_header(char *buffer)
+{
+ char *start;
+ char *end;
+ char *header;
+
+ start=buffer;
+ end=strstr(buffer, ":");
+
+ header=string_copyn(start, end-start);
+
+ if (SAEximDebug>5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: Extracted header %s in buffer %s", header, buffer);
+ }
+
+ return header;
+}
+
+
+/* Rejected mails can be archived in a spool directory */
+/* filename will contain a double / before the filename, I prefer two to none */
+static int savemail(int readfd, off_t fdstart, char *dir, char *dirvarname,
+ char *filename, int SAmaxarchivebody, char *condition)
+{
+ header_line *hl;
+ int writefd=0;
+ int ret;
+ ssize_t stret;
+ off_t otret;
+ char *expand;
+ char *fake_env_from;
+ int towrite;
+ int chunk;
+ struct stat bufst;
+
+ if (dir == NULL)
+ {
+ if (SAEximDebug>4)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug5: Not saving message because %s in undefined", dirvarname);
+ }
+ return 0;
+ }
+
+ if (condition[0] != '1' || condition[1] != 0)
+ {
+ expand=expand_string(condition);
+ if (expand == NULL)
+ {
+ /* Can't use PANIC within this function :( */
+ CHECKERR(-1, string_sprintf("savemail condition expansion failure on %s", condition), __LINE__ - 1);
+ }
+
+ if (SAEximDebug > 2)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug3: savemail condition expand returned: '%s'", expand);
+ }
+
+ if (expand[0] == 0 || (expand[0] == '0' && expand[1] == 0))
+ {
+ if (SAEximDebug > 1)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug2: savemail condition expanded to false, not saving message to disk");
+ }
+ return 0;
+ }
+ }
+
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: Writing message to %s/new/%s", dir, filename);
+
+ }
+
+ if (stat(string_sprintf("%s/new/", dir), &bufst) == -1)
+ {
+ log_write(0, LOG_MAIN, "SA: Notice: creating maildir tree in %s", dir);
+ if (stat(dir, &bufst) == -1)
+ {
+ ret=mkdir (dir, 0770);
+ CHECKERR(ret,string_sprintf("mkdir %s", dir),__LINE__);
+ }
+ ret=mkdir (string_sprintf("%s/new", dir), 0770);
+ CHECKERR(ret,string_sprintf("mkdir %s/new/", dir),__LINE__);
+ ret=mkdir (string_sprintf("%s/cur", dir), 0770);
+ CHECKERR(ret,string_sprintf("mkdir %s/cur/", dir),__LINE__);
+ ret=mkdir (string_sprintf("%s/tmp", dir), 0770);
+ CHECKERR(ret,string_sprintf("mkdir %s/tmp/", dir),__LINE__);
+ }
+
+ /* Let's not worry about you receiving two spams at the same second
+ * with the same message ID. If you do, the second one will overwrite
+ * the first one */
+ writefd=creat(string_sprintf("%s/new/%s", dir, filename), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
+ CHECKERR(writefd, string_sprintf("creat %s/new/%s", dir, filename),__LINE__);
+
+ /* make the file look like a valid mbox -- idea from dman */
+ /* Although now that we use maildir format, this isn't really necessary */
+ /* Richard Lithvall made this an option */
+ if(SAPrependArchiveWithFrom == 1)
+ {
+ fake_env_from=string_sprintf("From %s Thu Jan 1 00:00:01 1970\n",sender_address);
+ stret=write(writefd, fake_env_from, strlen(fake_env_from));
+ CHECKERR(stret,string_sprintf("'From ' line write in %s", filename),__LINE__);
+ }
+
+ /* First we need to get the header lines from exim, and then we can read
+ the body from writefd */
+ hl=header_list;
+ while (hl != NULL)
+ {
+ /* type '*' means the header is internal, don't print it */
+ if (hl->type == '*')
+ {
+ hl=hl->next;
+ continue;
+ }
+ stret=write(writefd,hl->text,strlen(hl->text));
+ CHECKERR(stret,string_sprintf("header line write in %s", filename),__LINE__);
+ hl=hl->next;
+ }
+ stret=write(writefd,"\n",1);
+ CHECKERR(stret,string_sprintf("header separation write in %s", filename),__LINE__);
+
+ /* Now copy the body to the save file */
+ /* we already read from readfd, so we need to reset it */
+ otret=lseek(readfd, fdstart, SEEK_SET);
+ CHECKERR(otret, "lseek reset on spooled message", __LINE__);
+
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: Archive body write starts: writing up to %d bytes in %d byte blocks", SAmaxarchivebody, sizeof(buffera));
+ }
+
+ towrite=SAmaxarchivebody;
+ chunk=0;
+ while (towrite>0 && (stret=read(readfd, buffer, MIN(sizeof(buffera), towrite))) > 0)
+ {
+ chunk++;
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: Processing archive body chunk %d (read %.0f, and %.0f can still be written)", chunk, (double)stret, (double)towrite);
+ }
+ towrite-=stret;
+ stret=write(writefd, buffer, stret);
+ CHECKERR(stret,string_sprintf("body write in %s", filename),__LINE__);
+ }
+ CHECKERR(stret, "read body for archival", __LINE__ - 8);
+ ret=close(writefd);
+ CHECKERR(ret, "Closing spooled message",__LINE__);
+ return 0;
+
+ /* catch the global errexit, clean up, and return the error up */
+ errexit:
+ close(writefd);
+ return -1;
+}
+
+/*
+ * let's add the X-SA-Exim-Connect-IP, X-SA-Exim-Rcpt-To, and
+ * X-SA-Exim-Mail-From headers.
+ * Those are all required by the greylisting with SA implementation
+ * And From/Rcpt-To can also be used for personalized SA rules
+ */
+void AddSAEheaders(char *rcptlist, int SAmaxrcptlistlength)
+{
+ if (sender_host_address)
+ {
+ header_add(' ', "X-SA-Exim-Connect-IP: %s\n", sender_host_address);
+ }
+ else
+ {
+ header_add(' ', "X-SA-Exim-Connect-IP: <locally generated>\n");
+ }
+
+ /* Create a mega envelope-to header with all the recipients */
+ /* Note, if you consider this a privacy violation, you can remove the header
+ * in exim's system filter.
+ * This is very useful to see who a message was really sent to, and can
+ * be used by Spamassassin to do additional scoring */
+ if (strlen(rcptlist) <= SAmaxrcptlistlength)
+ {
+ header_add(' ', "X-SA-Exim-Rcpt-To: %s\n", rcptlist);
+ }
+ /* Therefore SAmaxrcptlistlength set to 0 disables the header completely */
+ else if (SAmaxrcptlistlength)
+ {
+ header_add(' ', "X-SA-Exim-Rcpt-To: too long (recipient list exceeded maximum allowed size of %d bytes)\n", SAmaxrcptlistlength);
+ }
+
+ header_add(' ', "X-SA-Exim-Mail-From: %s\n", sender_address);
+}
+
+void RemoveHeaders(char *headername)
+{
+ header_line *hl;
+
+ /* Remove headers that SA can set */
+ hl=header_list;
+ while (hl != NULL)
+ {
+
+ /* type '*' means the header is internal or deleted */
+ if (hl->type == '*')
+ {
+ hl=hl->next;
+ continue;
+ }
+
+ /* Strip all SA and SA-Exim headers on incoming mail */
+ if ( compare_header((char *)hl->text, headername) )
+ {
+ if (SAEximDebug > 2)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug3: removing header %s on incoming mail '%s'", headername, (char *)hl->text);
+ }
+ hl->type = '*';
+ }
+ hl=hl->next;
+ }
+}
+
+
+/*
+ * Headers can be multi-line (in theory all of them can I think). Parsing them
+ * is a little more work than a simple line scan, so we're off-loading this to
+ * a function
+ */
+int parsemlheader(char *buffer, FILE *readfh, char *headername, char **header)
+{
+ header_line *hl;
+ char *dummy;
+ char *foundheadername;
+
+ if (SAEximDebug > 4)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug5: looking for header %s", headername);
+ }
+
+ if (header == NULL)
+ {
+ header=&dummy;
+ }
+
+ if (compare_header(buffer, string_sprintf("%s", headername)))
+ {
+ *header=string_copy(buffer);
+
+ /* Read the next line(s) in case this is a multi-line header */
+ while ((fgets((char *)buffer,sizeof(buffera),readfh)) != NULL)
+ {
+ /* Remove trailing newline */
+ if (buffer[strlen(buffer)-1] == '\n')
+ {
+ buffer[strlen(buffer)-1]=0;
+ }
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: while parsing header %s, read %s", headername, buffer);
+ }
+ /* concatenated lines only start with space or tab. right? */
+ if (buffer[0] != ' ' && buffer[0] != '\t')
+ {
+ break;
+ }
+
+ /* Guard against humongous header lines */
+ if (strlen(*header) < 8000)
+ {
+ /* Slight waste of memory here, oh well... */
+ *header=string_sprintf("%s\n%s", *header, buffer);
+ }
+ else
+ {
+ log_write(0, LOG_MAIN, "SA: Warning: while parsing header %s, ignoring the following trailing line due to header size overflow: %s", headername, buffer);
+
+ }
+ }
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: header pieced up %s as: '%s'", headername, *header);
+ }
+
+ /* Headers need a newline at the end before being handed out to exim */
+ /* Slight waste of memory here, oh well... */
+ *header=string_sprintf("%s\n", *header);
+
+ foundheadername=get_header(*header);
+
+ /* Mark the former header as deleted if it's already present */
+ /* Note that for X-Spam, it won't since we already deleted it earlier */
+ hl=header_list;
+ while (hl != NULL)
+ {
+ /* type '*' means the header is internal or deleted */
+ if (hl->type == '*')
+ {
+ hl=hl->next;
+ continue;
+ }
+
+ if ( compare_header((char *)hl->text, foundheadername) )
+ {
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: removing old copy of header '%s' and replacing with new one: '%s'", (char *)hl->text, *header);
+ }
+ hl->type = '*';
+ break;
+ }
+ hl=hl->next;
+ }
+
+ header_add(' ', "%s", *header);
+ return 1;
+ }
+ return 0;
+}
+
+
+char *cleanmsgid(char *msgid, char *SAsafemesgidchars)
+{
+ char *safemesgid;
+ char *ptr;
+
+ /* In case the message-Id is too long, let's truncate it */
+ safemesgid=string_copyn(msgid, 220);
+ ptr=safemesgid;
+
+ /* Clean Message-ID to make sure people can't write on our FS */
+ while (*ptr)
+ {
+ /* This might be more aggressive than you want, but since you
+ * potentially have shell programs dealing with the resulting filenames
+ * let's make it a bit safer */
+ if (strchr(SAsafemesgidchars, *ptr) == NULL)
+ {
+ *ptr='_';
+ }
+ ptr++;
+ }
+
+ if (SAEximDebug > 1)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug2: Message-Id taken from Exim and cleaned from: %s to: %s", msgid, safemesgid);
+ }
+
+ return safemesgid;
+}
+
+
+/* Exim calls us here, feeds us a fd on the message body, and expects a return
+ message in *return_text */
+int local_scan(volatile int fd, uschar **return_text)
+{
+#warning you should not worry about the "might be clobbered by longjmp", see source
+ int ret;
+ ssize_t stret;
+ int pid;
+ int writefd[2];
+ int readfd[2];
+ char *spamc_argv[10];
+ int i;
+ /* These are the only values that we want working after the longjmp
+ * The automatic ones can be clobbered, but we don't really care */
+ volatile FILE *readfh;
+ volatile char *mesgfn=NULL;
+ volatile off_t fdsize;
+ volatile off_t scansize;
+ volatile off_t fdstart;
+ volatile char *rcptlist;
+ volatile void *old_sigchld;
+ char *safemesgid=NULL;
+ int isspam=0;
+ int gotsa=0;
+ int chunk;
+ off_t towrite;
+ char *mailinfo;
+ float spamvalue=0.0;
+ char *spamstatus=NULL;
+ time_t beforescan;
+ time_t afterscan;
+ time_t afterwait;
+ time_t scantime=0;
+ time_t fulltime=0;
+ struct stat stbuf;
+
+ uschar *expand;
+ header_line *hl;
+
+ static int readconffile=0;
+ static int wrotedebugenabled=0;
+
+ /* Options we read from /etc/exim4/sa-exim.conf */
+ static char *SAspamcpath=SPAMC_LOCATION;
+ static char *SAsafemesgidchars=SAFEMESGIDCHARS
+ static char *SAspamcSockPath=NULL;
+ static char *SAspamcPort="783";
+ static char *SAspamcHost="127.0.0.1";
+ static char *SAspamcUser=NULL;
+ static char *SAEximRunCond="0";
+ static char *SAEximRejCond="1";
+ static int SAmaxbody=250*1024;
+ static char *SATruncBodyCond="0";
+ static int SARewriteBody=0;
+ static int SAmaxarchivebody=20*1048576;
+ static int SAerrmaxarchivebody=1024*1048576;
+ static int SAmaxrcptlistlength=0;
+ static int SAaddSAEheaderBeforeSA=1;
+ static int SAtimeout=240;
+ static char *SAtimeoutsave=NULL;
+ static char *SAtimeoutSavCond="1";
+ static char *SAerrorsave=NULL;
+ static char *SAerrorSavCond="1";
+ static int SAtemprejectonerror=0;
+ static char *SAteergrube="1048576";
+ static float SAteergrubethreshold;
+ /* This is obsolete, since SAteergrube (now a condition) can do the same */
+ static char *SAteergrubecond="1";
+ static int SAteergrubetime=900;
+ static char *SAteergrubeSavCond="1";
+ static char *SAteergrubesave=NULL;
+ static int SAteergrubeoverwrite=1;
+ static char *SAdevnull="1048576";
+ static float SAdevnullthreshold;
+ static char *SAdevnullSavCond="1";
+ static char *SAdevnullsave=NULL;
+ static char *SApermreject="1048576";
+ static float SApermrejectthreshold;
+ static char *SApermrejectSavCond="1";
+ static char *SApermrejectsave=NULL;
+ static char *SAtempreject="1048576";
+ static float SAtemprejectthreshold;
+ static char *SAtemprejectSavCond="1";
+ static char *SAtemprejectsave=NULL;
+ static int SAtemprejectoverwrite=1;
+ static char *SAgreylistiswhitestr="GREYLIST_ISWHITE";
+ static float SAgreylistraisetempreject=3.0;
+ static char *SAspamacceptsave=NULL;
+ static char *SAspamacceptSavCond="0";
+ static char *SAnotspamsave=NULL;
+ static char *SAnotspamSavCond="0";
+ /* Those variables can take a %s to show the spam info */
+ static char *SAmsgteergrubewait="wait for more output";
+ static char *SAmsgteergruberej="Please try again later";
+ static char *SAmsgpermrej="Rejected";
+ static char *SAmsgtemprej="Please try again later";
+ /* Do not put a %s in there, or you'll segfault */
+ static char *SAmsgerror="Temporary local error while processing message, please contact postmaster";
+
+ /* This needs to be retrieved through expand_string in order
+ not to violate the API. */
+ static uschar *primary_hostname;
+ if (!primary_hostname) {
+ store_pool = POOL_PERM;
+ primary_hostname = expand_string("$primary_hostname");
+ store_pool = POOL_MAIN;
+ }
+
+ /* New values we read from spamassassin */
+ char *xspamstatus=NULL;
+ char *xspamflag=NULL;
+
+
+ /* Any error can write the faulty message to mesgfn, so we need to
+ give it a value right now. We'll set the real value later */
+ /* message_id here comes from Exim, it's an internal disk Mesg-Id format
+ which doesn't correlate to the actual message's Mesg-Id. We shouldn't
+ need to clean it, and besides, SAsafemesgidchars hasn't been read from
+ the config file yet, but eh, safety is always a good thing, right? */
+ safemesgid=cleanmsgid(message_id, SAsafemesgidchars);
+ mesgfn=string_sprintf("%d_%s", time(NULL), safemesgid);
+
+ /* We won't scan local messages. I think exim bypasses local_scan for a
+ * bounce generated after a locally submitted message, but better be safe */
+ /* This is commented out now, because you can control it with SAEximRunCond
+ if (!sender_host_address)
+ {
+ return LOCAL_SCAN_ACCEPT;
+ }
+ */
+
+ /* If you discard a mail with exim ACLs, we get 0 recipients, so let's just
+ * accept the mail, which won't matter either way since it'll get dropped
+ * (thanks to John Horne for reporting this corner case) */
+ if (recipients_count == 0)
+ {
+ return LOCAL_SCAN_ACCEPT;
+ }
+
+ /*
+ * We keep track of whether we've alrady read the config file, but since
+ * exim spawns itself, it will get read by exim children even though you
+ * didn't restart exim. That said, after you change the config file, you
+ * should restart exim to make sure all the instances pick up the new
+ * config file
+ */
+ if (!readconffile)
+ {
+ ret=open(conffile, 0);
+ CHECKERR(ret,string_sprintf("conf file open for %s", conffile),__LINE__);
+ readfh=fdopen(ret, "r");
+ CHECKERR(readfh,"fdopen",__LINE__);
+
+ while ((fgets((char *)buffer, sizeof(buffera), (FILE *)readfh)) != NULL)
+ {
+ if (*buffer == '#' || *buffer == '\n' )
+ {
+ continue;
+ }
+
+ if (*buffer != 'S' || *(buffer+1) != 'A')
+ {
+ log_write(0, LOG_MAIN, "SA: Warning: error while reading configuration file %s. Line does not begin with a SA directive: '%s', ignoring", conffile, buffer);
+ continue;
+ }
+
+#define M_CHECKFORVAR(VAR, TYPE) \
+ if (strstr(buffer, #VAR ": ") == buffer) \
+ { \
+ if (sscanf(buffer, #VAR ": " TYPE, &VAR)) \
+ { \
+ if (SAEximDebug > 3) \
+ { \
+ if (SAEximDebug && ! wrotedebugenabled) \
+ { \
+ log_write(0, LOG_MAIN, "SA: Debug4: Debug enabled, reading config from file %s", conffile); \
+ wrotedebugenabled=1; \
+ } \
+ else \
+ { \
+ log_write(0, LOG_MAIN, "SA: Debug4: config read " #VAR " = " TYPE, VAR); \
+ }\
+ }\
+ } \
+ else \
+ { \
+ log_write(0, LOG_MAIN, "SA: Warning: error while reading configuration file %s. Can't parse value in: '%s', ignoring", conffile, buffer); \
+ } \
+ continue; \
+ }
+
+#define M_CHECKFORSTR(VAR) \
+ if (strstr(buffer, #VAR ": ") == buffer) \
+ { \
+ VAR = strdup(buffer+strlen( #VAR )+2); \
+ if (VAR == NULL) \
+ { \
+ log_write(0, LOG_MAIN, "SA: PANIC: malloc failed, quitting..."); \
+ exit(-1); \
+ } \
+ \
+ if (VAR[strlen(VAR)-1] == '\n') \
+ { \
+ VAR[strlen(VAR)-1]=0; \
+ } \
+ if (SAEximDebug > 3) \
+ { \
+ log_write(0, LOG_MAIN, "SA: Debug4: config read " #VAR " = %s", VAR); \
+ } \
+ continue; \
+ }
+
+ M_CHECKFORVAR(SAEximDebug, "%d");
+ M_CHECKFORSTR(SAspamcpath);
+ M_CHECKFORSTR(SAsafemesgidchars);
+ M_CHECKFORSTR(SAspamcSockPath);
+ M_CHECKFORSTR(SAspamcPort);
+ M_CHECKFORSTR(SAspamcHost);
+ M_CHECKFORSTR(SAspamcUser);
+ M_CHECKFORSTR(SAEximRunCond);
+ M_CHECKFORSTR(SAEximRejCond);
+ M_CHECKFORVAR(SAmaxbody, "%d");
+ M_CHECKFORSTR(SATruncBodyCond);
+ M_CHECKFORVAR(SARewriteBody, "%d");
+ M_CHECKFORVAR(SAPrependArchiveWithFrom, "%d");
+ M_CHECKFORVAR(SAmaxarchivebody, "%d");
+ M_CHECKFORVAR(SAerrmaxarchivebody, "%d");
+ M_CHECKFORVAR(SAmaxrcptlistlength, "%d");
+ M_CHECKFORVAR(SAaddSAEheaderBeforeSA, "%d");
+ M_CHECKFORVAR(SAtimeout, "%d");
+ M_CHECKFORSTR(SAtimeoutsave);
+ M_CHECKFORSTR(SAtimeoutSavCond);
+ M_CHECKFORSTR(SAerrorsave);
+ M_CHECKFORSTR(SAerrorSavCond);
+ M_CHECKFORVAR(SAtemprejectonerror, "%d");
+ M_CHECKFORSTR(SAteergrube);
+ M_CHECKFORSTR(SAteergrubecond);
+ M_CHECKFORVAR(SAteergrubetime, "%d");
+ M_CHECKFORSTR(SAteergrubeSavCond);
+ M_CHECKFORSTR(SAteergrubesave);
+ M_CHECKFORVAR(SAteergrubeoverwrite, "%d");
+ M_CHECKFORSTR(SAdevnull);
+ M_CHECKFORSTR(SAdevnullSavCond);
+ M_CHECKFORSTR(SAdevnullsave);
+ M_CHECKFORSTR(SApermreject);
+ M_CHECKFORSTR(SApermrejectsave);
+ M_CHECKFORSTR(SApermrejectSavCond);
+ M_CHECKFORSTR(SAtempreject);
+ M_CHECKFORSTR(SAtemprejectSavCond);
+ M_CHECKFORSTR(SAtemprejectsave);
+ M_CHECKFORVAR(SAtemprejectoverwrite, "%d");
+ M_CHECKFORSTR(SAgreylistiswhitestr);
+ M_CHECKFORVAR(SAgreylistraisetempreject, "%f");
+ M_CHECKFORSTR(SAspamacceptsave);
+ M_CHECKFORSTR(SAspamacceptSavCond);
+ M_CHECKFORSTR(SAnotspamsave);
+ M_CHECKFORSTR(SAnotspamSavCond);
+ M_CHECKFORSTR(SAmsgteergrubewait);
+ M_CHECKFORSTR(SAmsgteergruberej);
+ M_CHECKFORSTR(SAmsgpermrej);
+ M_CHECKFORSTR(SAmsgtemprej);
+ M_CHECKFORSTR(SAmsgerror);
+
+
+ }
+
+ readconffile=1;
+ }
+
+#define M_CONDTOFLOAT(VAR) \
+ if ((expand=expand_string( VAR )) == NULL) \
+ { \
+ PANIC(string_sprintf(#VAR " config expansion failure on %s", #VAR ));\
+ } \
+ sscanf(expand, "%f", &VAR ## threshold); \
+ if (SAEximDebug > 2) \
+ { \
+ log_write(0, LOG_MAIN, "SA: Debug3: expanded " #VAR " = %.2f", VAR ## threshold); \
+ }\
+
+ M_CONDTOFLOAT(SAteergrube);
+ M_CONDTOFLOAT(SAdevnull);
+ M_CONDTOFLOAT(SApermreject);
+ M_CONDTOFLOAT(SAtempreject);
+
+ /* Initialize the list of recipients here */
+ rcptlist=string_copy(recipients_list[0].address);
+ for (i=1; i < recipients_count && strlen((char *)rcptlist) < 7998 - strlen(recipients_list[i].address); i++)
+ {
+ rcptlist=string_sprintf("%s, %s", rcptlist, recipients_list[i].address);
+ }
+
+ if (sender_host_address != NULL)
+ {
+ mailinfo=string_sprintf("From <%s> (host=%s [%s]) for",
+ sender_address, sender_host_name, sender_host_address);
+ }
+ else
+ {
+ mailinfo=string_sprintf("From <%s> (local) for", sender_address);
+ }
+ mailinfo=string_sprintf("%s %s", mailinfo, rcptlist);
+
+
+ /* Remove SA-Exim headers that could have been set before we add ours*/
+ RemoveHeaders("X-SA-Exim-");
+
+ if(SAaddSAEheaderBeforeSA)
+ {
+ AddSAEheaders((char *)rcptlist, SAmaxrcptlistlength);
+ }
+
+ /* This is used later if we need to rewind and save the body elsewhere */
+ fdstart=lseek(fd, 0, SEEK_CUR);
+ CHECKERR(fdstart,"lseek SEEK_CUR",__LINE__);
+
+ ret=fstat(fd, &stbuf);
+ CHECKERR(ret,"fstat fd",__LINE__);
+ /* this is the body size plus a few bytes (exim msg ID) */
+ /* it should be 18 bytes, but I'll assume it could be more or less */
+ fdsize=stbuf.st_size;
+
+ if (SAEximDebug > 3)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug4: Message body is about %.0f bytes and the initial offset is %.0f", (double)(fdsize-18), (double)fdstart);
+ }
+
+ if (fdsize > SAmaxbody)
+ {
+ if (SATruncBodyCond[0] != '1' || SATruncBodyCond[1] != 0)
+ {
+ expand=expand_string(SATruncBodyCond);
+ if (expand == NULL)
+ {
+ PANIC(string_sprintf("SATruncBodyCond expansion failure on %s", SATruncBodyCond));
+ }
+
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: SATruncBodyCond expand returned: '%s'", expand);
+ }
+
+ if (expand[0] == 0 || (expand[0] == '0' && expand[1] == 0))
+ {
+ log_write(0, LOG_MAIN, "SA: Action: check skipped due to message size (%.0f bytes) and SATruncBodyCond expanded to false (Message-Id: %s). %s", (double)(fdsize-18), safemesgid, mailinfo);
+ header_add(' ', "X-SA-Exim-Scanned: No (on %s); Message bigger than SAmaxbody (%d)\n", primary_hostname, SAmaxbody);
+ return LOCAL_SCAN_ACCEPT;
+ }
+ }
+
+ if (SAEximDebug > 1)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug2: Message body is about %.0f bytes and SATruncBodyCond expanded to true, will feed a truncated body to SA", (double)(fdsize-18));
+ }
+
+ /* Let's feed exactly spamc will accept */
+ scansize=SAmaxbody;
+ header_add(' ', "X-SA-Exim-Scan-Truncated: Fed %.0f bytes of the body to SA instead of %.0f\n", (double)scansize, (double)fdsize);
+ }
+ else
+ {
+ scansize=fdsize;
+ }
+
+ expand=expand_string(SAEximRunCond);
+ if (expand == NULL)
+ {
+ PANIC(string_sprintf("SAEximRunCond expansion failure on %s", SAEximRunCond));
+ }
+
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: SAEximRunCond expand returned: '%s'", expand);
+ }
+
+
+ /* Bail from SA if the expansion string says so */
+ if (expand[0] == 0 || (expand[0] == '0' && expand[1] == 0))
+ {
+ log_write(0, LOG_MAIN, "SA: Action: Not running SA because SAEximRunCond expanded to false (Message-Id: %s). %s", safemesgid, mailinfo);
+ header_add(' ', "X-SA-Exim-Scanned: No (on %s); SAEximRunCond expanded to false\n", primary_hostname);
+ return LOCAL_SCAN_ACCEPT;
+ }
+
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: check succeeded, running spamc");
+ }
+
+ /* Ok, so now that we know we're running SA, we remove the X-Spam headers */
+ /* that might have been there */
+ RemoveHeaders("X-Spam-");
+
+
+ beforescan=time(NULL);
+ /* Fork off spamc, and get ready to talk to it */
+ ret=pipe(writefd);
+ CHECKERR(ret,"write pipe",__LINE__);
+ ret=pipe(readfd);
+ CHECKERR(ret,"read pipe",__LINE__);
+
+ /* Ensure that SIGCHLD isn't being ignored. */
+ old_sigchld = signal(SIGCHLD, SIG_DFL);
+
+ if ((pid=fork()) < 0)
+ {
+ CHECKERR(pid, "fork", __LINE__ - 1);
+ }
+
+ if (pid == 0)
+ {
+ close(readfd[0]);
+ close(writefd[1]);
+
+ ret=dup2(writefd[0],0);
+ CHECKERR(ret,"dup2 stdin",__LINE__);
+ ret=dup2(readfd[1],1);
+ CHECKERR(ret,"dup2 stdout",__LINE__);
+ ret=dup2(readfd[1],2);
+ CHECKERR(ret,"dup2 stderr",__LINE__);
+
+ i = 0;
+ spamc_argv[i++] = "spamc";
+ if (SAspamcUser && SAspamcUser[0])
+ {
+ expand=expand_string(SAspamcUser);
+ if (expand == NULL)
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "SA: SAspamcUser expansion failure on %s, will run as Exim user instead.", SAspamcUser);
+ }
+ else if (expand[0] != '\0')
+ {
+ spamc_argv[i++] = "-u";
+ spamc_argv[i++] = expand;
+ }
+ }
+
+ /*
+ * I could implement the spamc protocol and talk to spamd directly
+ * instead of forking spamc, but considering the overhead spent
+ * in spamd, forking off spamc seemed acceptable rather than
+ * re-implementing and tracking the spamc/spamd protocol or linking
+ * with a possibly changing library
+ */
+ /* Ok, we cheat, spamc cares about how big the whole message is and
+ * we only know about the body size, so I'll give an extra 16K
+ * to account for any headers that can accompany the message */
+
+ spamc_argv[i++] = "-s";
+ spamc_argv[i++] = string_sprintf("%d", SAmaxbody+16384);
+
+ if(SAspamcSockPath)
+ {
+ spamc_argv[i++] = "-U";
+ spamc_argv[i++] = SAspamcSockPath;
+ }
+ else
+ {
+ spamc_argv[i++] = "-d";
+ spamc_argv[i++] = SAspamcHost;
+ spamc_argv[i++] = "-p";
+ spamc_argv[i++] = SAspamcPort;
+ }
+ spamc_argv[i++] = NULL;
+
+ ret=execv(SAspamcpath, spamc_argv);
+ CHECKERR(ret,string_sprintf("exec %s", SAspamcpath),__LINE__);
+ }
+
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: forked spamc");
+ }
+
+ ret=close(readfd[1]);
+ CHECKERR(ret,"close r",__LINE__);
+ ret=close(writefd[0]);
+ CHECKERR(ret,"close w",__LINE__);
+ readfh=fdopen(readfd[0], "r");
+
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: closed filehandles");
+ }
+
+ /* Ok, we're ready for spewing the mail at spamc */
+ /* First we need to get the header lines from exim, and then we can read
+ the body from fd */
+ hl=header_list;
+ while (hl != NULL)
+ {
+ /* type '*' means the header is internal, don't print it */
+ if (hl->type == '*')
+ {
+ hl=hl->next;
+ continue;
+ }
+
+ stret=write(writefd[1],hl->text,strlen(hl->text));
+ CHECKERR(stret,"header line write",__LINE__);
+
+ hl=hl->next;
+ }
+ stret=write(writefd[1],"\n",1);
+ CHECKERR(stret,"header separation write",__LINE__);
+
+ if (SAEximDebug > 6)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug7: sent headers to spamc pipe. Sending body...");
+ }
+
+ towrite=scansize;
+ chunk=0;
+ while (towrite>0 && (stret=read(fd, buffer, MIN(sizeof(buffera), towrite))) > 0)
+ {
+ chunk++;
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: spamc body going to write chunk %d (read %.0f, %.0f left to write)", chunk, (double)stret, (double)towrite);
+ }
+ towrite-=stret;
+ stret=write(writefd[1], buffer, stret);
+ CHECKERR(stret,"body write in",__LINE__);
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: Spamc body wrote chunk %d (wrote %.0f, %.0f left to write)", chunk, (double)stret, (double)towrite);
+ }
+ }
+ CHECKERR(stret, "read body", __LINE__ - 14);
+ close(writefd[1]);
+
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: fed spam to spamc, reading result");
+ }
+
+ if (SAtimeout)
+ {
+ if (SAEximDebug > 2)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug3: Setting timeout of %d secs before reading from spamc", SAtimeout);
+ }
+ /* SA can take very long to run for various reasons, let's not wait
+ * forever, that's just bad at SMTP time */
+ if (setjmp(jmp_env) == 0)
+ {
+ signal(SIGALRM, alarm_handler);
+ alarm (SAtimeout);
+ }
+ else
+ {
+ /* Make sure that all your variables here are volatile or static */
+ signal(SIGCHLD, old_sigchld);
+ fclose((FILE *)readfh);
+
+ header_add(' ', "X-SA-Exim-Scanned: No (on %s); SA Timed out after %d secs\n", primary_hostname, SAtimeout);
+
+ /* We sent it to LOG_REJECT too so that we get a header dump */
+ log_write(0, LOG_MAIN | LOG_REJECT, "SA: Action: spamd took more than %d secs to run, accepting message (scanned in %d/%d secs | Message-Id: %s). %s", SAtimeout, scantime, fulltime, safemesgid, mailinfo);
+
+ ret=savemail(fd, fdstart, SAtimeoutsave, "SAtimeoutsave", (char *)mesgfn, SAerrmaxarchivebody, SAtimeoutSavCond);
+ CHECKERR(ret,where,line);
+
+ /* Make sure we kill spamc in case SIGPIPE from fclose didn't */
+ kill(pid, SIGTERM);
+ return LOCAL_SCAN_ACCEPT;
+
+ }
+ }
+
+ /* Let's see what SA has to tell us about this mail and store the headers */
+ while ((fgets((char *)buffer,sizeof(buffera),(FILE *) readfh)) != NULL)
+ {
+ /* Remove trailing newline */
+ if (buffer[strlen(buffer)-1] == '\n')
+ {
+ buffer[strlen(buffer)-1]=0;
+ }
+restart:
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: spamc read: %s", buffer);
+ }
+
+ /* Let's handle special multi-line headers first, what a pain... */
+ /* We feed the one line we read and the filehandle because we'll need
+ to check whether more lines need to be concatenated */
+ /* This is ugly, there is an order dependency so we return to the
+ beginning of the loop without reading a new line since we already
+ did that */
+ if (parsemlheader(buffer, (FILE *)readfh, "Subject", NULL)) goto restart;
+ if ((SARewriteBody == 1) && parsemlheader(buffer, (FILE *)readfh, "Content-Type", NULL)) goto restart;
+ if ((SARewriteBody == 1) && parsemlheader(buffer, (FILE *)readfh, "Content-Transfer-Encoding", NULL)) goto restart;
+
+ if (parsemlheader(buffer, (FILE *)readfh, "X-Spam-Flag", &xspamflag))
+ {
+ if (xspamflag[13] == 'Y')
+ {
+ isspam=1;
+ }
+ if (SAEximDebug > 2)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug3: isspam read from X-Spam-Flag: %d", isspam);
+ }
+ goto restart;
+ }
+
+ if (parsemlheader(buffer, (FILE *)readfh, "X-Spam-Status", &xspamstatus))
+ {
+ char *start;
+ char *end;
+
+ gotsa=1;
+
+ /* if we find the preconfigured greylist string (and it is defined
+ * in sa-exim.conf), we can raise the threshold for tempreject just
+ * for this mail, since it's been whitelisted */
+ if (SAgreylistiswhitestr && strstr(xspamstatus, SAgreylistiswhitestr))
+ {
+ SAtemprejectthreshold+=SAgreylistraisetempreject;
+ if (SAEximDebug > 2)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug3: read %s string, SAtempreject is now changed to %f", SAgreylistiswhitestr, SAtemprejectthreshold);
+ }
+ }
+ else
+ {
+ if (SAEximDebug > 2)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug3: did not find read GREYLIST_ISWHITE string in X-Spam-Status");
+ }
+ }
+
+ start=strstr(xspamstatus, "hits=");
+ /* Support SA 3.0 format */
+ if (start == NULL)
+ {
+ start=strstr(xspamstatus, "score=");
+ }
+
+ end=strstr(xspamstatus, " tests=");
+ if (end == NULL)
+ {
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: Could not find old spamstatus format, trying new one...");
+ }
+ end=strstr(xspamstatus, "\n tests=");
+ }
+ if (start!=NULL && end!=NULL)
+ {
+ spamstatus=string_copyn(start, end-start);
+ if (SAEximDebug > 2)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug3: Read from X-Spam-Status: %s", spamstatus);
+ }
+ }
+ else
+ {
+ PANIC(string_sprintf("SA: could not parse X-Spam-Status: to extract hits and required. Bad!. Got: '%s'", xspamstatus));
+ }
+
+ start=strstr(spamstatus, "=");
+ end=strstr(spamstatus, " ");
+ if (start!=NULL && end!=NULL)
+ {
+ start++;
+ sscanf(start, "%f", &spamvalue);
+ }
+ else
+ {
+ PANIC(string_sprintf("SA: spam value extract failed in '%s'. Bad!", xspamstatus));
+ }
+
+ goto restart;
+ }
+
+ if (parsemlheader(buffer, (FILE *)readfh, "X-Spam-", NULL)) goto restart;
+
+ /* Ok, now we can do normal processing */
+
+ /* If no more headers here, we're done */
+ if (buffer[0] == 0)
+ {
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: spamc read got newline, end of headers", buffer);
+ }
+ goto exit;
+ }
+
+ if (compare_header(buffer, "Message-Id: "))
+ {
+ char *start;
+ char *end;
+ char *mesgid=NULL;
+
+ start=strchr(buffer, '<');
+ end=strchr(buffer, '>');
+
+ if (start == NULL || end == NULL)
+ {
+ /* we keep the default mesgfn (unix date in seconds) */
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: Could not get Message-Id from %s", buffer);
+ }
+ }
+ else if ((mesgid=string_copyn(start+1,end-start-1)) && mesgid[0])
+ {
+ /* We replace the exim Message-ID with the one read from
+ the message * as we use this to detect dupes when we
+ send 45x and get the same * message multiple times */
+ safemesgid=cleanmsgid(mesgid, SAsafemesgidchars);
+ mesgfn=string_sprintf("%d_%s", time(NULL), safemesgid);
+
+ if (SAEximDebug > 5)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug6: Message-Id received and cleaned as: %s", safemesgid);
+ }
+ }
+ continue;
+ }
+ }
+
+ exit:
+
+
+ if (isspam && SARewriteBody == 1)
+ {
+ int line;
+
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: SARewriteBody == 1, rewriting message body");
+ }
+
+ /* already read from fd? Better reset it... */
+ ret=lseek(fd, fdstart, SEEK_SET);
+ CHECKERR(ret, "lseek reset on spooled message", __LINE__);
+
+ line=1;
+ while ((fgets((char *)buffer,sizeof(buffera),(FILE *) readfh)) != NULL)
+ {
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: Read body from SA; line %d (read %d)", line, strlen(buffer));
+ }
+
+ stret=write(fd, buffer, strlen(buffer));
+ CHECKERR(stret,string_sprintf("SA body write to msg"),__LINE__);
+ if (SAEximDebug > 8)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug9: Wrote to msg; line %d (wrote %d)", line, ret);
+ }
+ if (buffer[strlen(buffer)-1] == '\n')
+ {
+ line++;
+ }
+ }
+
+/* if (SAEximDebug > 1)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug2: body_linecount before SA: %d", body_linecount);
+ }
+*/
+ /* update global variable $body_linecount to reflect the new body size*/
+/* body_linecount = (line - 1);
+
+ if (SAEximDebug > 1)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug2: body_linecount after SA: %d", body_linecount);
+ }
+*/
+ }
+
+ fclose((FILE *)readfh);
+
+ afterscan=time(NULL);
+ scantime=afterscan-beforescan;
+
+ wait(&ret);
+ signal(SIGCHLD, old_sigchld);
+
+ if (ret)
+ {
+ sprintf(buffer, "%d", ret);
+ PANIC(string_sprintf("wait on spamc child yielded, %s", buffer));
+ }
+
+ afterwait=time(NULL);
+ fulltime=afterwait-beforescan;
+
+ if(!SAaddSAEheaderBeforeSA)
+ {
+ AddSAEheaders((char *)rcptlist, SAmaxrcptlistlength);
+ }
+
+ header_add(' ', "X-SA-Exim-Version: %s\n",version);
+
+ if (gotsa == 0)
+ {
+ header_add(' ', "X-SA-Exim-Scanned: No (on %s); Unknown failure\n", primary_hostname);
+ log_write(0, LOG_MAIN, "SA: Action: SA didn't successfully run against message, accepting (time: %d/%d secs | Message-Id: %s). %s", scantime, fulltime, safemesgid, mailinfo);
+ return LOCAL_SCAN_ACCEPT;
+ }
+
+ header_add(' ', "X-SA-Exim-Scanned: Yes (on %s)\n", primary_hostname);
+
+ if (spamstatus == NULL)
+ {
+ spamstatus = (char *) nospamstatus;
+ }
+ if (isspam)
+ {
+ int dorej=1;
+ int doteergrube=0;
+
+ if (SAEximRejCond[0] != '1' || SAEximRejCond[1] != 0)
+ {
+ expand=expand_string(SAEximRejCond);
+ if (expand == NULL)
+ {
+ PANIC(string_sprintf("SAEximRejCond expansion failure on %s", SAEximRejCond));
+ }
+
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: SAEximRejCond expand returned: '%s'", expand);
+ }
+
+ if (expand[0] == 0 || (expand[0] == '0' && expand[1] == 0))
+ {
+ log_write(0, LOG_MAIN, "SA: Notice: SAEximRejCond expanded to false, not applying reject rules");
+ dorej=0;
+ }
+ }
+
+ if (dorej && spamvalue >= SAteergrubethreshold)
+ {
+ doteergrube=1;
+ if (SAteergrubecond[0] != '1' || SAteergrubecond[1] != 0)
+ {
+ expand=expand_string(SAteergrubecond);
+ if (expand == NULL)
+ {
+ PANIC(string_sprintf("SAteergrubecond expansion failure on %s", SAteergrubecond));
+ }
+
+ if (SAEximDebug)
+ {
+ log_write(0, LOG_MAIN, "SA: Debug: SAteergrubecond expand returned: '%s'", expand);
+ }
+
+ if (expand[0] == 0 || (expand[0] == '0' && expand[1] == 0))
+ {
+ log_write(0, LOG_MAIN, "SA: Notice: SAteergrubecond expanded to false, not teergrubing known peer");
+ doteergrube=0;
+ }
+ }
+ }
+
+ if (dorej && doteergrube)
+ {
+ char *teergrubewaitstr;
+ teergrubewaitstr=string_sprintf(SAmsgteergrubewait, spamstatus);
+
+ /* By default, we'll only save temp bounces by message ID so
+ * that when the same message is submitted several times, we
+ * overwrite the same file on disk and not create a brand new
+ * one every single time */
+ if (SAteergrubeoverwrite)
+ {
+ ret=savemail(fd, fdstart, SAteergrubesave, "SAteergrubesave", safemesgid, SAmaxarchivebody, SAteergrubeSavCond);
+ CHECKERR(ret,where,line);
+ }
+ else
+ {
+ ret=savemail(fd, fdstart, SAteergrubesave, "SAteergrubesave", (char *)mesgfn, SAmaxarchivebody, SAteergrubeSavCond);
+ CHECKERR(ret,where,line);
+ }
+
+ spamstatus=string_sprintf("%s trigger=%.1f", spamstatus, SAteergrubethreshold);
+ /* Exim might want to stop us if we run for too long, but that's
+ * exactly what we're trying to do, so let's override that */
+ alarm(0);
+
+ for (i=0;i<SAteergrubetime/10;i++)
+ {
+ smtp_printf("451-%s\r\n", teergrubewaitstr);
+ ret=smtp_fflush();
+ if (ret != 0)
+ {
+ log_write(0, LOG_MAIN | LOG_REJECT, "SA: Action: teergrubed sender for %d secs until it closed the connection: %s (scanned in %d/%d secs | Message-Id: %s). %s", i*10, spamstatus, scantime, fulltime, safemesgid, mailinfo);
+ /* The other side closed the connection, nothing to print */
+ *return_text="";
+ return LOCAL_SCAN_TEMPREJECT_NOLOGHDR;
+ }
+ sleep(10);
+ }
+
+ log_write(0, LOG_MAIN | LOG_REJECT, "SA: Action: teergrubed sender until full configured duration of %d secs: %s (scanned in %d/%d secs | Message-Id: %s). %s", SAteergrubetime, spamstatus, scantime, fulltime, safemesgid, mailinfo);
+ *return_text=string_sprintf(SAmsgteergruberej, spamstatus);
+ return LOCAL_SCAN_TEMPREJECT_NOLOGHDR;
+ }
+ else if (dorej && spamvalue >= SAdevnullthreshold)
+ {
+ ret=savemail(fd, fdstart, SAdevnullsave, "SAdevnullsave", (char *)mesgfn, SAmaxarchivebody, SAdevnullSavCond);
+ CHECKERR(ret,where,line);
+
+ recipients_count=0;
+ spamstatus=string_sprintf("%s trigger=%.1f", spamstatus, SAdevnullthreshold);
+ log_write(0, LOG_REJECT | LOG_MAIN, "SA: Action: silently tossed message: %s (scanned in %d/%d secs | Message-Id: %s). %s", spamstatus, scantime, fulltime, safemesgid, mailinfo);
+ return LOCAL_SCAN_ACCEPT;
+ }
+ else if (dorej && spamvalue >= SApermrejectthreshold)
+ {
+ ret=savemail(fd, fdstart, SApermrejectsave, "SApermrejectsave", (char *)mesgfn, SAmaxarchivebody, SApermrejectSavCond);
+ CHECKERR(ret,where,line);
+
+ spamstatus=string_sprintf("%s trigger=%.1f", spamstatus, SApermrejectthreshold);
+ log_write(0, LOG_MAIN | LOG_REJECT, "SA: Action: permanently rejected message: %s (scanned in %d/%d secs | Message-Id: %s). %s", spamstatus, scantime, fulltime, safemesgid, mailinfo);
+ *return_text=string_sprintf(SAmsgpermrej, spamstatus);
+ return LOCAL_SCAN_REJECT_NOLOGHDR;
+ }
+ else if (dorej && spamvalue >= SAtemprejectthreshold)
+ {
+ /* Yeah, gotos are harmful, but that'd be a function with a lot
+ * of options to send, so, here's a small shortcut */
+ goto dotempreject;
+ }
+ else
+ {
+ ret=savemail(fd, fdstart, SAspamacceptsave, "SAspamacceptsave", (char *)mesgfn, SAmaxarchivebody, SAspamacceptSavCond);
+ CHECKERR(ret,where,line);
+ log_write(0, LOG_MAIN, "SA: Action: flagged as Spam but accepted: %s (scanned in %d/%d secs | Message-Id: %s). %s", spamstatus, scantime, fulltime, safemesgid, mailinfo);
+ return LOCAL_SCAN_ACCEPT;
+ }
+ }
+ else
+ {
+ /* This is an exception to the rule, for grey listing, we allow for
+ * sending back a tempreject on SA scores that aren't considered as
+ * spam (greylisting is now done directly in spamassassin though */
+ if (spamvalue >= SAtemprejectthreshold)
+ {
+ dotempreject:
+
+ /* By default, we'll only save temp bounces by message ID so
+ * that when the same message is submitted several times, we
+ * overwrite the same file on disk and not create a brand new
+ * one every single time */
+ if (SAtemprejectoverwrite)
+ {
+ ret=savemail(fd, fdstart, SAtemprejectsave, "SAtemprejectsave", safemesgid, SAmaxarchivebody, SAtemprejectSavCond);
+ CHECKERR(ret,where,line);
+ }
+ else
+ {
+ ret=savemail(fd, fdstart, SAtemprejectsave, "SAtemprejectsave", (char *)mesgfn, SAmaxarchivebody, SAtemprejectSavCond);
+ CHECKERR(ret,where,line);
+ }
+
+ spamstatus=string_sprintf("%s trigger=%.1f", spamstatus, SAtemprejectthreshold);
+ log_write(0, LOG_MAIN | LOG_REJECT, "SA: Action: temporarily rejected message: %s (scanned in %d/%d secs | Message-Id: %s). %s", spamstatus, scantime, fulltime, safemesgid, mailinfo);
+ *return_text=string_sprintf(SAmsgtemprej, spamstatus);
+ return LOCAL_SCAN_TEMPREJECT_NOLOGHDR;
+ }
+ else
+ {
+ ret=savemail(fd, fdstart, SAnotspamsave, "SAnotspamsave", (char *)mesgfn, SAmaxarchivebody, SAnotspamSavCond);
+ CHECKERR(ret,where,line);
+ log_write(0, LOG_MAIN, "SA: Action: scanned but message isn't spam: %s (scanned in %d/%d secs | Message-Id: %s). %s", spamstatus, scantime, fulltime, safemesgid, mailinfo);
+ return LOCAL_SCAN_ACCEPT;
+ }
+ }
+
+
+
+ errexit:
+ if (SAtemprejectonerror)
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "SA: PANIC: Unexpected error on %s, file "__FILE__", line %d: %s", where, line-1, strerror(errno));
+ }
+ else
+ {
+ log_write(0, LOG_MAIN, "SA: PANIC: Unexpected error on %s (but message was accepted), file "__FILE__", line %d: %s", where, line-1, strerror(errno));
+ }
+
+ header_add(' ', "X-SA-Exim-Scanned: No (on %s); Exit with error (see exim mainlog)\n", primary_hostname);
+
+ ret=savemail(fd, fdstart, SAerrorsave, "SAerrorsave", (char *)mesgfn, SAerrmaxarchivebody, SAerrorSavCond);
+ if (ret < 0)
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "SA: PANIC: Error in error handler while trying to save mail to %s, file "__FILE__", line %d: %s", string_sprintf("%s/%s", SAerrorsave, mesgfn), __LINE__ - 3, strerror(errno));
+ }
+
+ if (SAtemprejectonerror)
+ {
+ *return_text=SAmsgerror;
+ return LOCAL_SCAN_TEMPREJECT_NOLOGHDR;
+ }
+ else
+ {
+ return LOCAL_SCAN_ACCEPT;
+ }
+
+
+ panicexit:
+ if (SAtemprejectonerror)
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "SA: PANIC: %s", panicerror);
+ }
+ else
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "SA: PANIC: %s (but message was accepted)", panicerror);
+ }
+
+ header_add(' ', "X-SA-Exim-Scanned: No (on %s); Panic (see exim mainlog)\n", primary_hostname);
+
+ ret=savemail(fd, fdstart, SAerrorsave, "SAerrorsave", (char *)mesgfn, SAerrmaxarchivebody, SAerrorSavCond);
+ if (ret < 0)
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC , "SA: PANIC: Error in error handler while trying to save mail to %s, file "__FILE__", line %d: %s", string_sprintf("%s/%s", SAerrorsave, mesgfn), __LINE__ - 3, strerror(errno));
+ }
+
+ if (SAtemprejectonerror)
+ {
+ *return_text=SAmsgerror;
+ return LOCAL_SCAN_TEMPREJECT_NOLOGHDR;
+ }
+ else
+ {
+ return LOCAL_SCAN_ACCEPT;
+ }
+}
Index: 4.2.1-12/sa-exim.conf
===================================================================
--- 4.2.1-12/sa-exim.conf (nonexistent)
+++ 4.2.1-12/sa-exim.conf (revision 61)
@@ -0,0 +1,376 @@
+# Options for spamassassin running in exim's local_scan (SA Exim)
+# By Marc MERLIN <marc_soft@merlins.org> - Initial version: April 2002
+# Sander Smeenk <ssmeenk@freshdot.net> - Improvements: March 2004
+#
+# Sample file version 1.16 for SA-Exim 4.1 - 2005/01/10
+#
+# The parse routine is minimalistic. It expects "option: value" (exactly
+# one space after the colon, and none before). You should put long lines
+# on one line. The parser isn't capable of parsing multiline values.
+#
+# SA threshold values are parsed as floats and other numerical options
+# are ints. String options have to be set. To unset them, comment out the
+# variable, don't set it to nothing.
+#
+# READ THIS:
+# ---------
+# Watch your logs, you will get errors and your messages will get
+# temporarily bounced if expansions fail. Watch your logs!
+#
+# If you are afraid that spammers might use a header that is used here
+# as a default, have exim set it to another value than 'Yes' and check
+# here for that other value.
+#
+# For every expansion, anything that doesn't expand to "" or "0"
+# (without quotes) will be considered true. If you set the string to 1,
+# it will be true without going through exim's condition evaluator (and
+# if you leave it unset, it will default to 0)
+#
+# You should not put double quotes around expressions!
+# --- snip ---
+
+# Enable basic verbose output by default. Watch your logs!
+SAEximDebug: 1
+
+
+# Default path is /usr/bin/spamc, but you can change it here
+SAspamcpath: /usr/bin/spamc
+
+# Which characters are retained from a Message-Id header (for safety, we
+# remove characters that might cause problems with shell parsing)
+# Change the default at your own risk (you also have to change this in
+# the SA greylisting patch if you use that)
+#SAsafemesgidchars: !#%( )*+,-.0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~
+
+# If SAspamcSockPath is set spamc uses socket to connect to spamd,
+# use --socketpath pathname as argument to spamd (new in SA 2.60).
+# Leave it unset if you want spamc to connect(AF_INET) to spamd at
+# 127.0.0.1 (this is the default shown in the options below), but if
+# you set it, it will override the two TCP connect options below
+#SAspamcSockPath: /var/run/spamd.sock
+
+# SAspamcHost / SAspamcPort: TCP socket where your spamd is listening
+# Shown below are the defaults:
+SAspamcHost: 127.0.0.1
+SAspamcPort: 783
+
+# SAspamcUser: The username passed to spamc. Some tricks are needed to
+# decide on one user when there are many recipients. This string is of
+# course expanded. If unset or empty, spamc will use the user Exim
+# runs as. We suggest that you decide what username to use in the ACLs
+# and set an ACL variable.
+#SAspamcUser: $acl_m2
+
+# Exim configuration string to run before running SA against the message
+# This decides whether SA gets run against the message or not. This
+# default will not reject messages if the message had SA headers but
+# they weren't added by us.
+SAEximRunCond: ${if and {{def:sender_host_address} {!eq {$sender_host_address}{127.0.0.1}} {!eq {$sender_host_address}{::1}}}}
+# If you want more detailed control over when to run SA, it's recommended
+# that you set an ACL variable indicating this from the acl section of
+# your Exim configuration file. The current maintainer sets acl_m0 to
+# "noscan" if the sending host is localhost or has authenticated.
+#SAEximRunCond: ${if !eq{$acl_m0}{noscan}}
+# (This means exactly the same as ${if !eq{$acl_m0}{noscan} {true}{}},
+# where the empty string is considered false.)
+
+#----------------------------------------------------------------------
+# Remove or comment out the following line to enable sa-exim
+SAEximRunCond: 0
+#----------------------------------------------------------------------
+
+# If and only if SAEximRunCond was true, and we did run SA, this
+# expression decides whether we actually consider acting upon SAdevnull,
+# SApermreject, and SAtempreject if you have them set.
+#
+# Use this to tag messages that you shouldn't reject (messages sent to
+# abuse or postmaster for instance).
+#
+# As an example, set acl_m0 to "canreject" if a recipient other than
+# postmaster or abuse is encountered (and the sender isn't local). That
+# way, spammers can't circumvent blocking by sending to postmaster and
+# 99 other recipients. (If acl_m0 is taken, you'll of course have to use
+# a different variable.
+#SAEximRejCond: ${if eq{$acl_m0}{canreject}}
+
+
+# How much of the body we feed to spamassassin (in bytes)
+# Default is 250KB
+SAmaxbody: 256000
+
+# Do you want to feed SAmaxbody's worth of the message body if it is too big?
+# Either, you skip messages that are too big and not scan them, or you can
+# truncate the body and feed that to SA.
+# Note that SA will sometimes raise the spam score if it can't parse
+# the message correctly (since the end is missing, decoding will fail)
+# Default is 0: do not scan messages that are too big
+# (note that this is parsed as a condition)
+SATruncBodyCond: 0
+
+# If you want SA to report_safe you need sa-exim to rewrite the body of
+# the message since SA encapsulates the spam as a mime attachment.
+# You probably want SATruncBodyCond to be 0 or else you'll end up with a
+# partial message if it's larger than SAmaxbody and it's spam
+#
+# Also note that if you enable this option, any saved message will be saved
+# after the body has been modified by SA.
+# (this is not a condition as SA's report_safe is not conditional)
+SARewriteBody: 0
+
+# Prepend saved messages with an fake From-header to make the file look like a
+# valid mbox file
+SAPrependArchiveWithFrom: 1
+
+# If you are archiving messages that are rejected, how much do you want
+# to archive? Default is 20MB.
+SAmaxarchivebody: 20971520
+
+# On errors, if you are saving messages, you probably want the entire message
+# Default size saved (if you are saving errors) is 1GB
+SAerrmaxarchivebody: 1073741824
+
+# You can have SA-Exim add a X-SA-Exim-Rcpt-To header, which will list all
+# the recipients for the Email, unless the list gets bigger than
+# SAmaxrcptlistlength bytes.
+# The default value of 0 disables the header for privacy reasons (the header
+# exposes Bcced recipients)
+# Any value bigger than 8000 will be ignored because there is a limit on the
+# size of headers that you can have and exim's string_sprintf
+# Note that if you are planning to use greylisting, you should set this
+# value to 8000 since SA's greylisting code needs the recipients.
+SAmaxrcptlistlength: 0
+
+# Add X-SA-Exim-Rcpt-To and X-SA-Exim-Mail-From headers before SA scans
+# the message.
+# If this option is enabled, SARewiteBody is true, and safe_mode is
+# enabled in SA, you end up with the X-SA-Exim-Rcpt-To/X-SA-Exim-Mail-From in
+# the attatched message as well without the ability to remove them later in an
+# exim transport (think privacy).
+# In real life this is usually not a problem because the message is spam anyway,
+# and if you turn this off, you lose the option to use those headers to score
+# the message with SA.
+SAaddSAEheaderBeforeSA: 1
+
+# How many seconds you want to allow spamc to run. Exim 4.04 and better will
+# kill us after a default of 5 minutes. This however is not great, because the
+# mail gets temporarily rejected
+# You should set this and have SA Exim handle the timeout itself and accept the
+# message if spamc takes too long (instead of timing out)
+# A value of 0 means no timeout, and we run until exim stops us.
+# I know of at least one mail server (nanog's merit.edu) that will not
+# wait a full 5mn (which causes tempreject and resends), so the default is 4mn
+#SAtimeout: 240
+
+# Do you want to save mails that were accepted because spamc timed out?
+# Specify a directory to enable the feature.
+# SA-Exim will try to create the directory if it has the permissions to do so,
+# check your maillog for failures (or create the directory yourself and make it
+# writeable by exim)
+SAtimeoutsave: /var/spool/exim/SAtimeoutsave
+
+# You can optionally save or not save messages that matched the above rule
+SAtimeoutSavCond: 1
+
+
+# You should really create this directory for local_scan to save messages that
+# created an error. If you don't want this, comment out this variable
+# Make sure all these directories are owned by the exim user
+# SA-Exim will try to create the directory if it has the permissions to do
+# so, check your maillog for failures (or create the directory yourself and
+# make it writeable by exim)
+SAerrorsave: /var/spool/exim/SAerrorsave
+
+# You can optionally save or not save messages that matched the above rule
+# You should not put double quotes around the expression
+SAerrorSavCond: 1
+
+# If you set to 1, SA will temporarily reject messages that generated an error
+# while they were processed (they'll still be saved if SAerrorsave is set).
+# Otherwise (0 = false), the messages are just accepted, which seems like a
+# more sensible default
+SAtemprejectonerror: 0
+
+
+###############################################################################
+# NOTE: Spamd needs to tell sa-exim that the message SA-Exim gave spamd
+# is spam before sa-exim will consider the SA tresholds.
+# In other words, you cannot reject mails on SA scores if you set that
+# threshold to a lower threshold than SA's required_hits value.
+# The one exception to this rule is SAtempreject (in order to let you
+# temporarily reject mail when you are doing greylisting, see
+# README.greylisting in the documentation for details)
+###############################################################################
+
+# SA score when you start stalling the sender by sending many continuation
+# lines for up to SAteergrubetime
+# This is now a string (without quotes) that gets evaluated at runtime by exim
+# but you can still assign a simple float value to it
+# Note that this is an obvious abuse of SMTP, but eh, they started it :-)
+# Of course, this means that each incoming spam with the right score threshold
+# will keep an exim process busy on your machine. Make sure you can afford it.
+# Default value is 2^20, which should disable the behavior
+
+# Please, don't teergrube people who relay for you or your own MXes :-)
+# This option is left behind for backward compatibility, but you can now
+# get the same result by putting a condition string in SAteergrube
+# The trick is to list your score if the condition succeeds, and a really
+# high score otherwise.
+#SAteergrube: ${if and { {!eq {$sender_host_address}{127.0.0.1}} {!eq {$sender_host_address}{127.0.0.2}} } {25}{1048576}}
+
+# SAteergrubecond is deprecated (replaced by SAteergrube)
+# You used to be say whether you would apply the teergrubing score with this
+# condition, but now that scores are conditions, it is obsolete
+#SAteergrubecond: ${if and { {!eq {$sender_host_address}{127.0.0.1}} {!eq {$sender_host_address}{127.0.0.2}} } {1}{0}}
+
+# How long do you want to stall the sender (in seconds)
+# If you set the value too high, you might get too many exim processes running
+# and run out of process slots
+# Remember, don't come crying if playing with this "feature" causes your mail
+# server to catch fire :-)
+SAteergrubetime: 900
+
+# You can optionally save or not save messages that matched the above rule
+SAteergrubeSavCond: 1
+
+# Do you want to save mails that you stalled for later analysis?
+# Specify a directory to enable the feature.
+# SA-Exim will try to create the directory if it has the permissions to do so,
+# check your maillog for failures (or create the directory yourself and make it
+# writeable by exim)
+SAteergrubesave: /var/spool/exim/SAteergrube
+
+# When you stall the sender, you will probably get the mail again.
+# By default, we'll only save messages by message ID so that we don't save
+# multiple copies every time the sender tries again.
+# Of course, this means someone could fake someone else's message ID to
+# overwrite the saved copy of another spam. Such is life :-)
+SAteergrubeoverwrite: 1
+
+
+
+# If you reach this score, the mail is accepted and tossed (/dev/nulled).
+# The default value is 2^20 which should ensure this never happens.
+# This is now a string (without quotes) that gets evaluated at runtime by exim
+# but you can still assign a simple float value to it
+# You should be really sure that the message is spam because the sender will
+# get no notification
+#SAdevnull: 20.0
+
+# You can optionally save or not save messages that matched the above rule
+SAdevnullSavCond: 1
+
+# Do you want to save mails that are tossed?
+# Specify a directory to enable the feature.
+# This is just in case you do want to keep a copy of the alledge spams somewhere
+# Messages are saved by unixdate_Message-Id or just unix date if there is no
+# Message-Id.
+# SA-Exim will try to create the directory if it has the permissions to do so,
+# check your maillog for failures (or create the directory yourself and make it
+# writeable by exim)
+SAdevnullsave: /var/spool/exim/SAdevnull
+
+
+
+# SA score when you start rejecting Emails (this is better than the above as
+# it can notify the sender in case you reject non-spam by mistake)
+# This is now a string (without quotes) that gets evaluated at runtime by exim
+# but you can still assign a simple float value to it
+# Default value is 2^20, which should disable the behavior if you comment out
+# the line below
+SApermreject: 12.0
+
+# You can optionally save or not save messages that matched the above rule
+SApermrejectSavCond: 1
+
+# Do you want to save mails that are rejected?
+# Specify a directory to enable the feature.
+# SA-Exim will try to create the directory if it has the permissions to do so,
+# check your maillog for failures (or create the directory yourself and make it
+# writeable by exim)
+SApermrejectsave: /var/spool/exim/SApermreject
+
+
+
+# SA score when you start returning a temporary reject.
+# There are few reasons to use this, except if you're reading your tempreject
+# save folder (see below) and ajusting scores on the fly, or if you are using
+# greylisting
+# This is now a string (without quotes) that gets evaluated at runtime by exim
+# but you can still assign a simple float value to it
+# Default value is 2^20, which should disable the behavior
+#SAtempreject: 9.0
+
+# You can optionally save or not save messages that matched the above rule
+SAtemprejectSavCond: 1
+
+# Do you want to save mails that are temporarily rejected?
+# Specify a directory to enable the feature.
+# You could use this to analyse what SA is bouncing and adding an allow rule
+# to accept the mail next time it is sent back to you
+# SA-Exim will try to create the directory if it has the permissions to do so,
+# check your maillog for failures (or create the directory yourself and make it
+# writeable by exim)
+SAtemprejectsave: /var/spool/exim/SAtempreject
+
+# When you send back a temp reject code, you will get the mail again.
+# By default, we'll only save messages by message ID so that we don't save
+# multiple copies every time the sender tries again.
+# Of course, this means someone could fake someone else's message ID to
+# overwrite the saved copy of another spam. Such is life :-)
+SAtemprejectoverwrite: 1
+
+# See README.greylisting in the documentation for the following options
+# This is the string that SpamAssassin adds if the message is whitelisted
+# We use this to optionally increase the score needed for a tempreject
+# (in order to let a message through when it would otherwise have been
+# temprejected)
+# Default value is "GREYLIST_ISWHITE" (as used in the patch provided by SA-Exim)
+SAgreylistiswhitestr: GREYLIST_ISWHITE
+
+# By how much do we temporarly raise tempreject to allow a mail in when it
+# would otherwise have been temp rejected (because SA flagged it was whitelisted
+# by the greylisting code provided as a patch to SA in the SA-Exim distro)
+# Note that greylisting will not work in until you patch SA with the greylist
+# function
+# Note that you most likely want
+# SAtempreject + SAgreylistraisetempreject <= SApermreject
+# Default value is 3.0 but you'd probably to lower the tempreject score and
+# increase this one (see README.greylisting)
+SAgreylistraisetempreject: 3.0
+
+
+# Do you want to save mails that are flagged as spam by SA, but not rejected by
+# any of the above thresholds? Specify a directory to enable the feature.
+# That's one way to track mails thare are going through even though they were
+# flagged by SA (note that you could also save them in exim's system_filter,
+# although copies saved here happen before exim makes modification to the
+# message like rewriting)
+# SA-Exim will try to create the directory if it has the permissions to do so,
+# check your maillog for failures (or create the directory yourself and make it
+# writeable by exim)
+SAspamacceptsave: /var/spool/exim/SAspamaccept
+
+# You can control which messages you want saved if you only want a subset
+SAspamacceptSavCond: 0
+
+
+# Do you want to save mails that are not flagged as spam by SA
+# Specify a directory to enable the feature.
+# This is only here for completeness, if you want to save all messages not
+# flagged as spam by SA (you could also do this in system_filter)
+# SA-Exim will try to create the directory if it has the permissions to do so,
+# check your maillog for failures (or create the directory yourself and make it
+# writeable by exim)
+SAnotspamsave: /var/spool/exim/SAnotspam
+
+# You can control which messages you want saved if you only want a subset
+SAnotspamSavCond: 0
+
+# All the following strings can take one '%s' which will be replaced by
+# spamstatus: "SA score, trigger score"
+SAmsgteergrubewait: Wait for more output
+SAmsgteergruberej: Please try again later
+SAmsgpermrej: Rejected
+SAmsgtemprej: Please try again later
+# This string is a static string, do not include "%s"
+SAmsgerror: Temporary local error while processing message, please contact postmaster.
Index: 4.2.1-12/greylistclean.cron
===================================================================
--- 4.2.1-12/greylistclean.cron (nonexistent)
+++ 4.2.1-12/greylistclean.cron (revision 61)
@@ -0,0 +1,3 @@
+# If you don't run spamd as nobody (you should), change the user below
+# be smart and don't run this as root, it doesn't need those perms
+33 * * * * nobody [ -x /usr/share/sa-exim/greylistclean ] && /usr/share/sa-exim/greylistclean
Index: 4.2.1-12/README
===================================================================
--- 4.2.1-12/README (nonexistent)
+++ 4.2.1-12/README (revision 61)
@@ -0,0 +1,355 @@
+COPYRIGHTS
+----------
+SA-Exim was written by Marc MERLIN <marc_soft@merlins.org>
+You can find the latest version here:
+ http://sa-exim.sf.net/
+or here:
+ http://marc.merlins.org/linux/exim/sa.html
+
+greylisting was written by and is copyright Mark Lawrence <nomad@null.net>
+
+
+INSTALL
+-------
+See the file named INSTALL for installations instructions (either compiled
+in exim, or as a stand-alone shared library)
+
+If you got sa-exim prepackaged (like on debian), you have to make sure that
+your exim supports a dynamically loadable local_scan (which is true on debian
+and probably on other distros too if they shipped sa-exim as a package), and
+that your exim4.conf file contains the following:
+local_scan_path = /usr/lib/exim4/local_scan/sa-exim.so
+If you are using the split configuration file on debian with the sa-exim deb
+package, you'll be fine. If you're using the monolithic file, you are on your
+own until/unless the sa-exim packages try to do an in place edit (i.e. you have
+to add the above configuration line yourself)
+
+
+UPGRADING
+---------
+Deleting greylisting tuplets pre-4.2.1:
+If you are installing this package yourself, and ever installed the old
+greylistclean.cron which contained the complicated shell commands to clean
+old tuplets, you should stop using those commands and upgrade to greylistclean.
+Upgrading Greylisting.pm should also create safer tuplets without whitespace,
+but it's better to get rid of the old shell cron jobs either way
+
+
+PRIVACY WARNING
+---------------
+SA-Exim can add a header with the list of recipients in an Email (including
+Bcced folks).
+X-SA-Exim-Rcpt-To is used to allow you to see who a spam went to easily (i.e.
+without scanning the exim logs), and to write SpamAssassin rules on the envelope
+To (like adding a score if there were too many recipients or a recipient who you
+know only receives spam)
+X-SA-Exim-Rcpt-To is not added anymore by default, you need to enable it by
+setting SAmaxrcptlistlength to a value up to 8000, but if you do add it,
+you should consider removing it in exim's system_filter or in a transport.
+If SARewriteBody is true you should also consider setting
+SAaddSAEheaderBeforeSA to false (see the config) as all the recipients
+will be visible in the attached spam, note that this disables the
+ability to write SpamAssassin rules based on X-SA-Exim-Rcpt-From/To.
+In real life, who a spam was sent to isn't really a problem, but it could be if
+a private message is mis-categorized as spam
+Note however that if you disable X-SA-Exim-Rcpt-To by setting
+SAmaxrcptlistlength to 0, you will not be able to use greylisting, which
+depends on this header (however you'd still be welcome to remove the header in
+system_filter)
+
+
+CONFIGURATION
+-------------
+You should read sa-exim.conf, all the options there should be well
+documented.
+
+Note that the code will not act on any mail before it is flagged as SPAM by SA.
+
+Having SA flag the mail however doesn't mean the code rejects it or throws
+the alleged spam away, you control what you want to do depending on the score.
+The only restriction is that things happen in this order (for increasing SA
+scores)
+
+ - Save in SAnotspamsave if enabled
+ - Save in SAspamacceptsave if enabled
+ - Temporarily reject and optionally save if enabled
+ - Permanently reject and optionally save if enabled
+ - Accept, drop the mail, and optionally save if enabled
+ - Teergrube (i.e. stall) the sender to waste his resources (and yours)
+
+Note that you cannot set a teergrube threshold of 12, and a permreject
+threshold of 20 (not that it would make much sense anyway).
+Threshold scores should decrease as you apply the highest to the lowest penalty
+(i.e. the rules are run in this order: teergrube, devnull, permreject,
+tempreject)
+
+Now, as of SA-Exim 4.2, things get slightly more complicated as scores are
+actually full exim conditions, and therefore you could have:
+SAteergrube: ${if and { {!eq {$sender_host_address}{127.0.0.1}} {!eq {$sender_host_address}{127.0.0.2}} } {25}{1048576}}
+This means that if your condition succeeds, the teergrube score is set to 25,
+and if the condition fails, the teergrube score is set to 2^20, which for all
+intents and purposes, disables teergrubing.
+Regardless of what your scores end up being after the conditions are evaluated,
+sa-exim still tests them in this order: teergrube, devnull, permreject,
+tempreject)
+
+
+
+
+CONFIGURING SPAMASSASSIN
+------------------------
+A good example of spamassassin configuration would be:
+
+ report_safe 0
+ use_terse_report 1 # for SA < 3.x
+
+This will put a non-verbose SPAM-report in the headers, but leave the
+message itself intact for easy analyzing and for easy feeding to
+sa-learn when mis-flagged as spam or ham. The only way to see the
+message is spam, is by looking in the headers.
+
+If you have an older version of SpamAssassin (<= 2.50), you'd probably
+want to add 'report_header 1' to that list. But this is default and
+un-needed in new versions of SA)
+
+If you set 'report_safe' to a true value, you might also want to set
+use_terse_report to a false value, in case you'll get the long header
+which might be friendlier to your users.
+
+For SA before 3.x, add 'always_add_report 1' to always have a spamcheck report
+put in the message. This might be useful to test rules.
+For SA 3.x onward, the syntax you'd want, is:
+add_header all Report _REPORT_
+
+Since SA is usually configured to pass messages on that are beyond the SA
+spam threshold, it can make sense to rewrite the subject line.
+To achieve this, you would use this for SA 2.x:
+ rewrite_subject 1
+ subject_tag SPAM: _HITS_:
+
+For SA 3.x, the syntax is:
+ rewrite_header Subject SPAM: _HITS_:
+
+
+If you are using SA 2.50 or better, by default, you should probably set:
+ report_safe 0
+
+Now, if you are willing to take a small speed and I/O hit, you can have
+sa-exim read the body back from SA, and replace the original mail with
+the new body.
+
+You would use this if you want to set SA's report_safe to 1 or 2 (in
+which case you also have to set SARewriteBody: 1 in SA-Exim's config)
+
+Note that if you do so, unfortunately archived messages will have the
+body modified by SA. This is not very trivial to fix, so if you archive
+anything, you may not want to use SARewriteBody
+
+
+Important:
+You want to run spamd as such:
+/usr/sbin/spamd -d -u nobody -H /var/spool/spamassassin/
+
+It may not work if you run spamd with -c (debian default),
+(you shouldn't run spamassassin as root for this purpose anyway (there
+is no reason to, so why take the risk)
+
+You can edit this in /etc/default/spamassassin (debian) and probably
+/etc/sysconfig/spamassassin (redhat)
+
+With SA 3.x is better, the updated syntax would look like this:
+/usr/sbin/spamd --max-children 50 --daemonize --username=nobody --nouser-config --helper-home-dir=/var/spool/spamassassin/
+
+
+
+CONFIGURING EXIM4.CONF
+----------------------
+This code works without anything in the exim conf, but you probably want to use
+some knobs to disable scanning for some users (like setting X-SA-Do-Not-Rej
+or X-SA-Do-Not-Run in the rcpt ACL and removing those headers in the right
+places)
+
+See http://marc.merlins.org/linux/exim/#conf and more specifically
+http://marc.merlins.org/linux/exim/exim4-conf/exim4.conf
+
+Note that obviously if you set those headers, spammers can set them too, so
+if you are concerned about this, you can either change the header name, or set
+it to something else than 'Yes' and check for that value in sa-exim.conf
+(or as a 3rd option, you can use exim ACL variables to pass values to SA-Exim
+without generating headers; see the section contributed by Chirik, lower in
+this file)
+
+
+
+EXIM4 INTEGRATION / NOT SCANNING YOUR OWN MAILS
+-----------------------------------------------
+For a very complete exim4 config, including settings for SA, you should
+look at sa-exim.conf and play with:
+
+SAEximRunCond: ${if and{ \
+ {def:sender_host_address} \
+ {!eq {$sender_host_address}{127.0.0.1}} \
+ {!eq {$h_X-SA-Do-Not-Run:}{Yes}} \
+ } \
+ {1}{0} \
+ }
+
+PLEASE NOTE: This conditional statement must be on one line. SA-Exim's
+configfile parser does not support \-lineconitunation!!
+
+You may also want to look at my exim4.conf config if you haven't done so yet:
+http://marc.merlins.org/linux/exim/#conf
+
+The check_rcpt ACL has:
+ warn message = X-SA-Do-Not-Rej: Yes
+ local_parts = +nosarej:postmaster:abuse
+
+ warn message = X-SA-Do-Not-Run: Yes
+ hosts = +relay_from_hosts
+
+ warn message = X-SA-Do-Not-Run: Yes
+ authenticated = *
+
+Then, you'll want to strip SA headers for messages that aren't local
+This means you should strip them at least in the remote_smtp transport
+with this configuration snippet:
+
+ # This is generally set on messages originating from local users and it tells
+ # SA-Exim not to scan the message or that the message was scanned.
+ # Let's remove these headers if the message is sent remotely
+ headers_remove = "X-SA-Do-Not-Run:X-SA-Exim-Scanned:X-SA-Exim-Mail-From:X-SA-Exim-Rcpt-To:X-SA-Exim-Connect-IP"
+
+
+You can also use another option, which can't be spoofed by a spammer, but
+won't show you why a mail didn't get scanned if it was sent to multiple
+people (which is why I personally prefer the above, even if it's spoofable)
+
+Contributed by Chirik <chirik@castlefur.com>:
+----------------------------------------------------------------------------
+I have the following:
+
+SAEximRunCond: ${if !eq {$acl_m0}{do-not-scan} {1} {0}}
+SAEximRejCond: ${if !eq {$acl_m0}{do-not-reject} {1} {0}}
+
+Then, in my recipient ACL, I have:
+
+ ##### Checks for postmaster or abuse - we'll scan, still, but not reject
+ ##### Don't reject for certain users
+ warn local_parts = postmaster : abuse
+ set acl_m0 = do-not-reject
+
+ ##### Check for situations we don't even scan (local mail)
+ ##### Don't scan if hosts we relay for (probably dumb MUAs),
+ warn hosts = +relay_from_hosts:127.0.0.1/8
+ set acl_m0 = do-not-scan
+
+ ##### Don't scan non-smtp connections (empty host list)
+ warn hosts = :
+ set acl_m0 = do-not-scan
+
+ ##### Don't scan if authenticated
+ warn authenticated = *
+ set acl_m0 = do-not-scan
+----------------------------------------------------------------------------
+
+
+
+TEERGRUBING: SAteergrube
+------------------------
+The idea is for mail that you know for sure is spam (I use a threshold of 25),
+you can stall the spammer for as long as possible by sending a continuation
+line every 10 seconds:
+451- wait for more output
+451- wait for more output
+451- wait for more output
+(...)
+
+You can go there for details:
+http://www.iks-jena.de/mitarb/lutz/usenet/teergrube.en.html
+
+What should you know?
+1) This is obviously going to use up some of your resources
+2) You should not teergrube SMTP servers that relay mail for you, be
+ courteous (set a condition in SAteergrube like in the example
+ provided). Besides they are real mail relays, so they will diligently
+ try to send you the spam over and over for days)
+ (note that you should probably not teergrube mailling lists you subscribed
+ to either, or you risk getting unsubscribed)
+ See a sample in sa-exim.conf for example syntax.
+3) Because of limitations in the current exim code, teergrubing will not work
+ over TLS.
+ This shouldn't be a problem since real spammers should not be using TLS,
+ and you shouldn't teergrube relays that do TLS with you.
+ If you do teergrube a TLS connection, it will break the connection and you
+ will see this in your logs:
+18640m-0000Vb-00 SSL_write error 5
+TLS error (SSL_write): error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
+ This is not ideal, but in real life, that's ok.
+
+
+
+GREYLISTING
+-----------
+See README.greylisting
+
+
+
+READING ARCHIVED SPAMS
+----------------------
+Spams are optionally saved in individual files in a 'new' subdirectory
+of some place like /var/spool/sa-exim/SAteergrube.
+
+There are two ways to read them:
+1) cat new/* > /tmp/mailbox, and use the resulting file as a standard
+ mbox file with any mail client (if SAPrependArchiveWithFrom is true)
+2) Use a maildir capable mail client, like mutt, and run something like
+ 'mutt -f /var/spool/sa-exim/SAteergrube'. This will read the messages in
+ place, since what sa-exim creates looks like a valid Maildir spool.
+
+If you configured SA-Exim to set X-SA-Exim-Rcpt-To, you can even resend
+archived refused messages to the users they were meant for
+
+Note that sa-exim runs with the same uid/gid than the exim daemon (something
+like mail, exim, or Debian-Exim), so /var/spool/sa-exim/SAteergrube must exist
+and be writeable by exim.
+SA-Exim will then create (sub-)directories with the permissions 0770 as
+needed (those permissions aren't a configuration option, but you can change
+them after the fact or pre-create the directories with the permissions of your
+choice)
+Files are created with 0664 permissions so that anyone who has directory access
+can read (and maybe write) the files.
+If you chgrp the parent 'new' directory to a group of your choice, and give it
+permissions 2770 or 2775, the files will be created with that group instead of
+the default exim group
+
+
+
+LOG AND SMTP OUTPUT
+-------------------
+As of SA-Exim 3.0, SMTP output does not contain the spam score anymore,
+and you can change the messages or re-add the score by changing the
+runtime SAmsg* variables
+
+All SA-Exim log now looks like this:
+- "SA: PANIC: " -> severe errors
+- "SA: Warning: " -> config file parsing errors
+- "SA: Notice: " -> misc info on what SA-Exim is doing or not doing
+- "SA: Action: " -> what action SA-Exim took on a mail after scanning
+- "SA: Debug[X]: " -> misc debug info if enabled
+
+Marin Balvers has written a nice log parser here:
+http://nossie.addicts.nl/projects/sa-exim-stats/
+
+
+
+FAQ
+---
+Why do I get this in my exim logs?
+
+2004-05-15 12:43:57 1BP54T-0002gV-Nu TLS send error on connection from internalmx1.company.tld (internalmx.company.tld) [192.168.1.1]:51552: Error in the push function.
+2004-05-15 12:43:57 TLS recv error on connection from internalmx1.company.tld (internalmx.company.tld)
+[192.168.1.1]:51552: The specified session has been invalidated for some reason.
+
+This is because you are teergrubing a host that is doing TLS. Teergrubing does
+not work with TLS, and people doing TLS with you are probably known relays which
+you should exclude from your teergrube list (SAteergrubecond)
Index: 4.2.1-12/accept.c
===================================================================
--- 4.2.1-12/accept.c (nonexistent)
+++ 4.2.1-12/accept.c (revision 61)
@@ -0,0 +1,45 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) University of Cambridge 1995 - 2002 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+
+#include "local_scan.h"
+
+/*
+ * This is a basic version of local_scan that always accepts the messge.
+ * It is like the template provided by Philip Hazel, except it is
+ * intended to be compiled as a .so and loaded dynamically by the "real"
+ * local_scan.
+ */
+
+int local_scan_version_major(void)
+{
+ return LOCAL_SCAN_ABI_VERSION_MAJOR;
+}
+
+int local_scan_version_minor(void)
+{
+ return LOCAL_SCAN_ABI_VERSION_MINOR;
+}
+
+int local_scan_version( void )
+{
+ return 1;
+}
+
+
+int local_scan(int fd, uschar **return_text)
+{
+ /* Keep pedantic compilers happy */
+ fd = fd;
+ return_text = return_text;
+
+ log_write(0, LOG_MAIN, "Message accepted by dynamically loaded dummy local_scan");
+ return LOCAL_SCAN_ACCEPT;
+}
+
+
+/* End of local_scan.c */
Index: 4.2.1-12/sa.html.template
===================================================================
--- 4.2.1-12/sa.html.template (nonexistent)
+++ 4.2.1-12/sa.html.template (revision 61)
@@ -0,0 +1,221 @@
+<html>
+<head>
+<title>Exim SpamAssassin at SMTP time</title>
+</head>
+
+<body>
+
+<h1 ALIGN="CENTER">Exim SpamAssassin at SMTP time</h1>
+
+<h3>What's that?</h3>
+<pre>
+mail from: merlin@gandalf
+250 OK
+rcpt to: merlin@gandalf
+250 Accepted
+data
+354 Enter message, ending with "." on a line by itself
+From: merlin@gandalf
+To: merlin@gandalf
+Subject: $$$ Make Money Fast $$$ !!!
+
+viagra 100% GARANTEE AMAZING FULL REFUND
+This is not spam
+.
+550 Rejected
+</pre>
+(logs would show something like this:
+<tt>2004-03-10 08:27:18 1B16Y8-0001UP-4R SA: Action: permanently rejected message: hits=14.8 required=7.0 trigger=11.0 ( scanned in 2/2 secs | Message-Id: CCQPVENACPQBFLTRLICXWQVEK@gandalf). From <merlin@gandalf> (host=gandalf [127.0.0.1]) for merlin@gandalf</tt>)
+
+
+<P>
+An example of teergrube would return this instead
+<pre>
+data
+354 Enter message, ending with "." on a line by itself
+(...)
+body SEE_FOR_YOURSELF /See (?:for|it) yourself\b/i
+describe SEE_FOR_YOURSELF See for yourself
+
+body ORDER_NOW /\border (?:now|soon|fast|quickly|while)\b/i
+describe ORDER_NOW Encourages you to waste no time in ordering
+
+.
+451- wait for more output
+451- wait for more output
+451- wait for more output
+(... one line every 10 secs, 15 minutes elapse ...)
+450 Please try again later
+</pre>
+
+The idea here is to stall and waste the resources of the remote sender (BTW
+teergrube comes from german, and means tar-pitting, or stopping someone in his
+tracks)
+
+<BR><BR>
+<h3>Why?</h3>
+SpamAssassin can be run inside exim after the mail has been accepted, as shown
+<a href="http://bogmog.sourceforge.net/document_show.php3?doc_id=28">here</a>,
+but if you're not going to use my patch and you just want to run SA as an exim
+transport,
+<a href="http://dman13.dyndns.org/~dman/config_docs/exim-spamassassin/">this</a>
+version is recommended
+<P>
+Now, while this will work, we can do better, hence the reason for my code
+(just to make things clear, you do not want to run both my code, and dman's
+transports. It'd work, but you'd be scanning the message twice)
+<P>
+The reason why I wanted SpamAssassin in local scan is that I don't want to
+accept the damn spam in the first place.
+
+<ul>
+<li>While my code lets you do that, I don't like to send mails to the bit
+ bucket, so you need to bounce them.
+<li>Once you accept the spam, you can't bounce it half the time, or you
+ bounce it to an innocent whose Email was forged as an envelope sender
+ (some spam even forges the bounce address to <em>you</em>)
+<li>If I refuse spam at SMTP time, it will remove the spam addresses from at
+ least a few lists (they gotta clean their lists eventually otherwise they'd
+ spend more time Emailing dead addresses than good ones)
+<li>I have the option of toying with spammers and stall their connections and
+ waste their resources (see the following page for details on
+ <A HREF="http://www.iks-jena.de/mitarb/lutz/usenet/teergrube.en.html">
+ teergrubing</A>
+</ul>
+
+Note that you can also use this code to simply run SA on all your mails (or
+portion thereof as configured with SAEximRunCond) without having to configure SA
+in your exim.conf. In other words, this code can be configured to not reject
+any mails.
+
+<BR><BR>
+<h3>SpamAssassin? What's that?</h3>
+Ah, you need to visit <a href="http://spamassassin.org/">this page</a> first
+then
+
+
+<BR><BR>
+<h3>How does it work, what knobs are there?</h3>
+You need to configure spamassassin to flags mails as spam after a certain
+threshold (7 for instance). After that, this code can be configured to
+
+<ul>
+<li>Pretend to be processing the Email and send continuation lines to the
+ remote server until it gives up (aka
+ <A HREF="http://www.iks-jena.de/mitarb/lutz/usenet/teergrube.en.html">
+ teergrubing</A>)
+<li>Accept but not deliver mail with a high threshold (i.e. devnull the mail)
+<li>Reject mail with a lower threshold
+<li>Temporarily reject mail with a still lower threshold (you can then inspect
+ your logs to decide if you want to tweak SA so that next time the mail
+ is sent, you can receive it)
+<li>In all 5 cases, mail can be optionally saved to disk so that you can
+ inspect all the mails you've rejected or /dev/nulled
+</ul>
+
+You can also (and probably should <img src="/gifs/people/smile.happy.gif" alt=":-)" align=TOP WIDTH=16 HEIGHT=16>) use the new greylisting support for even
+better spam control
+
+
+<P>
+For more details, you should look at the self-documented
+<a href="files/sa-exim.conf">config file</a> and you can see
+<a href="sa-exim.demo.txt">some sample rejects and what you get in the logs</a>
+
+
+<BR><BR>
+<h3><A NAME="greylisting">Greylisting you say?</A></h3>
+While when sa-exim first came out, its strongest point was being one of the
+first programs (if not the first) that let you reject Spam at SMTP time, its
+coolest feature now is adaptive greylisting support<BR>
+In a nutshell, you get the advantages of greylisting without the disadvantages:
+<ul>
+<li>mails with a low spam score are accepted without delay
+<li>mails with an average spam score are greylisted,
+ <b>and only those are delayed</b>
+<li>mails with high spam scores are rejected regardless (no greylisting)
+</ul>
+
+This method is the best combination I've seen out there so far, and
+while I've been talking about it for a while, I don't yet know of other
+programs that implement this method (if you do, please let me know so that
+I can acknowledge them)
+<BR>
+For more details on how this works, check out the <a href="files/sa-exim-cvs/README.greylisting">greylisting README</a>
+
+
+<BR><BR>
+<h3>Ok, where's the code? / Downloads</h3>
+<ul>
+<li>The latest version is here (<a href="files/sa-exim-current/">browsable tree</a> or <a href="files/sa-exim-current.tar.gz">tar.gz</a>). You can also
+get it from <A href="http://sourceforge.net/projects/sa-exim/">sf.net</a><BR>
+<li>The CVS version is here (<a href="files/sa-exim-cvs/">browsable tree</a>)
+and you can also get the CVS tree from
+<A HREF="http://sourceforge.net/cvs/?group_id=56124">sf.net</A>
+<li>The latest config file with documentation is
+<a href="files/sa-exim.conf">here</a>
+<li>Debian packages (source and binary) are <a href="files/debian/">here</a>
+</ul>
+<P>
+
+As explained in the archive, you can either copy <tt>sa-exim.c</tt> over exim's
+<tt>src/local_scan.c</tt> You need to copy local_scan in src in the exim source
+tree and rebuild it, or you can build sa-exim as a loadable module (you need
+to patch exim to support loadable modules though)
+<P>
+You can also browse all my exim files <A HREF="files/">here</A>
+
+<BR><BR>
+<h3>Mailing list</h3>
+You should probably subscribe to this low traffic
+<a href="http://lists.merlins.org/lists/listinfo/sa-exim">mailing list</a> if
+you download the code to keep apprised of bug fixes and enhancements
+
+<BR><BR>
+<h3>Integration with Exim 4</h3>
+This code works without anything in the exim conf, but you probably want to use
+some knobs to disable scanning for some users (like setting
+<tt>X-SA-Do-Not-Rej</tt> or <tt>X-SA-Do-Not-Run</tt> in the rcpt ACL and
+removing those headers in the right places).<BR>
+See <A HREF="http://marc.merlins.org/linux/exim/#conf">my exim4 conf tree</a>
+and more specifically the
+<A HREF="http://marc.merlins.org/linux/exim/exim4-conf/exim4.conf">exim4.conf</A>
+file
+<P>
+You can look at the <A HREF="files/sa-exim-cvs/README">README</A> for more
+integration details.
+
+
+<BR><BR>
+<h3>Changelog/Download</h3>
+
+<Changelog>
+</Changelog>
+
+<P>
+More generally, all the files can also be found <A HREF="files/">here</A>
+<P>
+<A HREF="/perso/contact.html">Feedback is appreciated</A> (but please
+prefer the use of the
+<a href="http://lists.merlins.org/lists/listinfo/sa-exim">sa-exim list</a>)
+
+<BR><BR>
+<h3>Acknowledgements</h3>
+
+<Acknowledgements>
+</Acknowledgements>
+
+
+<P ALIGN="center">
+<img src="/gifs/lines/misc/lampline.gif" alt="" WIDTH=720 HEIGHT=14>
+</P>
+<br>
+<img src="/gifs/misc/wizard.gif" alt="" align="middle" WIDTH=72 HEIGHT=61>
+<img src="/gifs/linux/damn-powered.gif" alt="" align="right" WIDTH=170 HEIGHT=29>
+<IMG SRC="/gifs/icons/msfree.gif" ALT="[ms free site]" ALIGN="right" WIDTH=95 HEIGHT=31>
+<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.php?group_id=56124&amp;type=1" width="88" height="31" border="0" align="right" alt="SourceForge.net Logo"></a>
+<A HREF="/perso/contact.html">Email</A><BR>
+<A HREF="/">Link to Home Page</A>
+<P>
+</body>
+</html>
Index: 4.2.1-12/LICENSE
===================================================================
--- 4.2.1-12/LICENSE (nonexistent)
+++ 4.2.1-12/LICENSE (revision 61)
@@ -0,0 +1 @@
+GPL version 2.0 ('nuff said :-D)
Index: 4.2.1-12/version
===================================================================
--- 4.2.1-12/version (nonexistent)
+++ 4.2.1-12/version (revision 61)
@@ -0,0 +1 @@
+4.2.1
Index: 4.2.1-12/localscan_dlopen_exim_4.20_or_better.patch
===================================================================
--- 4.2.1-12/localscan_dlopen_exim_4.20_or_better.patch (nonexistent)
+++ 4.2.1-12/localscan_dlopen_exim_4.20_or_better.patch (revision 61)
@@ -0,0 +1,268 @@
+The initial version of this patch was originally posted David Woodhouse, and
+dman gets the credit for first integrating it with SA-Exim.
+
+I have since then maintained it by first making a few minor changes, and
+later switching it to a major/minor number scheme to support upgrades in
+the exim API that don't affect backward compatibility (you can rely on
+a feature denoted by the minor number and be compatible with future versions
+of exim until Philip has to break the API and increase the major number)
+
+Marc MERLIN <marc_soft@merlins.org>
+
+diff -urN exim-4.14-0/src/EDITME exim-4.14-1/src/EDITME
+--- exim-4.14-0/src/EDITME Tue Mar 11 04:20:18 2003
++++ exim-4.14-1/src/EDITME Sun Mar 23 15:34:15 2003
+@@ -388,6 +388,20 @@
+
+
+ #------------------------------------------------------------------------------
++# On systems which support dynamic loading of shared libraries, Exim can
++# load a local_scan function specified in its config file instead of having
++# to be recompiled with the desired local_scan function. For a full
++# description of the API to this function, see the Exim specification.
++
++DLOPEN_LOCAL_SCAN=yes
++
++# If you set DLOPEN_LOCAL_SCAN, then you need to include -rdynamic in the
++# linker flags. Without it, the loaded .so won't be able to access any
++# functions from exim.
++
++LFLAGS=-rdynamic -ldl
++
++#------------------------------------------------------------------------------
+ # The default distribution of Exim contains only the plain text form of the
+ # documentation. Other forms are available separately. If you want to install
+ # the documentation in "info" format, first fetch the Texinfo documentation
+diff -urNad 50_localscan_dlopen.tmp/src/config.h.defaults 50_localscan_dlopen/src/config.h.defaults
+--- 50_localscan_dlopen.tmp/src/config.h.defaults Sun Dec 29 11:55:42 2002
++++ 50_localscan_dlopen/src/config.h.defaults Sun Dec 29 11:56:44 2002
+@@ -17,6 +17,8 @@
+ #define AUTH_PLAINTEXT
+ #define AUTH_SPA
+
++#define DLOPEN_LOCAL_SCAN
++
+ #define BIN_DIRECTORY
+
+ #define CONFIGURE_FILE
+diff -urN exim-4.14-0/src/globals.c exim-4.14-1/src/globals.c
+--- exim-4.14-0/src/globals.c Tue Mar 11 04:20:20 2003
++++ exim-4.14-1/src/globals.c Sun Mar 23 15:34:15 2003
+@@ -103,6 +103,9 @@
+ uschar *tls_verify_hosts = NULL;
+ #endif
+
++#ifdef DLOPEN_LOCAL_SCAN
++uschar *local_scan_path = NULL;
++#endif
+
+ /* Input-reading functions for messages, so we can use special ones for
+ incoming TCP/IP. The defaults use stdin. We never need these for any
+diff -urN exim-4.14-0/src/globals.h exim-4.14-1/src/globals.h
+--- exim-4.14-0/src/globals.h Tue Mar 11 04:20:20 2003
++++ exim-4.14-1/src/globals.h Sun Mar 23 15:34:15 2003
+@@ -67,6 +67,9 @@
+ extern uschar *tls_verify_hosts; /* Mandatory client verification */
+ #endif
+
++#ifdef DLOPEN_LOCAL_SCAN
++extern uschar *local_scan_path; /* Path to local_scan() library */
++#endif
+
+ /* Input-reading functions for messages, so we can use special ones for
+ incoming TCP/IP. */
+diff -urN exim-4.14-0/src/local_scan.c exim-4.14-1/src/local_scan.c
+--- exim-4.14-0/src/local_scan.c Tue Mar 11 04:20:20 2003
++++ exim-4.14-1/src/local_scan.c Sun Mar 23 15:34:15 2003
+@@ -5,60 +5,131 @@
+ /* Copyright (c) University of Cambridge 1995 - 2003 */
+ /* See the file NOTICE for conditions of use and distribution. */
+
++#include "exim.h"
+
+-/******************************************************************************
+-This file contains a template local_scan() function that just returns ACCEPT.
+-If you want to implement your own version, you should copy this file to, say
+-Local/local_scan.c, and edit the copy. To use your version instead of the
+-default, you must set
+-
+-LOCAL_SCAN_SOURCE=Local/local_scan.c
+-
+-in your Local/Makefile. This makes it easy to copy your version for use with
+-subsequent Exim releases.
+-
+-For a full description of the API to this function, see the Exim specification.
+-******************************************************************************/
+-
+-
+-/* This is the only Exim header that you should include. The effect of
+-including any other Exim header is not defined, and may change from release to
+-release. Use only the documented interface! */
+-
+-#include "local_scan.h"
+-
+-
+-/* This is a "do-nothing" version of a local_scan() function. The arguments
+-are:
+-
+- fd The file descriptor of the open -D file, which contains the
+- body of the message. The file is open for reading and
+- writing, but modifying it is dangerous and not recommended.
+-
+- return_text A pointer to an unsigned char* variable which you can set in
+- order to return a text string. It is initialized to NULL.
+-
+-The return values of this function are:
+-
+- LOCAL_SCAN_ACCEPT
+- The message is to be accepted. The return_text argument is
+- saved in $local_scan_data.
+-
+- LOCAL_SCAN_REJECT
+- The message is to be rejected. The returned text is used
+- in the rejection message.
+-
+- LOCAL_SCAN_TEMPREJECT
+- This specifies a temporary rejection. The returned text
+- is used in the rejection message.
+-*/
++#ifdef DLOPEN_LOCAL_SCAN
++#include <dlfcn.h>
++static int (*local_scan_fn)(int fd, uschar **return_text) = NULL;
++static int load_local_scan_library(void);
++#endif
+
+ int
+ local_scan(int fd, uschar **return_text)
+ {
+ fd = fd; /* Keep picky compilers happy */
+ return_text = return_text;
+-return LOCAL_SCAN_ACCEPT;
++#ifdef DLOPEN_LOCAL_SCAN
++/* local_scan_path is defined AND not the empty string */
++if (local_scan_path && *local_scan_path)
++ {
++ if (!local_scan_fn)
++ {
++ if (!load_local_scan_library())
++ {
++ char *base_msg , *error_msg , *final_msg ;
++ int final_length = -1 ;
++
++ base_msg=US"Local configuration error - local_scan() library failure\n";
++ error_msg = dlerror() ;
++
++ final_length = strlen(base_msg) + strlen(error_msg) + 1 ;
++ final_msg = (char*)malloc( final_length*sizeof(char) ) ;
++ *final_msg = '\0' ;
++
++ strcat( final_msg , base_msg ) ;
++ strcat( final_msg , error_msg ) ;
++
++ *return_text = final_msg ;
++ return LOCAL_SCAN_TEMPREJECT;
++ }
++ }
++ return local_scan_fn(fd, return_text);
++ }
++else
++#endif
++ return LOCAL_SCAN_ACCEPT;
++}
++
++#ifdef DLOPEN_LOCAL_SCAN
++
++static int load_local_scan_library(void)
++{
++/* No point in keeping local_scan_lib since we'll never dlclose() anyway */
++void *local_scan_lib = NULL;
++int (*local_scan_version_fn)(void);
++int vers_maj;
++int vers_min;
++
++local_scan_lib = dlopen(local_scan_path, RTLD_NOW);
++if (!local_scan_lib)
++ {
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library open failed - "
++ "message temporarily rejected");
++ return FALSE;
++ }
++
++local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_major");
++if (!local_scan_version_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan_version_major() function - message temporarily rejected");
++ return FALSE;
++ }
++
++/* The major number is increased when the ABI is changed in a non
++ backward compatible way. */
++vers_maj = local_scan_version_fn();
++
++local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_minor");
++if (!local_scan_version_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan_version_minor() function - message temporarily rejected");
++ return FALSE;
++ }
++
++/* The minor number is increased each time a new feature is added (in a
++ way that doesn't break backward compatibility) -- Marc */
++vers_min = local_scan_version_fn();
++
++
++if (vers_maj != LOCAL_SCAN_ABI_VERSION_MAJOR)
++ {
++ dlclose(local_scan_lib);
++ local_scan_lib = NULL;
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible major"
++ "version number, you need to recompile your module for this version"
++ "of exim (The module was compiled for version %d.%d and this exim provides"
++ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
++ LOCAL_SCAN_ABI_VERSION_MINOR);
++ return FALSE;
++ }
++else if (vers_min > LOCAL_SCAN_ABI_VERSION_MINOR)
++ {
++ dlclose(local_scan_lib);
++ local_scan_lib = NULL;
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible minor"
++ "version number, you need to recompile your module for this version"
++ "of exim (The module was compiled for version %d.%d and this exim provides"
++ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
++ LOCAL_SCAN_ABI_VERSION_MINOR);
++ return FALSE;
++ }
++
++local_scan_fn = dlsym(local_scan_lib, "local_scan");
++if (!local_scan_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan() function - message temporarily rejected");
++ return FALSE;
++ }
++
++return TRUE;
+ }
++
++#endif /* DLOPEN_LOCAL_SCAN */
+
+ /* End of local_scan.c */
+diff -urN exim-4.14-0/src/readconf.c exim-4.14-1/src/readconf.c
+--- exim-4.14-0/src/readconf.c Tue Mar 11 04:20:22 2003
++++ exim-4.14-1/src/readconf.c Sun Mar 23 15:34:15 2003
+@@ -182,6 +182,9 @@
+ { "local_from_prefix", opt_stringptr, &local_from_prefix },
+ { "local_from_suffix", opt_stringptr, &local_from_suffix },
+ { "local_interfaces", opt_stringptr, &local_interfaces },
++#ifdef DLOPEN_LOCAL_SCAN
++ { "local_scan_path", opt_stringptr, &local_scan_path },
++#endif
+ { "local_scan_timeout", opt_time, &local_scan_timeout },
+ { "local_sender_retain", opt_bool, &local_sender_retain },
+ { "localhost_number", opt_stringptr, &host_number_string },
Index: 4.2.1-12/Changelog.html
===================================================================
--- 4.2.1-12/Changelog.html (nonexistent)
+++ 4.2.1-12/Changelog.html (revision 61)
@@ -0,0 +1,291 @@
+<!-- <li>2004/08/23 - v4.2.1+cvs (<a href="files/sa-exim-cvs.tar.gz">sa-exim cvs tar.gz</a>
+ (latest version available via CVS only, or a somewhat recent via
+ <a href="files/sa-exim-cvs.tar.gz">this link</a>) -->
+
+<li>2006/01/09 - v4.2.1 (<a href="files/sa-exim-4.2.1.tar.gz">sa-exim.tar.gz</a>
+or <a href="files/local_scan/local_scan.c_4.2.1">local_scan only</a>)
+ <br><b>Security update</b> (reported by Chris Morris)
+ <ul>
+ <li>Modified Greylisting.pm not to generate tuplets with spaces, although
+ the cleaning cron job is now safe with regard to whitespace
+ <li>Included Mark Lawrence's perl script to better clean old tuplets
+ <li>The default config now ships with the greylistclean cronjob running
+ as nobody (which spamd should be running as, too)
+ </ul>
+
+<li>2005/01/17 - v4.2 (<a href="files/sa-exim-4.2.tar.gz">sa-exim.tar.gz</a>
+or <a href="files/local_scan/local_scan.c_4.2">local_scan only</a>)
+ <br><b>Do not use, greylistclean is insecure, use 4.2.1 instead</b>
+ <ul>
+ <li>Fixed code so that it compiles inside the exim tree too (thanks Jason)
+ <li>Support SA 3.0 new score reporting format (score= instead of hits=)
+ <li>Proper SA 3.0 plugin support
+ <li>Documentation updates
+ <li>greylisting files now also save the last SA score, just in case
+ <li>Saved files are now group read/write too, if you need to shut off group
+ access, do it at the directory level
+ <li>Only rewrite Content-Type/Content-Transfer-Encoding if SARewriteBody is
+ on now (this used to be useful with old SA versions and defang_mime
+ but those options are gone). Suggested by Adam Tilghman.
+ <li>Finally made all score threshold variables exim conditions that are
+ evaluated at runtime
+ <li>SAteergrubecond is deprecated as a result
+ </ul>
+
+<li>2004/08/16 - v4.1 (<a href="files/sa-exim-4.1.tar.gz">sa-exim.tar.gz</a>
+or <a href="files/local_scan/local_scan.c_4.1">local_scan only</a>)
+ <b>Please see the mailing list, or use the CVS version if you are compiling
+ sa-exim inside your exim tree</b> (there is a small mistake in the source
+ which will prevent proper building) / <b>You also need CVS if you are
+ using SA 3.0</b>
+ <ul>
+ <li>Deal with being called with the number of recipients is 0 (reported by
+ John Horne)
+ <li>Made hopefully fully 64 bit clean (well, it was written that way,
+ except for that pesky printf in C, which got in the way). Kudos go to
+ Adam D. Barratt for finding and explaining the bug
+ <li>Switched to using strchr instead of index to remove compilation warnings
+ on some systems (reported by John Horne/Jeff Carter)
+ <li>Added SAspamcHost/SAspamcPort at the request of several people
+ <li>Fixed mbox From file to be standards complaint (reported by Cliff Hones)
+ <li>Added SAFEMESGIDCHARS option for safer message-id based filenames
+ <li>New version of the SA patch, with safe file creation (clean env from
+ and rcpt to before using as directory names)
+ <li><b>IMPORTANT</b>: if you are using greylisting, and applied the
+ previous greylisting patch, it didn't create shell safe filenames,
+ it is therefore highly recommended that you apply the new version
+ <li>Added a quick patch to sa-exim to deal with headers that are longer
+ than 8K (and drop the remaining lines)
+ </ul>
+
+
+<li>2004/03/16 - v4.0 (<a href="files/sa-exim-4.0.tar.gz">sa-exim.tar.gz</a>
+or <a href="files/local_scan/local_scan.c_4.0">local_scan only</a>)
+ <ul>
+ <li>Added SAspamcpath (from Richard Lithvall)
+ <li>Makefile fixes for version.h and dependencies
+ <li>Added exim acl_m trick from Chirik in README
+ <li>New code to read and pass on any X-Spam- header from SpamAssassin
+ <li>Message-Id is now logged in SA log entries to allow you track down
+ a message in other logfiles, like SA's log
+ <li>Add X-SA-Exim-Connect-IP header for greylisting
+ <li>Allow for tempreject on messages not flagged as spam by SA (for
+ greylisting)
+ <li>Added greylisting support (see README.greylisting)
+ <li>Added the following options to sa-exim.conf:
+ <ul>
+ <li>SAspamcSockPath
+ <li>SAgreylistiswhitestr
+ <li>SAgreylistraisetempreject
+ </ul>
+ <li>Lots of documentation fixes and updates
+ <li>Basic debian tree shipped by default (but real deb package from Sander
+ Smeenk)
+ </ul>
+
+<li>2003/08/18 - v3.1 (<a href="files/sa-exim-3.1.tar.gz">sa-exim tar.gz</a>
+ or <a href="files/local_scan/local_scan.c_3.1">local_scan only</a>)
+ <ul>
+ <li>Fixed <em>SA: Action: teergrubed sender until full configured duration</em> output
+ <li>spamassassin.conf was renamed sa-exim.conf (bad initial name choice)
+ <li>Changed teergrubing so that it works with exim 4.20 and above
+ <li>Added the much requested SARewriteBody option for SA 2.50's report_safe
+ (courtesy of Richard Lithvall)
+ <li>Added SAaddSAEheaderBeforeSA to deal with SARewriteBody and privacy
+ <li>Added SAPrependArchiveWithFrom option (Richard Lithvall)
+ <li>As announced in the previous version, SAStallSender was removed.
+ Use Teergrubing instead
+ <li>Message-Id is read directly from Exim now that the API allows for that
+ (we used to parse the Message-Id header ourselves) -&gt; except that
+ we don't use this for logging or saving messages: as soon as we can
+ read the real Message-Id from the headers, we use that Message-Id for
+ logging (this is to facilitate tracking of messages from the logs and
+ correlating with something like SA timelog files)
+ <li>Logging improved some more: Message-Id is added to log entries, as
+ well as the full mailinfo whether the message is spam or not
+ </ul>
+
+<li>2003/04/30 - v3.0 (<a href="files/sa-exim-3.0.tar.gz">sa-exim tar.gz</a>
+ or <a href="files/local_scan/local_scan.c_3.0">local_scan only</a>)
+ <ul>
+ <li>Makefile can generate a short sa-exim.conf (for Brian Kendig)
+ <li>Added a contrib directory with 3rd party scripts
+ <li>Since we already had X-SA-Exim-Rcpt-To: to show the envelope to
+ (disabled by default), I added X-SA-Exim-Mail-From: to show the
+ envelope from (always enabled, but you can delete it in system_filter
+ if you wish). If you can't easily see or parse the envelope sender
+ in your mails, this should definitely help
+ <li>Much improved directory creation and error handling for the reject
+ save directories
+ <li>Added SIGCHLD patch from David Woodhouse
+ <li>Added version header that looks like this:
+ X-SA-Exim-Version: 2.2.x-cvs (built Tue Apr 22 10:28:25 PDT 2003)
+ <li>Rewrote pretty much every log message to be more consistent and grepable
+ (the previous ones were quite bad). Suggested by multiple people
+ including Brian Kendig
+ <li>Made the SMTP error messages finally configurable (suggested by
+ several people). This is now possible since exim lets me output a
+ different message in the log than in the SMTP session. Consequently, new
+ default messages do not show the spam score, this only goes to the exim
+ now.
+ <li>Made SAmaxrcptlistlength and option to control how long of a
+ X-SA-Exim-Rcpt-To header you can output if you want to output it at
+ all
+ <li>Do not output "savemail condition expanded to false" if not in debug
+ mode (as reported by Brian Kendig)
+ <li>Now ships with a sample local_scan.h if we can't find the exim source
+ <li>Change of logic to delete SA headers that were in the original mail
+ but weren't outputted by the SA run (like X-Spam-Flag, as reported
+ by Chad Leigh)
+ <li>Modified local_scan dlopen patch to deal with updates to the exim
+ local_scan API
+ <li>The default location for spamasassin.conf was changed to /etc/exim4
+ (debian default)
+ <li>Updated README and INSTALL
+ <li>Updated localscan_dlopen.patch to deal with minor/major version numbers
+ <li>Added X-SA-Exim-Version
+ </ul>
+<li>2002/10/28 - v2.2 (<a href="files/sa-exim-2.2.tar.gz">sa-exim tar.gz</a>
+ or <a href="files/local_scan/local_scan.c_2.2">local_scan only</a>)
+ <ul>
+ <li>Fixed a bug that affected all mails bigger than what spamc would
+ accept. Doh! (it not clear why, but spamc would hang and stop reading
+ after it had been fed more than it was willing to accept)
+ <li>Added more debugging code to help track the above problem
+ <li>Depending on SATruncBodyCond will now either not pass a message that's
+ too big to spamc, or will optionally truncate it first
+ <li>Now strips any X-SA-Exim-* headers already present in the message before
+ scanning it
+ <li>Added new X-SA-Exim-Rcpt-To: header (see privacy section in README)
+ after a suggestion from Brian Kendig
+ <li>Teergrube is now spelled correctly (note that the option names in
+ sa-exim.conf changed as a result)
+ <li>Teergrubing has been re-implemented to detect that the other side went
+ away so that exim doesn't stay around for nothing.
+ <li>Added SAteergrubecond so that you don't teergrube your neighbours
+ <li>Small cleanups
+ </ul>
+<li>2002/10/13 - v2.1 (buggy) (<a href="files/sa-exim-2.1.tar.gz">sa-exim tar.gz</a>
+ or <a href="files/local_scan/local_scan.c_2.1">local_scan only</a>)
+ <ul>
+ <li>Default mail config is now in /etc/exim instead of /etc/mail
+ <li>Fixed SAstallsender so that exim doesn't leave spool files behind
+ <li>Fixed comparison for spam values as suggested by Patrice Fournier
+ <li>Returned a header saying whether SA-Exim was able to scan the mail
+ or not (based on a suggestion from Patrice Fournier)
+ <li>Added support for teergrubing as suggested by Robert Strickler
+ (see
+ <A HREF="http://www.iks-jena.de/mitarb/lutz/usenet/teergrube.en.html">
+ http://www.iks-jena.de/mitarb/lutz/usenet/teergrube.en.html</A>)
+ <li>We now make sure that we feed spamc a little more data than it's
+ willing to accept. That way, we don't feed a truncated message
+ <li>sa-exim.conf now appends /new on save directories so that they
+ are valid maildir spool and you can run mutt -f dirname to read
+ <li>Small cleanups
+ </ul>
+
+<li>2002/07/07 - v2.0.1 (<a href="files/sa-exim-2.0.1.tar.gz">sa-exim tar.gz</a>
+ or <a href="files/local_scan/local_scan.c_2.0.1">local_scan only</a>)
+ <ul>
+ <li>Removed unneeded ## concatenation in macro
+ <li>Fixed lseek call, as reported by Peter N Lewis
+ <li>Improved Makefile for documentation
+ <li>Suggestion from dman to allow for config options overrides in Makefile
+ <li>Fixed all the compiler warnings that were fixable
+ <li>Handle more kinds of Message-Id as suggested by Patrice Fournier
+ </ul>
+
+<li>2002/06/14 - v2.0 (<a href="files/sa-exim-2.0.tar.gz">sa-exim tar.gz</a>
+ or <a href="files/local_scan/local_scan.c_2.0">local_scan only</a>)
+ <ul>
+ <li>Allow for stalling SMTP sessions from spammers (caution)
+ <li>Support X-Spam-Status from SA pre 2.30
+ <li>Build patches from Norm <norm@sandbox.org.uk>
+ <li>Documented that spamd shouldn't be run with -c
+ <li>dman's patch to allow for this to be a shared library
+ <li>dman's indirect request for saved files to be 660
+ </ul>
+<li><a href="files/local_scan/local_scan.c_2.0b1">2002/06/01 - v2.0b1</a><br>
+ This is how 1.0 would have been if I had done it right :-)
+ <ul>
+ <li>We now attempt to create directories we write to
+ (suggestion from Patrice Fournier)
+ <li>Log envelope sender, recipients and connecting host
+ on rejected messages (suggestion from Patrice Fournier)
+ <li>We can now save non rejected messages whether they were
+ flagged as spam or not (based on request from Patrice)
+ <li>Each save rule now has its own condition that lets you
+ decide which messages you want to save or not
+ <li>Fixed parsing of Message-Id. May not parse all of them
+ but won't do anything stupid with bad input
+ <li>Fixed a buglet where we removed old headers before knowing
+ whether they were going to be replaced.
+ <li>Added much needed internal alarm so that we don't run
+ too long
+ <li>I added lots of options, but weren't able to test all
+ of them and their combinations, please reports problems
+ you may notice and documentation issues (in config file)
+ <li>Thanks also go to dman for his plentiful feedback
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.3">2002/05/21 - v1.3</a>
+ <ul>
+ <li>We now close the files we create on disk. Duh!
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.2.2">2002/05/17 - v1.2.2</a>
+ <ul>
+ <li>SA options are now kept in memory. Small cleanups
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.2.1">2002/05/13 - v1.2.1</a>
+ <ul>
+ <li>v1.2 (unreleased) didn't work right: it tagged messages
+ properly, but failed to see what was marked as spam and
+ couldn't reject messages. Fixed.
+ <li>Stripped newlines in header lines (better for logging)
+ <li>fixed header_add bug if headers contained '%'
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.2">2002/05/12 - v1.2</a> (unreleased)
+ <ul>
+ <li>According to Craig R Hughes, any X-Spam header can be multiline.
+ Let's parse them accordingly
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.1.1">2002/05/08 - v1.1.1</a>
+ <ul>
+ <li>Added fake envelope from to mails that we save on disk
+ so that they can be opened with MUAs (idea from dman)
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.1">2002/05/07 - v1.1</a>
+ <ul>
+ <li>Cleaned up and fixed multiline header parsing
+ <li>Added parsing of Subject back from Spamc (suggestion from dman)
+ <li>We now log how long spamc took, and all messages processed
+ by spamc get logged in mainlog so that we know the outcome
+ <li>Added custom header compare function to handle mixed case headers
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.0.1">2002/05/06 - v1.0.1</a>
+ <ul>
+ <li>Fixed problems with reading Content-Type back from spamc
+ (we used to read whole body too, ooops...)
+ <li>Handle multi-line Content-Type headers.
+ <li>All log entries now start with "SA: "
+ <li>If SA gets run twice, we drop the previous X-Spam headers
+ <li>Support for X-Spam-Prev-Content-Transfer-Encoding
+ </ul>
+<li><a href="files/local_scan/local_scan.c_1.0">2002/05/05 - v1.0</a>
+ <ul>
+ <li>*Many* changes. This is now a real program with hopefully
+ most of the configuration options people could need
+ <li>Fully configurable through external config file
+ <li>Condition to run or not run SA against a message
+ <li>3 Levels of spam handling
+ <li>Option to save messages that are rejected or cause errors
+ <li>Very complete error checking
+ </ul>
+<li><a href="files/local_scan/local_scan.c_0.9.1">2002/04/17 - v0.9.1</a>
+ <ul>
+ <li>Added a few checks for possible failures
+ </ul>
+<li><a href="files/local_scan/local_scan.c_0.9">2002/04/16 - v0.9</a>
+ <ul>
+ <li>Pre-release
+ </ul>
+</ul>
Index: 4.2.1-12/eximinc/mytypes.h
===================================================================
--- 4.2.1-12/eximinc/mytypes.h (nonexistent)
+++ 4.2.1-12/eximinc/mytypes.h (revision 61)
@@ -0,0 +1,95 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) University of Cambridge 1995 - 2003 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+
+/* This header file contains type definitions and macros that I use as
+"standard" in the code of Exim and its utilities. Make it idempotent because
+local_scan.h includes it and exim.h includes them both (to get this earlier). */
+
+#ifndef MYTYPES_H
+#define MYTYPES_H
+
+
+#define FALSE 0
+#define TRUE 1
+#define TRUE_UNSET 2
+
+
+/* If gcc is being used to compile Exim, we can use its facility for checking
+the arguments of printf-like functions. This is done by a macro. */
+
+#ifdef __GNUC__
+#define PRINTF_FUNCTION __attribute__((format(printf,1,2)))
+#else
+#define PRINTF_FUNCTION
+#endif
+
+
+/* Some operating systems (naughtily, imo) include a definition for "uchar" in
+the standard header files, so we use "uschar". Solaris has u_char in
+sys/types.h. This is just a typing convenience, of course. */
+
+typedef int BOOL;
+typedef unsigned char uschar;
+
+
+/* These macros save typing for the casting that is needed to cope with the
+mess that is "char" in ISO/ANSI C. Having now been bitten enough times by
+systems where "char" is actually signed, I've converted Exim to use entirely
+unsigned chars, except in a few special places such as arguments that are
+almost always literal strings. */
+
+#define CS (char *)
+#define CSS (char **)
+#define US (unsigned char *)
+#define USS (unsigned char **)
+
+/* The C library string functions expect "char *" arguments. Use macros to
+avoid having to write a cast each time. We do this for string and file
+functions; for other calls to external libraries (which are on the whole
+special-purpose) we just use casts. */
+
+
+#define Uatoi(s) atoi(CS(s))
+#define Uatol(s) atol(CS(s))
+#define Uchdir(s) chdir(CS(s))
+#define Uchmod(s,n) chmod(CS(s),n)
+#define Uchown(s,n,m) chown(CS(s),n,m)
+#define Ufgets(b,n,f) fgets(CS(b),n,f)
+#define Ufopen(s,t) fopen(CS(s),CS(t))
+#define Ulink(s,t) link(CS(s),CS(t))
+#define Ulstat(s,t) lstat(CS(s),t)
+#ifdef O_BINARY /* This is for Cygwin, */
+#define Uopen(s,n,m) open(CS(s),(n)|O_BINARY,m) /* where all files must */
+#else /* be opened as binary */
+#define Uopen(s,n,m) open(CS(s),n,m) /* to avoid problems */
+#endif /* with CRLF endings. */
+#define Uread(f,b,l) read(f,CS(b),l)
+#define Urename(s,t) rename(CS(s),CS(t))
+#define Ustat(s,t) stat(CS(s),t)
+#define Ustrcat(s,t) strcat(CS(s),CS(t))
+#define Ustrchr(s,n) US strchr(CS(s),n)
+#define Ustrcmp(s,t) strcmp(CS(s),CS(t))
+#define Ustrcpy(s,t) strcpy(CS(s),CS(t))
+#define Ustrcspn(s,t) strcspn(CS(s),CS(t))
+#define Ustrftime(s,m,f,t) strftime(CS(s),m,f,t)
+#define Ustrlen(s) (int)strlen(CS(s))
+#define Ustrncat(s,t,n) strncat(CS(s),CS(t),n)
+#define Ustrncmp(s,t,n) strncmp(CS(s),CS(t),n)
+#define Ustrncpy(s,t,n) strncpy(CS(s),CS(t),n)
+#define Ustrpbrk(s,t) strpbrk(CS(s),CS(t))
+#define Ustrrchr(s,n) US strrchr(CS(s),n)
+#define Ustrspn(s,t) strspn(CS(s),CS(t))
+#define Ustrstr(s,t) US strstr(CS(s),CS(t))
+#define Ustrtod(s,t) strtod(CS(s),CSS(t))
+#define Ustrtol(s,t,b) strtol(CS(s),CSS(t),b)
+#define Ustrtoul(s,t,b) strtoul(CS(s),CSS(t),b)
+#define Uunlink(s) unlink(CS(s))
+
+#endif
+
+/* End of mytypes.h */
Index: 4.2.1-12/eximinc/store.h
===================================================================
--- 4.2.1-12/eximinc/store.h (nonexistent)
+++ 4.2.1-12/eximinc/store.h (revision 61)
@@ -0,0 +1,53 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) University of Cambridge 1995 - 2003 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* Header for Exim's memory allocation functions */
+
+#ifndef STORE_H
+#define STORE_H
+
+/* Define symbols for identifying the two store pools. */
+
+#define POOL_MAIN 0
+#define POOL_PERM 1
+
+/* This variable is set by store_get() to its yield, and by store_reset() to
+NULL. This allows string_cat() to optimize its store handling. */
+
+extern void *store_last_get;
+
+/* This variable contains the current store pool number. */
+
+extern int store_pool;
+
+/* Macros for calling the memory allocation routines with
+tracing information for debugging. */
+
+#define store_extend(addr,old,new) \
+ store_extend_3(addr, old, new, __FILE__, __LINE__)
+
+#define store_free(addr) store_free_3(addr, __FILE__, __LINE__)
+#define store_get(size) store_get_3(size, __FILE__, __LINE__)
+#define store_get_perm(size) store_get_perm_3(size, __FILE__, __LINE__)
+#define store_malloc(size) store_malloc_3(size, __FILE__, __LINE__)
+#define store_release(addr) store_release_3(addr, __FILE__, __LINE__)
+#define store_reset(addr) store_reset_3(addr, __FILE__, __LINE__)
+
+
+/* The real functions */
+
+extern BOOL store_extend_3(void *, int, int, char *, int); /* These use */
+extern void store_free_3(void *, char *, int); /* char * */
+extern void *store_get_3(int, char *, int); /* because */
+extern void *store_get_perm_3(int, char *, int); /* the */
+extern void *store_malloc_3(int, char *, int); /* value is */
+extern void store_release_3(void *, char *, int); /* always */
+extern void store_reset_3(void *, char *, int); /* __FILE__ */
+
+#endif /* STORE_H */
+
+/* End of store.h */
Index: 4.2.1-12/eximinc/local_scan.h
===================================================================
--- 4.2.1-12/eximinc/local_scan.h (nonexistent)
+++ 4.2.1-12/eximinc/local_scan.h (revision 61)
@@ -0,0 +1,150 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) University of Cambridge 1995 - 2003 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* This file is the header that is the only Exim header to be included in the
+source for the local_scan.c() function. It contains definitions that are made
+available for use in that function, and which are documented. */
+
+
+/* Some basic types that make some things easier, and the store functions. */
+
+#include <sys/types.h>
+#include "mytypes.h"
+#include "store.h"
+
+
+/* The function and its return codes. */
+
+extern int local_scan(int, uschar **);
+
+enum {
+ LOCAL_SCAN_ACCEPT, /* Accept */
+ LOCAL_SCAN_ACCEPT_FREEZE, /* Accept, but freeze */
+ LOCAL_SCAN_ACCEPT_QUEUE, /* Accept, but no immediate delivery */
+ LOCAL_SCAN_REJECT, /* Permanent rejection */
+ LOCAL_SCAN_REJECT_NOLOGHDR, /* Permanent rejection, no log header */
+ LOCAL_SCAN_TEMPREJECT, /* Temporary rejection */
+ LOCAL_SCAN_TEMPREJECT_NOLOGHDR /* Temporary rejection, no log header */
+};
+
+
+/* Return codes from the support functions lss_match_xxx(). */
+
+#define OK 0 /* Successful match */
+#define DEFER 1 /* Defer - some problem */
+#define FAIL 2 /* Matching failed */
+#define ERROR 3 /* Internal or config error */
+
+
+/* Available logging destinations */
+
+#define LOG_MAIN 1 /* Write to the main log */
+#define LOG_PANIC 2 /* Write to the panic log */
+#define LOG_REJECT 16 /* Write to the reject log, with headers */
+
+
+/* Accessible debugging bits */
+
+#define D_v 0x00000001
+#define D_local_scan 0x00000002
+
+
+/* Option types that can be used for local_scan_options. The boolean ones
+MUST be last so that they are contiguous with the internal boolean specials. */
+
+enum { opt_stringptr, opt_int, opt_octint, opt_mkint, opt_fixed, opt_time,
+ opt_bool };
+
+
+/* The length of message identification strings. This is the id used internally
+by exim. The external version for use in Received: strings has a leading 'E'
+added to ensure it starts with a letter. */
+
+#define MESSAGE_ID_LENGTH 16
+
+/* The offset to the start of the data in the data file - this allows for
+the name of the data file to be present in the first line. */
+
+#define SPOOL_DATA_START_OFFSET (MESSAGE_ID_LENGTH+3)
+
+/* local_scan() ABI version number for dynamic libraries
+ The major number is increased when the ABI is changed in a non
+ backward compatible way.
+ The minor number is increased each time a new feature is added (in a
+ way that doesn't break backward compatibility) -- Marc */
+#define LOCAL_SCAN_ABI_VERSION_MAJOR 1
+#define LOCAL_SCAN_ABI_VERSION_MINOR 0
+
+/* Structure definitions that are documented as visible in the function. */
+
+typedef struct header_line {
+ struct header_line *next;
+ int type;
+ int slen;
+ uschar *text;
+} header_line;
+
+/* Entries in lists options are in this form. */
+
+typedef struct {
+ char *name;
+ int type;
+ void *value;
+} optionlist;
+
+/*Structure for holding information about an envelope address. The errors_to
+field is always NULL except for one_time aliases that had errors_to on the
+routers that generated them. */
+
+typedef struct recipient_item {
+ uschar *address; /* the recipient address */
+ int pno; /* parent number for "one_time" alias, or -1 */
+ uschar *errors_to; /* the errors_to address or NULL */
+} recipient_item;
+
+
+/* Global variables that are documented as visible in the function. */
+
+extern unsigned int debug_selector; /* Debugging bits */
+
+extern uschar *expand_string_message; /* Error info for failing expansion */
+extern header_line *header_last; /* Final header */
+extern header_line *header_list; /* First header */
+extern BOOL host_checking; /* Set when checking a host */
+extern uschar *interface_address; /* Interface for incoming call */
+extern int interface_port; /* Port number for incoming call */
+extern uschar *message_id; /* Internal id of message being handled */
+extern uschar *received_protocol; /* Name of incoming protocol */
+extern int recipients_count; /* Number of recipients */
+extern recipient_item *recipients_list;/* List of recipient addresses */
+extern unsigned char *sender_address; /* Sender address */
+extern uschar *sender_host_address; /* IP address of sender, as chars */
+extern uschar *sender_host_authenticated; /* Name of authentication mechanism */
+extern uschar *sender_host_name; /* Host name from lookup */
+extern int sender_host_port; /* Port number of sender */
+
+
+/* Functions that are documented as visible in local_scan(). */
+
+extern int child_close(pid_t, int);
+extern pid_t child_open_exim(int *);
+extern void debug_printf(char *, ...) PRINTF_FUNCTION;
+extern uschar *expand_string(uschar *);
+extern void header_add(int, char *, ...);
+extern void log_write(unsigned int, int, char *format, ...);
+extern int lss_b64decode(uschar *, uschar **);
+extern uschar *lss_b64encode(uschar *, int);
+extern int lss_match_domain(uschar *, uschar *);
+extern int lss_match_local_part(uschar *, uschar *, BOOL);
+extern int lss_match_address(uschar *, uschar *, BOOL);
+extern int lss_match_host(uschar *, uschar *, uschar *);
+extern void receive_add_recipient(uschar *, int);
+extern uschar *string_copy(uschar *);
+extern uschar *string_copyn(uschar *, int);
+extern uschar *string_sprintf(char *, ...);
+
+/* End of local_scan.h */
Index: 4.2.1-12/eximinc/version
===================================================================
--- 4.2.1-12/eximinc/version (nonexistent)
+++ 4.2.1-12/eximinc/version (revision 61)
@@ -0,0 +1 @@
+exim-4.14
Index: 4.2.1-12/eximinc/README
===================================================================
--- 4.2.1-12/eximinc/README (nonexistent)
+++ 4.2.1-12/eximinc/README (revision 61)
@@ -0,0 +1,6 @@
+In order to faciliate building on systems that have exim installed but don't
+have the exim source, I am including includes from a recent exim version.
+While I am keeping track of which version, this shouldn't be necessary as
+the local_scan API is supposed to be upward compatible
+(technically, we should raise LOCAL_SCAN_ABI_VERSION every time Philip
+adds a feature to the API -- Marc)
Index: 4.2.1-12/README.greylisting
===================================================================
--- 4.2.1-12/README.greylisting (nonexistent)
+++ 4.2.1-12/README.greylisting (revision 61)
@@ -0,0 +1,258 @@
+ GREYLISTING with SA-Exim
+ ------------------------
+
+
+INTRODUCTION
+------------
+SA-Exim allows for intelligent greylisting by combining the idea of greylisting
+with Spam scores from SpamAssassin
+
+If you don't know what greylisting is, you should probably go read up there:
+http://projects.puremagic.com/greylisting/
+(note that this implementation works differently than the one described there)
+
+So, SA-Exim isn't just yet another greylisting implementation. By tying it
+into SA-Exim, and especially by running SA at SMTP time, you can do the
+following things:
+- do not bother greylisting people who send messages detected as spam by SA
+ (indeed, regular greylisting will accept mail from a spammer if he retries
+ or sends it from an open relay)
+ SA-Exim will never greylist, or whitelist a sender based on a mail clearly
+ marked as spam by SA.
+
+- do not delay mail from people who aren't spamming you (this one is the most
+ important feature of SA-Exim greylisting, as it removes the biggest
+ disadvantage linkes to greylisting)
+
+- only greylist (and maybe later whitelist) hosts that send you mail with
+ a certain SA score.
+
+
+IMPLEMENTATION
+--------------
+So how does this all work?
+SA comes with a patch for SA 2.x (and a module for SA 3.x) that does the
+following things:
+- add a greylisting rule which gets run at the very end, and where if
+ the score is already higher than a configured value, we do not bother
+ greylisting the host. We just return a rule failure, which doesn't
+ change the score and lets SA-Exim reject the mail as usual
+- if the score is lower than the "surely spam" threshold (shown as 11 in the
+ example below), check for a file in
+ /var/spool/sa-exim/messageids/co/nn/ect/ip/envfrom/envto
+ - if it's there, check if it was written more than x seconds ago (1800s/30mn
+ in the example below)
+ - if so, change the status to whitelisted and return true so that SA applies
+ the whitelist negative score
+ - if not, simply increase counters, host is still greylisted
+ - if the file is not there, create it
+- every x time (like 4 hours or two days), remove all greylist entries that
+ only saw one mail (i.e. still greylisted, not whitelisted yet).
+ This is done with a find cron job
+- every y time (like 1 week), remove whitelisted entries so that your filesystem
+ doesn't clutter up with hosts you're not going to hear from again in a while
+
+
+Then, you call the greylisting rule with this (in SA's local.cf)
+# reseval is a special eval which only runs after you have the result from
+# everything else (lets us not greylist a host that is sending spam, otherwise
+# this rule might set a sufficiently negative score that the next spam would
+# be allowed in)
+# Note the 'key' -> 'value'; syntax. It's a special hack to go through SA's
+# config parser. You need to keep that exact syntax
+# greylistsecs: how long you greylist a tuplet because whitelisting it
+# greylistnullfrom: set to 1 to also greylist mail with a null env from
+# greylistfourthbyte: keep the 4 bytes of the connecting host instead of 3
+header GREYLIST_ISWHITE reseval:greylisting("( 'dir' => '/var/spool/sa-exim/tuplets'; 'method' => 'dir'; 'greylistsecs' => '1800'; 'dontgreylistthreshold' => 11; 'connectiphdr' => 'X-SA-Exim-Connect-IP'; 'envfromhdr' => 'X-SA-Exim-Mail-From'; 'rcpttohdr' => 'X-SA-Exim-Rcpt-To'; 'greylistnullfrom' => 0; 'greylistfourthbyte' => 0 )")
+describe GREYLIST_ISWHITE The incoming server has been whitelisted for this rece
+ipient and sender
+score GREYLIST_ISWHITE -1.5
+
+Note that SA greylisting depends on X-SA-Exim-Rcpt-To, so you have to ensure
+that SAmaxrcptlistlength is set to a reasonably high value (up to 8000) instead
+of the current default of 0 (you can remove the header in exim's system_filter
+or a transport if you don't want it to show in user's mails, see "privacy
+warning" in README)
+
+
+Now, in case you aren't confused yet, you get even more knobs to play with :)
+If a spammer resends you a spam until it gets whitelisted (or typically, it
+gets sent to a relay that resends it to you), even if you are setup to
+accept the spam at the point, you don't want to lower the SA score too much
+just because the mail was resent to you several times (i.e. a rather negative
+score for GREYLIST_ISWHITE). So, you can actually configure SA-Exim to temp
+reject messages on a much higher score than usual, if they don't have the
+GREYLIST_ISWHITE tag.
+
+In other words, let's say you have this in sa-exim.conf:
+SApermreject: 11.0
+SAtempreject: 3.0
+SAgreylistraisetempreject: 6.5
+
+If a mail comes in at less than 3.0, the SA patch/module remembers the sending
+server's connecting IP, the env from, and the rcpt to(s), and whitelists those.
+(those will be referred to as tuplets, one for each rcpt to)
+
+If the score is between 3.0 and 11.0,
+- if at least one of the tuplets is already whitelisted, SA applies the -1.5
+ score and yields an end score below 9.5, Now, at the same time, SAtempreject
+ is temporarily raised by 6.5, so everything under 9.5 is accepted, which
+ basically means that the mail goes through.
+- if none of the tuplets are whitelisted, they get greylisted
+- if they are greylisted, they can get upgraded to whitelisted status if the
+ sending server has been trying for long enough (1800secs in the example given
+ above). At this point the same thing happens as in case #1 and the mail is
+ accepted
+
+If a tuplet that is going to be whitelisted or greylisted, already is, SA
+updates counters to let you run reports and anything else you want, like
+deciding if or when you'd like to expire the entry
+
+If by now you wonder why you would want to both decrease the SA score and
+increase the maximum score you'll accept mails on, the reason is as follows:
+You probably don't want to lower the SA score by 8 just because the tuplet
+is whitelisted (not only does it mess with the SA scoring of messages that used
+to be flagged as spam, but a spam with a score of 13.5 would then be lowered
+to 5.5, be temprejected, and be close to the accept range).
+Instead, giving an SA score of -1.5, a message with 13.5 becomes 12.0 and still
+gets rejected right away. You also do not overly (and artifically) lower the
+score of a message, just for SA-Exim's sake
+
+If you so wish, you can also give the SA rule a score of -0.1, and only
+dynamically raise the tempreject score for messages that are whitelisted.
+
+
+SCORE SETUP
+-----------
+It makes little sense to have
+SAtempreject + SAgreylistraisetempreject + SA GREYLIST_ISWHITE > SApermreject
+as there is little point to raise SAtempreject if the message that's
+whitelisted still gets refused by the SApermreject score
+
+As to whether you want to put more points into SA GREYLIST_ISWHITE or
+SAgreylistraisetempreject, this is your call, but as a general rule, you only
+want to change the SA score in a way that makes sense for spam scoring,
+as it similarly affects the score of all messages, whether SA-Exim sees them
+in the non spam range, tempreject range, or "this is spam that I would never
+let in" range.
+
+
+FILE SETUP
+----------
+Make very sure that uid nobody can traverse /var/spool/sa-exim and
+create tuplets writeable by nobody (or whoever you run SA as)
+
+Then, setup a cron job to delete tuplets that are older than 14 days for
+whitelisted entries, and 2 days for greylisted entries (or whatever
+values you fancy).
+Note that because this implementation does not systematically force the senders to resend you mail, unless they sent something that looks too much like spam,
+you will typically see few whitelisted entries, and those will either be
+potential spam that was actually resent to you at least 30mn after the
+initial copy (or whatever value you setup in "header GREYLIST_ISWHITE"), or
+people who sent you several Emails (where the second Email will just happen to
+trigger a whitelisting).
+
+
+FILE SETUP
+----------
+You should install greylistclean.cron in /etc/cron.d/ on your system to
+call greylistclean and clean up greylisted entries and whitelisted entries
+that haven't been used in a while.
+You can optionally modify it to tweak the cleanup times.
+Note that you need to tweak greylistclean.cron to match the user spamd runs
+as if you aren't using the recommended --username=nobody
+
+
+SA PATCH (SA 2.x)
+-----------------
+For all this to work, you also need to patch SA with SA-greylist.diff
+from the source tar (or /usr/share/doc/sa-exim*/ for a precompiled package).
+This patch never made it to the main SA 2.x branch as the developers had mostly
+switched to 3.x where you can use plugins.
+If you still use SA 3.x, you can go to /usr/share/perl5/Mail (or wherever
+appropriate on your system), and run
+patch -p0 -s < /path/to/sa-exim/SA-greylisting.diff
+Note that while the patch works, it will not be maintained anymore since
+it is deprecated for the SA 3.x plugin
+
+
+SA PLUGIN (SA 3.x)
+------------------
+Newer versions of SpamAssassin support plugins, so there is no need to
+patch SA anymore, you can just install the Greylisting.pm module on your
+system and get SA to use it
+This is how you call the module in SA 3.x (i.e. put this in your
+/etc/spamassassin/local.cf)
+
+# Note the 'key' -> 'value'; syntax. It's a special hack to go through SA's
+# config parser. You need to keep that exact syntax
+# greylistsecs: how long you greylist a tuplet because whitelisting it
+# greylistnullfrom: set to 1 to also greylist mail with a null env from
+# greylistfourthbyte: keep the 4 bytes of the connecting host instead of 3
+loadplugin Greylisting /usr/share/perl5/Mail/SpamAssassin/Plugin/Greylisting.pm
+header GREYLIST_ISWHITE eval:greylisting("( 'dir' => '/var/spool/sa-exim/tuplets'; 'method' => 'dir'; 'greylistsecs' => '1800'; 'dontgreylistthreshold' => 11; 'connectiphdr' => 'X-SA-Exim-Connect-IP'; 'envfromhdr' => 'X-SA-Exim-Mail-From'; 'rcpttohdr' => 'X-SA-Exim-Rcpt-To'; 'greylistnullfrom' => 1; 'greylistfourthbyte' => 0 )")
+describe GREYLIST_ISWHITE The incoming server has been whitelisted for this recipient and sender
+score GREYLIST_ISWHITE -1.5
+# Run SpamAssassin last, after all other rules.
+# (lets us not greylist a host that is sending spam, otherwise this rule might
+# set a sufficiently negative score that the next spam would be allowed in)
+priority GREYLIST_ISWHITE 99999
+
+
+SA-EXIM NEW BEHAVIOR CONCERNS
+-----------------------------
+What greylisting changes as far as spam accepting or rejection is concerned:
+Once a tuplet has been whitelisted, spam from that host is more likely
+to be accepted until the tuplet expires. In the case of a mailing list,
+unless you run a find / rm based on the creation time and not the last
+modified time, you will then be a bit more likely to accept spam from
+that list.
+If this turns out to not be acceptable in your case, there isn't a whole
+lot you can do about this, except deleting greylist entries for the host
+from cron before they get promoted to whitelist.
+
+What you can do on top of the existing greylisting code:
+Parse the SA-Exim logs and if you get spam from an IP, you can decide
+to delete greylist entries in /var/spool/sa-exim/tuplets/IP or just
+/var/spool/sa-exim/tuplets/IP/envfrom
+This may not may not be a good thing if you receive the occasional spam
+from a mailing list as you'll then re-delay mail for that list, but then
+again, it will also remove whitelisting for a host that spammed you once
+with an Email that managed to get under the SA scoring radar
+
+
+GREYLISTING AND MXES
+--------------------
+Depending on your configuration, you may have realized that SA-Exim doesn't
+play very well with secondary MXes for your domain if they don't run SA-Exim
+too (for instance, you'd send a tempreject on spam and clog up your
+secondary, or maybe even teergrube it if you forgot to add your MX's IP
+in the do not teergrube list.
+For greylisting, it's even more simple:
+If your secondary MXes aren't running SA-Exim with greylisting, then
+greylisting's efficiency will be greatly reduced as most spammers will send
+their spams to your secondary MXes which will accept the mail for you,
+even if it's sent only once, and then your MXes will resend the spam to you
+until you accept it (rendering greylisting useless)
+
+Now, if your secondaries are running greylisting too, most mail will flow
+through with no delay whatsoever. However, in the worst case scenario, a mail
+that isn't spam, but triggers greylisting because its score is high enough to
+generate a tempreject, could be delayed up to twice the whitelisting time
+if it were to go to your secondary MX first (assuming your primary is
+unreachable or temporarily overloaded), and then be resent to your primary
+MX, which would trigger a second greylisting delay
+FIXME: implement a whitelist of sending IPs so that greylisting returns
+whitelisted right away
+
+
+SECURITY
+--------
+The greylisting function works around the SA parser by sending all the options
+as a hash inside a string. In turn, greylisting evals the said string.
+This is a security problem if you allow your users to run custom rules and it
+gives them access to run spamassassin as a user different from their own, or
+in a way that they otherwise wouldn't be able to.
+Do not run greylisting if this a problem for you (in the default SA/SA-Exim
+setup, this shouldn't be a concern since it doesn't even parse users' config
+files)
Index: 4.2.1-12/localscan_dlopen_up_to_exim_4.14.patch
===================================================================
--- 4.2.1-12/localscan_dlopen_up_to_exim_4.14.patch (nonexistent)
+++ 4.2.1-12/localscan_dlopen_up_to_exim_4.14.patch (revision 61)
@@ -0,0 +1,287 @@
+The initial version of this patch was originally posted David Woodhouse, and
+dman gets the credit for first integrating it with SA-Exim.
+
+I have since then maintained it by first making a few minor changes, and
+later switching it to a major/minor number scheme to support upgrades in
+the exim API that don't affect backward compatibility (you can rely on
+a feature denoted by the minor number and be compatible with future versions
+of exim until Philip has to break the API and increase the major number)
+
+Marc MERLIN <marc_soft@merlins.org>
+
+diff -urN exim-4.14-0/src/EDITME exim-4.14-1/src/EDITME
+--- exim-4.14-0/src/EDITME Tue Mar 11 04:20:18 2003
++++ exim-4.14-1/src/EDITME Sun Mar 23 15:34:15 2003
+@@ -388,6 +388,20 @@
+
+
+ #------------------------------------------------------------------------------
++# On systems which support dynamic loading of shared libraries, Exim can
++# load a local_scan function specified in its config file instead of having
++# to be recompiled with the desired local_scan function. For a full
++# description of the API to this function, see the Exim specification.
++
++DLOPEN_LOCAL_SCAN=yes
++
++# If you set DLOPEN_LOCAL_SCAN, then you need to include -rdynamic in the
++# linker flags. Without it, the loaded .so won't be able to access any
++# functions from exim.
++
++LFLAGS=-rdynamic -ldl
++
++#------------------------------------------------------------------------------
+ # The default distribution of Exim contains only the plain text form of the
+ # documentation. Other forms are available separately. If you want to install
+ # the documentation in "info" format, first fetch the Texinfo documentation
+diff -urNad 50_localscan_dlopen.tmp/src/config.h.defaults 50_localscan_dlopen/src/config.h.defaults
+--- 50_localscan_dlopen.tmp/src/config.h.defaults Sun Dec 29 11:55:42 2002
++++ 50_localscan_dlopen/src/config.h.defaults Sun Dec 29 11:56:44 2002
+@@ -17,6 +17,8 @@
+ #define AUTH_PLAINTEXT
+ #define AUTH_SPA
+
++#define DLOPEN_LOCAL_SCAN
++
+ #define BIN_DIRECTORY
+
+ #define CONFIGURE_FILE
+diff -urN exim-4.14-0/src/globals.c exim-4.14-1/src/globals.c
+--- exim-4.14-0/src/globals.c Tue Mar 11 04:20:20 2003
++++ exim-4.14-1/src/globals.c Sun Mar 23 15:34:15 2003
+@@ -103,6 +103,9 @@
+ uschar *tls_verify_hosts = NULL;
+ #endif
+
++#ifdef DLOPEN_LOCAL_SCAN
++uschar *local_scan_path = NULL;
++#endif
+
+ /* Input-reading functions for messages, so we can use special ones for
+ incoming TCP/IP. The defaults use stdin. We never need these for any
+diff -urN exim-4.14-0/src/globals.h exim-4.14-1/src/globals.h
+--- exim-4.14-0/src/globals.h Tue Mar 11 04:20:20 2003
++++ exim-4.14-1/src/globals.h Sun Mar 23 15:34:15 2003
+@@ -67,6 +67,9 @@
+ extern uschar *tls_verify_hosts; /* Mandatory client verification */
+ #endif
+
++#ifdef DLOPEN_LOCAL_SCAN
++extern uschar *local_scan_path; /* Path to local_scan() library */
++#endif
+
+ /* Input-reading functions for messages, so we can use special ones for
+ incoming TCP/IP. */
+diff -urN exim-4.14-0/src/local_scan.c exim-4.14-1/src/local_scan.c
+--- exim-4.14-0/src/local_scan.c Tue Mar 11 04:20:20 2003
++++ exim-4.14-1/src/local_scan.c Sun Mar 23 15:34:15 2003
+@@ -5,60 +5,131 @@
+ /* Copyright (c) University of Cambridge 1995 - 2003 */
+ /* See the file NOTICE for conditions of use and distribution. */
+
++#include "exim.h"
+
+-/******************************************************************************
+-This file contains a template local_scan() function that just returns ACCEPT.
+-If you want to implement your own version, you should copy this file to, say
+-Local/local_scan.c, and edit the copy. To use your version instead of the
+-default, you must set
+-
+-LOCAL_SCAN_SOURCE=Local/local_scan.c
+-
+-in your Local/Makefile. This makes it easy to copy your version for use with
+-subsequent Exim releases.
+-
+-For a full description of the API to this function, see the Exim specification.
+-******************************************************************************/
+-
+-
+-/* This is the only Exim header that you should include. The effect of
+-including any other Exim header is not defined, and may change from release to
+-release. Use only the documented interface! */
+-
+-#include "local_scan.h"
+-
+-
+-/* This is a "do-nothing" version of a local_scan() function. The arguments
+-are:
+-
+- fd The file descriptor of the open -D file, which contains the
+- body of the message. The file is open for reading and
+- writing, but modifying it is dangerous and not recommended.
+-
+- return_text A pointer to an unsigned char* variable which you can set in
+- order to return a text string. It is initialized to NULL.
+-
+-The return values of this function are:
+-
+- LOCAL_SCAN_ACCEPT
+- The message is to be accepted. The return_text argument is
+- saved in $local_scan_data.
+-
+- LOCAL_SCAN_REJECT
+- The message is to be rejected. The returned text is used
+- in the rejection message.
+-
+- LOCAL_SCAN_TEMPREJECT
+- This specifies a temporary rejection. The returned text
+- is used in the rejection message.
+-*/
++#ifdef DLOPEN_LOCAL_SCAN
++#include <dlfcn.h>
++static int (*local_scan_fn)(int fd, uschar **return_text) = NULL;
++static int load_local_scan_library(void);
++#endif
+
+ int
+ local_scan(int fd, uschar **return_text)
+ {
+ fd = fd; /* Keep picky compilers happy */
+ return_text = return_text;
+-return LOCAL_SCAN_ACCEPT;
++#ifdef DLOPEN_LOCAL_SCAN
++/* local_scan_path is defined AND not the empty string */
++if (local_scan_path && *local_scan_path)
++ {
++ if (!local_scan_fn)
++ {
++ if (!load_local_scan_library())
++ {
++ char *base_msg , *error_msg , *final_msg ;
++ int final_length = -1 ;
++
++ base_msg=US"Local configuration error - local_scan() library failure\n";
++ error_msg = dlerror() ;
++
++ final_length = strlen(base_msg) + strlen(error_msg) + 1 ;
++ final_msg = (char*)malloc( final_length*sizeof(char) ) ;
++ *final_msg = '\0' ;
++
++ strcat( final_msg , base_msg ) ;
++ strcat( final_msg , error_msg ) ;
++
++ *return_text = final_msg ;
++ return LOCAL_SCAN_TEMPREJECT;
++ }
++ }
++ return local_scan_fn(fd, return_text);
++ }
++else
++#endif
++ return LOCAL_SCAN_ACCEPT;
++}
++
++#ifdef DLOPEN_LOCAL_SCAN
++
++static int load_local_scan_library(void)
++{
++/* No point in keeping local_scan_lib since we'll never dlclose() anyway */
++void *local_scan_lib = NULL;
++int (*local_scan_version_fn)(void);
++int vers_maj;
++int vers_min;
++
++local_scan_lib = dlopen(local_scan_path, RTLD_NOW);
++if (!local_scan_lib)
++ {
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library open failed - "
++ "message temporarily rejected");
++ return FALSE;
++ }
++
++local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_major");
++if (!local_scan_version_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan_version_major() function - message temporarily rejected");
++ return FALSE;
++ }
++
++/* The major number is increased when the ABI is changed in a non
++ backward compatible way. */
++vers_maj = local_scan_version_fn();
++
++local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_minor");
++if (!local_scan_version_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan_version_minor() function - message temporarily rejected");
++ return FALSE;
++ }
++
++/* The minor number is increased each time a new feature is added (in a
++ way that doesn't break backward compatibility) -- Marc */
++vers_min = local_scan_version_fn();
++
++
++if (vers_maj != LOCAL_SCAN_ABI_VERSION_MAJOR)
++ {
++ dlclose(local_scan_lib);
++ local_scan_lib = NULL;
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible major"
++ "version number, you need to recompile your module for this version"
++ "of exim (The module was compiled for version %d.%d and this exim provides"
++ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
++ LOCAL_SCAN_ABI_VERSION_MINOR);
++ return FALSE;
++ }
++else if (vers_min > LOCAL_SCAN_ABI_VERSION_MINOR)
++ {
++ dlclose(local_scan_lib);
++ local_scan_lib = NULL;
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible minor"
++ "version number, you need to recompile your module for this version"
++ "of exim (The module was compiled for version %d.%d and this exim provides"
++ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
++ LOCAL_SCAN_ABI_VERSION_MINOR);
++ return FALSE;
++ }
++
++local_scan_fn = dlsym(local_scan_lib, "local_scan");
++if (!local_scan_fn)
++ {
++ dlclose(local_scan_lib);
++ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
++ "local_scan() function - message temporarily rejected");
++ return FALSE;
++ }
++
++return TRUE;
+ }
++
++#endif /* DLOPEN_LOCAL_SCAN */
+
+ /* End of local_scan.c */
+diff -urN exim-4.14-0/src/local_scan.h exim-4.14-1/src/local_scan.h
+--- exim-4.14-0/src/local_scan.h Tue Mar 11 04:20:20 2003
++++ exim-4.14-1/src/local_scan.h Sun Mar 23 15:34:57 2003
+@@ -71,6 +71,15 @@
+
+ #define SPOOL_DATA_START_OFFSET (MESSAGE_ID_LENGTH+3)
+
++/* local_scan() ABI version number for dynamic libraries
++ The major number is increased when the ABI is changed in a non
++ backward compatible way.
++ The minor number is increased each time a new feature is added (in a
++ way that doesn't break backward compatibility) -- Marc */
++#define LOCAL_SCAN_ABI_VERSION_MAJOR 1
++#define LOCAL_SCAN_ABI_VERSION_MINOR 0
++#define LOCAL_SCAN_ABI_VERSION \
++ LOCAL_SCAN_ABI_VERSION_MAJOR.LOCAL_SCAN_ABI_VERSION_MINOR
+
+ /* Structure definitions that are documented as visible in the function. */
+
+diff -urN exim-4.14-0/src/readconf.c exim-4.14-1/src/readconf.c
+--- exim-4.14-0/src/readconf.c Tue Mar 11 04:20:22 2003
++++ exim-4.14-1/src/readconf.c Sun Mar 23 15:34:15 2003
+@@ -182,6 +182,9 @@
+ { "local_from_prefix", opt_stringptr, &local_from_prefix },
+ { "local_from_suffix", opt_stringptr, &local_from_suffix },
+ { "local_interfaces", opt_stringptr, &local_interfaces },
++#ifdef DLOPEN_LOCAL_SCAN
++ { "local_scan_path", opt_stringptr, &local_scan_path },
++#endif
+ { "local_scan_timeout", opt_time, &local_scan_timeout },
+ { "local_sender_retain", opt_bool, &local_sender_retain },
+ { "localhost_number", opt_stringptr, &host_number_string },
Index: 4.2.1-12/Acknowledgements.html
===================================================================
--- 4.2.1-12/Acknowledgements.html (nonexistent)
+++ 4.2.1-12/Acknowledgements.html (revision 61)
@@ -0,0 +1,119 @@
+While I wrote SA-Exim after realizing that I didn't want to accept Spam in the
+first place, this package would not have been put together without the help
+and contributions of the following people:
+
+
+<ul>
+<li>Philip Hazel<BR>
+ We wouldn't have exim without him :-)
+
+<li>Justin Mason, Craig R Hughes, Dan Quinlan, and the rest of the SpamAssassin
+ crew<BR>
+
+<li>Derrick 'dman' Hudson<BR>
+ Early adopter, feedback, ideas, first integration with localscan_dlopen
+
+<li>David Woodhouse<BR>
+ Excellent original localscan_dlopen patch for exim 4
+ SIGCHLD patch (was set to ignore by exim)
+
+<li>Norm<BR>
+ Build patches and trailing slash problem for mkdir on netbsd
+
+<li>Patrice Fournier<BR>
+ Several suggestions, including adding the X-SA-Exim-Scanned header
+
+<li>Peter N Lewis<BR>
+ Spotted a buglet in lseek call
+
+<li>Robert Strickler<BR>
+ Suggested that I add teergrube support
+
+<li>Tim Jackson<BR>
+ Narrowed the problem with SA Exim 2.1 to a hang when we feed a message
+ that's too big to spamc and did a lot of research on the bug
+
+<li>Brian Kendig<BR>
+ Suggested the functionality behind X-SA-Exim-Rcpt-To:
+ Noted and requested logging changes
+
+<li>Paul Matthews<BR>
+ Reported string length problem with X-SA-Exim-Rcpt-To:
+
+<li>Chad Leigh<BR>
+ Reported that SA-Exim doesn't delete a X-Spam-Flag header in the original
+ mail if the local config decides that the mail isn't spam
+
+<li>Martin Balvers<BR>
+ Reported that
+ SA: Action: teergrubed sender until full configured duration
+ logging wasn't consistent.
+ Author of http://nossie.addicts.nl/projects/sa-exim-stats/
+
+<li>Andreas Metzler<BR>
+ Has provided invaluable help by being the main maintainer of the exim4
+ debian package and doing most of the work for the sa-exim package, while
+ patiently helping me with my debian build questions
+
+<li>Richard Lithvall<BR>
+ Added the much requested SARewriteBody option for SA 2.50's report_safe
+ Also added SAPrependArchiveWithFrom option<BR>
+ Also added SAspamcSockPath for SA 2.60 and better
+
+<li>Justin F. Knotzke<BR>
+ Reported that Dec 31st 1969 isn't a good idea and upsets some MUAs like mutt
+
+<li>Norihisa Washitake<BR>
+ Pointed out that I should be using date -R to override foreign locales
+
+<li>Chirik<BR>
+ Made suggestions on increasing logging consistency
+ Gave example on how you can trigger mail scans without using headers
+ (using internal exim acl variables)
+
+<li>Ross Boylan<BR>
+ Suggestions for documentation tweaks
+
+<li>Sander Smeenk<BR>
+ Made sa-exim show up in Debian. Yeah! :)
+ Major doc diffs
+
+<li>Stéphane MANHES<BR>
+ Pointed out that greylisting requires X-SA-Exim-Rcpt-To:
+
+<li>John Horne<BR>
+ Reported crash on discard, due to the number of recipients being 0
+
+<li>Adam D. Barratt<BR>
+ Found the problem with sa-exim's indirect use of printf and causing a crash
+ in exim on 64 bit architectures, and gave a detailed explanation on what
+ happened and how to fix it
+
+<li>Jeffrey D. Carter<BR>
+ Suggested strchr instead of index for easier compilation.
+
+<li>Danilo Lotina F. &amp; Others<BR>
+ Suggested adding a destination host for spamc (I added a port too)
+
+<li>Cliff Hones<BR>
+ Reported that From mbox line was in an incorrect format
+
+<li>Jason John Schwarz<BR>
+ Reported compile problem inside the exim tree (i.e. without local_scan)
+
+<li>Kristopher Austin<BR>
+ Initial port of the SA patch to an SA 3.0 plugin
+
+<li>Adam Tilghman<BR>
+ Pointed out that I shouldn't be rewriting Content-Type headers if we don't
+ rewrite the body (and defang_mime is dead now)
+
+<li>Mark Lawrence<BR>
+ He is the author of the greylistclean cron job
+
+<li>Chris Morris<BR>
+ Reported the ealier tuplet deletion cronjob in shell as insecure
+
+<li>Your name here<BR>
+ If you contribute or if you did and I forgot your name (sorry, let me know)
+</ul>
Index: 4.2.1-12/contrib/sa-exim-stats.txt
===================================================================
--- 4.2.1-12/contrib/sa-exim-stats.txt (nonexistent)
+++ 4.2.1-12/contrib/sa-exim-stats.txt (revision 61)
@@ -0,0 +1,3 @@
+See this page:
+
+http://nossie.addicts.nl/projects/sa-exim-stats/
Index: 4.2.1-12/contrib/spam_resend.txt
===================================================================
--- 4.2.1-12/contrib/spam_resend.txt (nonexistent)
+++ 4.2.1-12/contrib/spam_resend.txt (revision 61)
@@ -0,0 +1,70 @@
+From: Richard Lithvall <richard@lithvall.nu>
+Date: Mon, 24 Mar 2003 16:31:40 +0100
+To: sa-exim@lists.merlins.org
+Subject: [SA-exim] Rejecting spam at SMTP but forward it to its recipients
+
+Hi list members!
+
+As the lazy postmaster I am I don't want to check every mail caught by
+SA for false positives but I really want to reject the damn spam at SMTP
+time.
+Therefore I wrote this little perl hack delegating this responsibilty to
+my users (they all use exim filters to file mail tagged as spam into a
+Junk folder).
+
+It works as follows.
+- Configure SA-exim to save rejected mail into a directory
+- Run the perl script attatched below from cron, let's say, once an hour
+(as user mail or whoever that runs your exim)
+- Inform your users how things work and their responsibilites to check
+for false positives.
+
+Please comment this script/hack and I'd really love to get some English
+spelling/grammar check as well :-)
+
+/Richard
+
+
+#!/usr/bin/perl
+$dir = "/var/spool/exim4/SApermrejectsave/new";
+foreach $mail (<$dir/*>) {
+ if(-f $mail){
+ open(MAIL, $mail);
+# print "Working on: " . $mail . "\n";
+ $from = <MAIL>;
+ $from =~ s/^From\s(.+?)\s.+\n/$1/;
+ while (<MAIL>){
+ if(/^X-SA-Exim-Rcpt-To:\s(.+)/){
+ @rcpts = split(/, /, $1);
+ last;
+ }
+ if(/^$/){
+ last;
+ }
+ }
+ open(BSMTP, "| /usr/sbin/exim4 -bS");
+ print BSMTP "mail from:<" . $from . ">\n";
+ foreach $rcpt (@rcpts){
+ print BSMTP "rcpt to:<" . $rcpt . ">\n";
+ }
+ print BSMTP "data\n";
+ print BSMTP "X-Spam-Notice: This mail was rejected
+during reception due to heuristic check marked it as spam,\n";
+ print BSMTP "\tbut forwarded to You for checking for
+false positives.\n";
+ seek(MAIL, 0, 0);
+ $throw_away_first_from_line = <MAIL>;
+ while (<MAIL>){
+ if(/^\./){
+ print BSMTP ".";
+ }
+ print BSMTP;
+ }
+ close(MAIL);
+ print BSMTP ".\n";
+ print BSMTP "quit\n";
+ close(BSMTP);
+ unlink($mail);
+ }
+}
+
Index: 4.2.1-12/SA-greylisting-2.4x.diff
===================================================================
--- 4.2.1-12/SA-greylisting-2.4x.diff (nonexistent)
+++ 4.2.1-12/SA-greylisting-2.4x.diff (revision 61)
@@ -0,0 +1,264 @@
+Note, this patch is unmaintained. It is not supposed to be functional or
+safe anymore, but I'm leaving it behind if you'd like to backport the 2.6
+patch to SA 2.4 (much easier than with 2.6)
+
+-- Marc
+
+
+diff -urN SpamAssassin.orig/Conf.pm SpamAssassin/Conf.pm
+--- SpamAssassin.orig/Conf.pm Mon Jul 14 11:57:40 2003
++++ SpamAssassin/Conf.pm Sun Feb 22 17:17:03 2004
+@@ -66,6 +66,9 @@
+ use constant TYPE_RBL_EVALS => 0x0013;
+ # UNUSED => 0x0014
+ use constant TYPE_RBL_RES_EVALS => 0x0015;
++# Need to reserve a number with the SA folks (needs to be odd as it is an
++# eval test)
++use constant TYPE_RES_EVALS => 0x0021;
+
+ $VERSION = 'bogus'; # avoid CPAN.pm picking up version strings later
+
+@@ -1507,6 +1510,9 @@
+ if (/^header\s+(\S+)\s+rblreseval:(.*)$/) {
+ $self->add_test ($1, $2, TYPE_RBL_RES_EVALS); next;
+ }
++ if (/^header\s+(\S+)\s+reseval:(.*)$/) {
++ $self->add_test ($1, $2, TYPE_RES_EVALS); next;
++ }
+ if (/^header\s+(\S+)\s+eval:(.*)$/) {
+ my ($name,$rule) = ($1, $2);
+ # Backward compatibility with old rule names -- Marc
+@@ -2096,6 +2102,9 @@
+ }
+ elsif ($type == TYPE_RBL_RES_EVALS) {
+ $self->{rbl_res_evals}->{$name} = \@args;
++ }
++ elsif ($type == TYPE_RES_EVALS) {
++ $self->{res_evals}->{$name} = \@args;
+ }
+ elsif ($type == TYPE_RAWBODY_EVALS) {
+ $self->{rawbody_evals}->{$name} = \@args;
+diff -urN SpamAssassin.orig/EvalTests.pm SpamAssassin/EvalTests.pm
+--- SpamAssassin.orig/EvalTests.pm Mon Feb 23 23:28:37 2004
++++ SpamAssassin/EvalTests.pm Tue Feb 24 21:34:36 2004
+@@ -1863,6 +1863,195 @@
+ return 0;
+ }
+
++
++# This was originally written to implement greylisting in SA-Exim, although
++# I have tried to make it more general and allow for reuse in other MTAs
++# (although they will need to
++# 1) be running SA at SMTP time
++# 2) Provide the list of rcpt to and env from in some headers for SA to read
++# 3) Provide the IP of the connecting host )
++#
++# This rule should get a negative score so that if we've already seen the
++# greylisting tuplet before, we lower the score, which hopefully brings us from
++# a tempreject to an accept (at least that's how sa-exim does it)
++# -- Marc <marc_soft@merlins.org> 2004/01/19
++
++sub greylisting {
++ # db/file/dir / pointer type / how many secs to greylist after 1st connection
++ # SA score after which we don't bother running / SMTP time data header names
++ my ($self, $dirorfileordb, $method, $greylisttime, $dontcheckscore,
++ $connectiphdr, $envfromhdr, $rcpttohdr) = @_;
++ my $dirorfile = shift @_;
++
++ my $connectip;
++ my $envfrom;
++ my $rcptto;
++ my @rcptto;
++ my $iswhitelisted=0;
++ my $err;
++ my $mesgid = $self->get ('Message-Id')."\n";
++ my $tuplet;
++
++ # No newlines, thank you (yes, you need this twice apparently)
++ chomp ($mesgid);
++ chomp ($mesgid);
++ $mesgid =~ s/\012/|/g;
++
++ # For stuff that we know is spam, don't greylist the host
++ # (that might help later spam with a lower score to come in)
++ if ($self->{hits} >= $dontcheckscore)
++ {
++ #warn "debug: skipping greylisting on $mesgid, since score is already ".$self->{hits}." and you configured greylisting to not bother with anything above $dontcheckscore\n";
++ return 0;
++ }
++
++
++ if (not $connectip = $self->get($connectiphdr))
++ {
++ warn "Couldn't get Connecting IP header $connectiphdr for message $mesgid, skipping greylisting call\n";
++ return 0;
++ }
++ chomp($connectip);
++ # Clean up input (for security, if you use files/dirs)
++ $connectip =~ s#/#-#g;
++
++ if (not $envfrom = $self->get($envfromhdr))
++ {
++ warn "Couldn't get Envelope From header $envfromhdr for message $mesgid, skipping greylisting call\n";
++ return 0;
++ }
++ chomp($envfrom);
++ # Clean up input (for security, if you use files/dirs)
++ $envfrom =~ s#/#-#g;
++
++ if (not $rcptto = $self->get($rcpttohdr))
++ {
++ warn "Couldn't get Rcpt To header $rcpttohdr for message $mesgid, skipping greylisting call\n";
++ return 0;
++ }
++ chomp($rcptto);
++ # Clean up input (for security, if you use files/dirs)
++ $rcptto =~ s#/#-#g;
++ @rcptto = split(/, /, $rcptto);
++
++ umask 0007;
++
++ foreach $rcptto (@rcptto)
++ {
++ my $ipdir = "$dirorfileordb/$connectip";
++ my $tupletdir = "$ipdir/$envfrom";
++
++ $tuplet = "$tupletdir/$rcptto";
++
++ # The dir method is easy to fiddle with and expire records in (with
++ # a find | rm) but it's probably more I/O extensive than a real DB
++ # and suffers from directory size problems if a specific IP is sending
++ # generating tens of thousands of tuplets. -- Marc
++ # That said, I prefer formats I can easily tinker with, and not having to
++ # worry about buggy locking and so forth
++ if ($method eq "dir")
++ {
++ # make directory whether it's there or not (faster than test and set)
++ mkdir $ipdir;
++ mkdir $tupletdir;
++
++ if (not -e $tuplet)
++ {
++ # If the tuplets aren't there, we create them and continue in
++ # case there are other ones (one of them might be whitelisted already)
++ $err="creating $tuplet";
++ open (TUPLET, ">$tuplet") or goto greylisterror;
++ print TUPLET time."\n";
++ print TUPLET "Status: Greylisted\n";
++ print TUPLET "Last Message-Id: $mesgid\n";
++ print TUPLET "Whitelisted Count: 0\n";
++ print TUPLET "Query Count: 1\n";
++ $err="closing first-written $tuplet";
++ close TUPLET or goto greylisterror;
++ }
++ else
++ {
++ my $time;
++ my $status;
++ my $whitelistcount;
++ my $querycount;
++
++ # Take into account race condition of expiring deletes and us running
++ $err="reading $tuplet";
++ open (TUPLET, "<$tuplet") or goto greylisterror;
++ $err="Couldn't read time";
++ $time=<TUPLET> or goto greylisterror;
++ chomp ($time);
++
++ $err="Couldn't read status";
++ $status=<TUPLET> or goto greylisterror;
++ chomp ($status);
++ $err="Couldn't extract Status from $status";
++ $status =~ s/^Status: // or goto greylisterror;
++
++ # Skip Mesg-Id
++ $err="Couldn't skip Mesg-Id";
++ $_=<TUPLET> or goto greylisterror;
++
++ $err="Couldn't read whitelistcount";
++ $whitelistcount=<TUPLET> or goto greylisterror;
++ chomp ($whitelistcount);
++ $err="Couldn't extract Whitelisted Count from $whitelistcount";
++ $whitelistcount =~ s/^Whitelisted Count: // or goto greylisterror;
++
++ $err="Couldn't read querycount";
++ $querycount=<TUPLET> or goto greylisterror;
++ chomp ($querycount);
++ $err="Couldn't extract Query Count from $querycount";
++ $querycount =~ s/^Query Count: // or goto greylisterror;
++ close (TUPLET);
++
++ $querycount++;
++ if ((time - $time) > $greylisttime)
++ {
++ $status="Whitelisted";
++ $whitelistcount++;
++ }
++
++ $err="re-writing $tuplet";
++ open (TUPLET, ">$tuplet") or goto greylisterror;
++ print TUPLET "$time\n";
++ print TUPLET "Status: $status\n";
++ print TUPLET "Last Message-Id: $mesgid\n";
++ print TUPLET "Whitelisted Count: $whitelistcount\n";
++ print TUPLET "Query Count: $querycount\n";
++ $err="closing re-written $tuplet";
++ close TUPLET or goto greylisterror;
++
++ # We continue processing the other recipients, to setup or
++ # update their counters
++ if ($status="Whitelisted")
++ {
++ $iswhitelisted=1;
++ }
++ }
++ }
++ elsif ($method eq "file")
++ {
++ warn "codeme\n";
++ }
++ elsif ($method eq "db")
++ {
++ warn "codeme\n";
++ }
++ }
++
++ return $iswhitelisted;
++
++ greylisterror:
++ warn "Reached greylisterror: $err / $!";
++ # delete tuplet since it apparently had issues but don't check for errors
++ # in case it was a permission denied on write
++ unlink ($tuplet);
++ return $iswhitelisted;
++}
++
++
+ ###########################################################################
+ # BODY TESTS:
+ ###########################################################################
+diff -urN SpamAssassin.orig/PerMsgStatus.pm SpamAssassin/PerMsgStatus.pm
+--- SpamAssassin.orig/PerMsgStatus.pm Mon May 12 12:15:33 2003
++++ SpamAssassin/PerMsgStatus.pm Sun Feb 22 17:47:11 2004
+@@ -189,6 +189,9 @@
+
+ # add points from Bayes, before adjusting the AWL
+ $self->{hits} += $self->{learned_hits};
++
++ # Now, we can run rules that have to run last
++ $self->do_res_eval_tests();
+
+ # Do AWL tests last, since these need the score to have already been
+ # calculated
+@@ -1866,6 +1869,11 @@
+ my ($self) = @_;
+ # run_rbl_eval_tests doesn't process check returns unless you set needresult
+ $self->run_rbl_eval_tests ($self->{conf}->{rbl_res_evals}, 1);
++}
++
++sub do_res_eval_tests {
++ my ($self) = @_;
++ $self->run_eval_tests ($self->{conf}->{res_evals}, '');
+ }
+
+ sub do_head_eval_tests {
Index: 4.2.1-12/TODO
===================================================================
--- 4.2.1-12/TODO (nonexistent)
+++ 4.2.1-12/TODO (revision 61)
@@ -0,0 +1 @@
+Do per-user SA runs with the exiscan 45x trick
Index: 4.2.1-12/greylistclean
===================================================================
--- 4.2.1-12/greylistclean (nonexistent)
+++ 4.2.1-12/greylistclean (revision 61)
@@ -0,0 +1,177 @@
+#!/usr/bin/perl
+# ----------------------------------------------------------------------
+# Copyright (C) 2005 Mark Lawrence <nomad@null.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# ----------------------------------------------------------------------
+# greylistclean - remove expired SA-Exim greylist entries from the filesystem.
+#
+# This is basically a perl implementation of the old shell commands that
+# used to be shipped with sa-exim, combined with simple syslog reporting.
+# This perl script cleans old tuplets and directories in
+# /var/spool/sa-exim/tuplets/
+#
+# You can call this script with '-v' to see what files and
+# directories are being removed (sent to STDERR).
+# Otherwise during normal operation there is no output.
+#
+# To use this in production you either:
+# 1. Copy this file to your cron.hourly directory if you accept the risk of
+# running this script as root (it is uncessary)
+# or
+# 2. Copy this file to /usr/local/bin and create a crontab entry
+# that looks something like the following (this works on Debian):
+#
+# 33 * * * * debian-exim /usr/local/bin/greylistclean
+# ^^^^^^^^^^^
+# (a)
+# (a) find out under which user tuplets are created, it could be mail, exim
+# or something else depending on your system ("debian-exim" on debian)
+#
+# Changelog
+# ---------
+# 2005-02-14 Original version. Mark Lawrence <nomad@null.net>
+# 2005-02-21 Added example cron entry comment. Mark Lawrence <nomad@null.net>
+# 2006-01-09 Added a few comments on how to run without root, inclusion in
+# sa-exim / verbose is -v ( -d would be debug )
+#
+# ----------------------------------------------------------------------
+use strict;
+use warnings;
+use Sys::Syslog;
+use File::Find;
+use File::stat;
+
+my $tuplet_dir = '/var/spool/sa-exim/tuplets';
+
+my $max_grey_age = 60*60*24*2; # seconds to keep greylisted entries (2 days)
+my $max_age = 60*60*24*14; # seconds to keep all entries (14 days)
+
+my $tcount = 0; # total number of tuplets
+my $rm_tcount = 0; # number of tuplets removed
+
+my $dircount = 0; # total number of directories
+my $rm_dircount = 0; # number of directories removed
+
+my @empty_dirs = (); # list of empty directories
+
+my $verbose = 0;
+my $now = time();
+
+
+if (@ARGV == 1 and $ARGV[0] eq '-v') {
+ $verbose = 1;
+ print STDERR "$0 running at $now\n"
+}
+
+
+#
+# Open the reporting channel
+#
+openlog('sa-exim', 'pid,ndelay', 'mail');
+
+#
+# Process the tuplets
+#
+find({wanted => \&prune, postprocess => \&dircheck}, $tuplet_dir);
+
+syslog('info', 'Removed %d of %d greylist tuplets in %d seconds', $rm_tcount,
+ $tcount, time() - $now);
+
+#
+# Remove empty directories found by dircheck()
+#
+$now = time();
+
+foreach my $dir (@empty_dirs) {
+ rmdir $dir && $rm_dircount++;
+ $verbose && print STDERR "removed empty directory $dir\n";
+}
+
+syslog('info', 'Removed %d of %d greylist directories in %d seconds',
+ $rm_dircount, $dircount, time() - $now);
+
+closelog();
+exit;
+
+
+
+#
+# Called from File::Find::find() function with $_ set to filename/directory.
+# Search for the line 'Status: Greylisted' in files modified more than
+# $max_grey_age seconds ago and remove the files that contain it.
+# Remove any entry that is older than $max_age seconds ago.
+#
+sub prune {
+ return if (-d $_); # we don't do directories
+ $tcount++;
+
+ my $file = $_;
+ my $sb = stat($file);
+ my $age = $now - $sb->mtime;
+
+ #
+ # Remove all old entries (older than $max_age)
+ #
+ if ($age > $max_age) {
+ $verbose && print STDERR 'removing old entry ',
+ "${File::Find::dir}/$file (age: ",
+ $now - $sb->mtime, " seconds)\n";
+ unlink($file);
+ $rm_tcount++;
+ return;
+ }
+
+ #
+ # Do nothing if not old enough to expire
+ #
+ return if ($age < $max_grey_age);
+
+ #
+ # Check if this tuplet has been 'greylisted'. Use the 3 argument
+ # form of 'open', because a lot of these files have funny characters
+ # in their names.
+ #
+ if (!open(FH, '<', $file)) {
+ print STDERR "Could not open ${File::Find::name}: $!\n";
+ return;
+ }
+
+ while (my $line = <FH>) {
+ if ($line =~ /^Status: Greylisted$/) {
+ $verbose && print STDERR 'removing greylisted ',
+ "${File::Find::dir}/$file (age: ",
+ $now - $sb->mtime, " seconds)\n";
+ unlink($file);
+ $rm_tcount++;
+ last;
+ }
+ }
+
+ close FH;
+}
+
+
+#
+# Called from File::Find::find() function when all entries in a directory
+# have been processed. We check if there are any files left in the directory
+# and if not then add it to a list for later deletion
+#
+sub dircheck {
+ return if ($File::Find::dir eq $tuplet_dir); # don't check top dir.
+ $dircount++;
+
+ #
+ # Check if directory is empty and add to $empty_dirs hash
+ #
+ if (opendir(DIR, $File::Find::dir)) {
+ my $files = grep {!/^\./} readdir(DIR);
+ if ($files == 0) {
+ push(@empty_dirs, $File::Find::dir);
+ }
+ closedir(DIR);
+ }
+}
/4.2.1-12/greylistclean
Property changes:
Added: svn:executable
Index: 4.2.1-12/INSTALL
===================================================================
--- 4.2.1-12/INSTALL (nonexistent)
+++ 4.2.1-12/INSTALL (revision 61)
@@ -0,0 +1,100 @@
+READ THIS FIRST
+---------------
+If you try to build with 'make' without editing the makefile for sa-exim to
+see the exim source, and if you haven't patched your exim source with
+localscan_dlopen.patch, sa-exim will not build.
+This is normal, see the BUILDING section below
+
+This version of sa-exim now requires at least exim 4.11
+
+
+
+
+BUILDING
+--------
+The code can be compiled in two ways:
+
+0) Do not set LOCAL_SCAN_HAS_OPTIONS=yes in exim's Makefile. Leave the
+ default which is disabled.
+
+1) Unpack exim 4.11 or better, and overwrite src/local_scan.c with
+ sa-exim.c.
+ In the sa-exim distribution directory, type make sa-exim.h, and copy
+ it in the same place than sa-exim.c.
+ Rebuild exim, and you're done.
+ Note that if you do this, you are responsible for modifying variables
+ in sa-exim.c that would normally have been modified by the Makefile.
+
+ This method might seem simpler, but it requires that you rebuild exim every
+ time you upgrade sa-exim.
+
+2) The better solution is to patch exim with localscan_dlopen.patch originally
+ from David Woodhouse (provided in this archive), and rebuild exim.
+ Here are details on how to patch exim if yours needs it (at least debian's
+ exim4 is prepatched, yours may be too).
+ Choose the patch for your exim version (Philip included the portion that
+ sets LOCAL_SCAN_ABI_VERSION_MAJOR and LOCAL_SCAN_ABI_VERSION_MINOR in exim
+ 4.20)
+ - localscan_dlopen_exim_4.20_or_better.patch
+ - localscan_dlopen_up_to_4.14.patch
+
+
+ What you gain from doing this is that sa-exim, or another local_scan module
+ can be plugged into exim without rebuilding exim itself (here too you need
+ exim 4.11 or better)
+
+ To build, you can edit EXIM_SRC in the Makefile and build sa-exim-x.y.so,
+ or I have also recently modified the build environment so that you can
+ now build sa-exim without having the exim sources.
+ You can look in eximinc/version to see which source I included. While this
+ should work for the forseable future, the exim local_scan API might change
+ one day and not building against the current exim sources could cause issues
+ (hopefully, at worst it will prevent sa-exim from using better functions in
+ newer versions of the local_scan API).
+ To be really safe, I modified the localscan_dlopen patch to include a
+ minor and major version number for the API. Philip has agreed to including
+ the piece of the patch that says which version of the API exim is using,
+ so it will be obvious in the future whether exim becomes potentially
+ incompatible with an older version of sa-exim. Note that when Philip adds
+ this small portion of the patch, you will have a resulting conflict if
+ you try to apply it again. This is obviously normal, just remove it :-)
+
+ Once you're done building, you can copy sa-exim-x.y.so and optionally the
+ dummy/test accept.so in /usr/lib/exim4/local_scan/, and add this to your
+ exim4.conf (at the beginning of the file)
+ #local_scan_path = /usr/lib/exim4/local_scan/accept.so
+ local_scan_path = /usr/lib/exim4/local_scan/sa-exim.so
+
+ If you are a package builder, note that you don't actually have
+ to edit the values in the Makefile, you can override them as such:
+ make SACONF=/etc/mail/sa-exim.conf LDFLAGS="-shared -fPIC"
+
+
+The following is mostly obsolete, but left here for info purposes
+-----------------------------------------------------------------
+I would also recommend to edit exim/src/config.h.defaults as such:
+#define STRING_SPRINTF_BUFFER_SIZE 32768
+The default value is a bit too small for some of the strings that we need to
+expand from SA.
+That said, I found out that exim then complaints that the headers
+it tries to add are too big even after I set "uschar buffer[32768];" in
+src/header.c.
+As a result, I haven't quite found out how to deal with more than 8KB worth
+of SpamAssassin headers, but it may not be a huge deal, 8KB headers are too
+long anyway.
+I asked the SA guys not to output such huge headers and I wrote a patch
+to disable one of the "features" that outputs such huge headers.
+See: http://bugzilla.spamassassin.org/showattachment.cgi?attach_id=195
+This is included and turned on by default in Spamassassin 2.40 and later.
+
+
+INSTALL
+-------
+Copy sa-exim.conf to /etc/exim4 (or whatever you set SACONF to),
+and make sure to read it and edit the values to suit your environment.
+So that you don't make any mistakes, SAEximRunCond is turned off by default.
+This should force you to scan the docs before potentially shooting yourself
+in the foot :)
+
+See README for options
+
Index: 4.2.1-12/SA-greylisting-2.6.diff
===================================================================
--- 4.2.1-12/SA-greylisting-2.6.diff (nonexistent)
+++ 4.2.1-12/SA-greylisting-2.6.diff (revision 61)
@@ -0,0 +1,304 @@
+diff -urN SpamAssassin.orig/Conf.pm SpamAssassin/Conf.pm
+--- SpamAssassin.orig/Conf.pm Mon Dec 15 22:41:57 2003
++++ SpamAssassin/Conf.pm Sun Feb 29 17:42:58 2004
+@@ -107,6 +107,10 @@
+ use constant TYPE_URI_EVALS => 0x0011;
+ use constant TYPE_META_TESTS => 0x0012;
+ use constant TYPE_RBL_EVALS => 0x0013;
++# Need to reserve a number with the SA folks (needs to be odd as it is an
++# eval test)
++use constant TYPE_RES_EVALS => 0x0021;
++
+
+ $VERSION = 'bogus'; # avoid CPAN.pm picking up version strings later
+
+@@ -2000,12 +2004,15 @@
+
+ =cut
+
+- if (/^header\s+(\S+)\s+(?:rbl)?eval:(.*)$/) {
++ if (/^header\s+(\S+)\s+(?:rbl|res)?eval:(.*)$/) {
+ my ($name, $fn) = ($1, $2);
+
+ if ($fn =~ /^check_rbl/) {
+ $self->add_test ($name, $fn, TYPE_RBL_EVALS);
+ }
++ elsif (/^header\s+(\S+)\s+reseval:(.*)$/) {
++ $self->add_test ($name, $fn, TYPE_RES_EVALS);
++ }
+ else {
+ $self->add_test ($name, $fn, TYPE_HEAD_EVALS);
+ }
+@@ -2603,6 +2610,9 @@
+ }
+ elsif ($type == TYPE_RBL_EVALS) {
+ $self->{rbl_evals}->{$name} = \@args;
++ }
++ elsif ($type == TYPE_RES_EVALS) {
++ $self->{res_evals}->{$name} = \@args;
+ }
+ elsif ($type == TYPE_RAWBODY_EVALS) {
+ $self->{rawbody_evals}->{$name} = \@args;
+diff -urN SpamAssassin.orig/EvalTests.pm SpamAssassin/EvalTests.pm
+--- SpamAssassin.orig/EvalTests.pm Sat Jan 17 15:56:08 2004
++++ SpamAssassin/EvalTests.pm Sun Aug 15 15:47:22 2004
+@@ -1941,6 +1941,234 @@
+ return $self->{habeas_swe};
+ }
+
++
++# This was originally written to implement greylisting in SA-Exim, although
++# I have tried to make it more general and allow for reuse in other MTAs
++# (although they will need to
++# 1) be running SA at SMTP time
++# 2) Provide the list of rcpt to and env from in some headers for SA to read
++# 3) Provide the IP of the connecting host )
++#
++# This rule should get a negative score so that if we've already seen the
++# greylisting tuplet before, we lower the score, which hopefully brings us from
++# a tempreject to an accept (at least that's how sa-exim does it)
++# -- Marc <marc_soft@merlins.org> 2004/01/19
++
++sub greylisting {
++ my ($self, $optionhash) = @_;
++
++ $optionhash =~ s/;/,/g;
++ # This is safe, right? (users shouldn't be able to set it in their config)
++ my %option=eval $optionhash;
++ my $connectip;
++ my $envfrom;
++ my $rcptto;
++ my @rcptto;
++ my $iswhitelisted=0;
++ my $err;
++ my $mesgid = $self->get ('Message-Id')."\n";
++ my $mesgidfn;
++ my $tuplet;
++
++ foreach my $reqoption (qw ( method greylistsecs dontgreylistthreshold
++ connectiphdr envfromhdr rcpttohdr greylistnullfrom greylistfourthbyte ))
++ {
++ die "Greylist option $reqoption missing from SA config" unless (defined $option{$reqoption});
++ #warn "found $reqoption -> $option{$reqoption}\n";
++ }
++
++ # No newlines, thank you (yes, you need this twice apparently)
++ chomp ($mesgid);
++ chomp ($mesgid);
++ # Newline in the middle mesgids, are you serious? Get rid of them here
++ $mesgid =~ s/\012/|/g;
++
++ # For stuff that we know is spam, don't greylist the host
++ # (that might help later spam with a lower score to come in)
++ if ($self->{hits} >= $option{'dontgreylistthreshold'})
++ {
++ #warn "debug: skipping greylisting on $mesgid, since score is already ".$self->{hits}." and you configured greylisting to not bother with anything above $dontcheckscore\n";
++ return 0;
++ }
++
++
++ if (not $connectip = $self->get($option{'connectiphdr'}))
++ {
++ warn "Couldn't get Connecting IP header $option{'connectiphdr'} for message $mesgid, skipping greylisting call\n";
++ return 0;
++ }
++ chomp($connectip);
++ # Clean up input (for security, if you use files/dirs)
++ $connectip =~ s#/#-#g;
++
++ # Account for a null envelope from
++ if (not defined ($envfrom = $self->get($option{'envfromhdr'})))
++ {
++ warn "Couldn't get Envelope From header $option{'envfromhdr'} for message $mesgid, skipping greylisting call\n";
++ return 0;
++ }
++ chomp($envfrom);
++ # Clean up input (for security, if you use files/dirs)
++ $envfrom =~ s#/#-#g;
++ if (not $envfrom)
++ {
++ $envfrom="<>";
++ return 0 if (not $option{'greylistnullfrom'});
++ }
++
++ if (not $rcptto = $self->get($option{'rcpttohdr'}))
++ {
++ warn "Couldn't get Rcpt To header $option{'rcpttohdr'} for message $mesgid, skipping greylisting call\n";
++ return 0;
++ }
++ chomp($rcptto);
++ # Clean up input (for security, if you use files/dirs)
++ $rcptto =~ s#/#-#g;
++ @rcptto = split(/, /, $rcptto);
++
++
++ umask 0007;
++
++ foreach $rcptto (@rcptto)
++ {
++ # The dir method is easy to fiddle with and expire records in (with
++ # a find | rm) but it's probably more I/O extensive than a real DB
++ # and suffers from directory size problems if a specific IP is sending
++ # generating tens of thousands of tuplets. -- Marc
++ # That said, I prefer formats I can easily tinker with, and not having to
++ # worry about buggy locking and so forth
++
++ if ($option{'method'} eq "dir")
++ {
++ # The clean strings are hardcoded because it's hard to do a variable
++ # substitution within a tr (and using the eval solution is too resource
++ # expensive)
++ $envfrom =~ tr/!#%( )*+,-.0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~/_/c;
++ # clean variables to run properly under -T
++ $envfrom =~ /(.+)/;
++ $envfrom = $1;
++ $rcptto =~ tr/!#%( )*+,-.0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~/_/c;
++ $rcptto =~ /(.+)/;
++ $rcptto = $1;
++
++ die "greylist option dir not passed, even though method was set to dir" unless ($option{'dir'});
++ my ($ipbyte1, $ipbyte2, $ipbyte3, $ipbyte4) = split(/\./, $connectip);
++ my $ipdir1 = "$option{'dir'}/$ipbyte1";
++ my $ipdir2 = "$ipdir1/$ipbyte2";
++ my $ipdir3 = "$ipdir2/$ipbyte3";
++ my $ipdir4;
++ my $tupletdir;
++
++ $ipdir4 = "$ipdir3";
++ $ipdir4 .= "/$ipbyte4" if ($option{'greylistfourthbyte'});
++ $tupletdir = "$ipdir4/$envfrom";
++
++ $tuplet = "$tupletdir/$rcptto";
++
++ # make directory whether it's there or not (faster than test and set)
++ mkdir $ipdir1;
++ mkdir $ipdir2;
++ mkdir $ipdir3;
++ mkdir $ipdir4;
++ mkdir $tupletdir;
++
++ if (not -e $tuplet)
++ {
++ # If the tuplets aren't there, we create them and continue in
++ # case there are other ones (one of them might be whitelisted already)
++ $err="creating $tuplet";
++ open (TUPLET, ">$tuplet") or goto greylisterror;
++ print TUPLET time."\n";
++ print TUPLET "Status: Greylisted\n";
++ print TUPLET "Last Message-Id: $mesgid\n";
++ print TUPLET "Whitelisted Count: 0\n";
++ print TUPLET "Query Count: 1\n";
++ $err="closing first-written $tuplet";
++ close TUPLET or goto greylisterror;
++ }
++ else
++ {
++ my $time;
++ my $status;
++ my $whitelistcount;
++ my $querycount;
++
++ # Take into account race condition of expiring deletes and us running
++ $err="reading $tuplet";
++ open (TUPLET, "<$tuplet") or goto greylisterror;
++ $err="Couldn't read time";
++ defined ($time=<TUPLET>) or goto greylisterror;
++ chomp ($time);
++
++ $err="Couldn't read status";
++ defined ($status=<TUPLET>) or goto greylisterror;
++ chomp ($status);
++ $err="Couldn't extract Status from $status";
++ $status =~ s/^Status: // or goto greylisterror;
++
++ # Skip Mesg-Id
++ $err="Couldn't skip Mesg-Id";
++ defined ($_=<TUPLET>) or goto greylisterror;
++
++ $err="Couldn't read whitelistcount";
++ defined ($whitelistcount=<TUPLET>) or goto greylisterror;
++ chomp ($whitelistcount);
++ $err="Couldn't extract Whitelisted Count from $whitelistcount";
++ $whitelistcount =~ s/^Whitelisted Count: // or goto greylisterror;
++
++ $err="Couldn't read querycount";
++ defined ($querycount=<TUPLET>) or goto greylisterror;
++ chomp ($querycount);
++ $err="Couldn't extract Query Count from $querycount";
++ $querycount =~ s/^Query Count: // or goto greylisterror;
++ close (TUPLET);
++
++ $querycount++;
++ if ((time - $time) > $option{'greylistsecs'})
++ {
++ $status="Whitelisted";
++ $whitelistcount++;
++ }
++
++ $err="re-writing $tuplet";
++ open (TUPLET, ">$tuplet") or goto greylisterror;
++ print TUPLET "$time\n";
++ print TUPLET "Status: $status\n";
++ print TUPLET "Last Message-Id: $mesgid\n";
++ print TUPLET "Whitelisted Count: $whitelistcount\n";
++ print TUPLET "Query Count: $querycount\n";
++ $err="closing re-written $tuplet";
++ close TUPLET or goto greylisterror;
++
++ # We continue processing the other recipients, to setup or
++ # update their counters
++ if ($status eq "Whitelisted")
++ {
++ $iswhitelisted=1;
++ }
++ }
++ }
++ elsif ($option{'method'} eq "file")
++ {
++ warn "codeme\n";
++ }
++ elsif ($option{'method'} eq "db")
++ {
++ warn "codeme\n";
++ }
++ }
++
++ return $iswhitelisted;
++
++ greylisterror:
++ warn "Reached greylisterror: $err / $!";
++ # delete tuplet since it apparently had issues but don't check for errors
++ # in case it was a permission denied on write
++ unlink ($tuplet);
++ return $iswhitelisted;
++}
++
++
+ ###########################################################################
+ # BODY TESTS:
+ ###########################################################################
+diff -urN SpamAssassin.orig/PerMsgStatus.pm SpamAssassin/PerMsgStatus.pm
+--- SpamAssassin.orig/PerMsgStatus.pm Tue Jan 20 13:40:04 2004
++++ SpamAssassin/PerMsgStatus.pm Sun Feb 29 19:01:19 2004
+@@ -184,6 +184,9 @@
+
+ # add points from Bayes, before adjusting the AWL
+ $self->{hits} += $self->{learned_hits};
++
++ # Now, we can run rules that have to run last
++ $self->do_res_eval_tests();
+
+ # Do AWL tests last, since these need the score to have already been
+ # calculated
+@@ -2010,6 +2013,11 @@
+ }
+
+ ###########################################################################
++
++sub do_res_eval_tests {
++ my ($self) = @_;
++ $self->run_eval_tests ($self->{conf}->{res_evals}, '');
++}
+
+ sub do_head_eval_tests {
+ my ($self) = @_;
Index: 4.2.1-12/Makefile
===================================================================
--- 4.2.1-12/Makefile (nonexistent)
+++ 4.2.1-12/Makefile (revision 61)
@@ -0,0 +1,107 @@
+# SA-Exim can be built standalone as a loadable module with this Makefile
+# or you can copy sa-exim.c over exim's local_scan.c file if you want to
+# statically build it into exim
+#
+
+VERSION=$(shell cat version)
+
+# The idea is that you don't have to edit these values, you can override
+# them on the command line:
+# make SACONF=/etc/exim/sa-exim.conf LDFLAGS="-shared -fPIC" CC=cc
+CC=gcc
+CFLAGS=-O2 -Wall
+LDFLAGS=-shared
+SACONF=/etc/exim4/sa-exim.conf
+SPAMC=/usr/bin/spamc
+
+
+# I place the directory in exim/debian/local_scan. Adjust the path as needed
+# Actually, we will also look for the versions supplied with this source
+# if we can't find the exim source
+EXIM_SRC= ../../src
+EXIM_SRC_LOCAL = ./eximinc
+SUFF=-$(VERSION)
+
+SAFLAGS=-DSPAMASSASSIN_CONF=\"$(SACONF)\" -DSPAMC_LOCATION=\"$(SPAMC)\"
+BUILDCFLAGS=-I$(EXIM_SRC) -I$(EXIM_SRC_LOCAL) -DDLOPEN_LOCAL_SCAN $(SAFLAGS) $(CFLAGS)
+
+SONAME=$(subst .so,$(SUFF).so,sa-exim.so)
+
+DOCS=sa.html CHANGELOG ACKNOWLEDGEMENTS
+OBJECTS=$(SONAME) accept.so sa-exim_short.conf $(DOCS)
+OTHERTARGETS=sa-exim.h
+
+all: $(OBJECTS)
+
+docs: $(DOCS)
+
+
+$(SONAME) : sa-exim.c sa-exim.h
+ @echo "Building $@"
+ $(CC) $(BUILDCFLAGS) $(LDFLAGS) -o $@ $<
+ chmod a+rx $(SONAME)
+
+accept.so: accept.c
+ @echo "Building $@"
+ $(CC) $(BUILDCFLAGS) $(LDFLAGS) -o $@ $<
+ chmod a+rx $@
+
+ACKNOWLEDGEMENTS: Acknowledgements.html
+ @echo "Generating $@"
+ @links -dump $< > $@
+
+CHANGELOG: Changelog.html
+ @echo "Generating $@"
+ @links -dump $< > $@
+
+sa.html: Changelog.html Acknowledgements.html sa.html.template
+ @echo "Generating $@"
+ @bash -c 'sed "/<Changelog>/,$$ d" < sa.html.template; cat Changelog.html; sed "1,/<\/Changelog>/ d; /<Acknowledgements>/,$$ d" < sa.html.template; cat Acknowledgements.html; sed "1,/<\/Acknowledgements>/ d" < sa.html.template' > sa.html
+
+sa-exim_short.conf: sa-exim.conf
+ @cat sa-exim.conf | sed "/# --- snip ---/,$$ d" > sa-exim_short.conf
+ @cat sa-exim.conf | grep -v "^#" | tr '\012' 'ÿ' | sed "s/ÿÿÿ*/ÿÿ/g" | tr 'ÿ' '\012' >> sa-exim_short.conf
+
+sa-exim.h: sa-exim.c version
+ echo "char *version=\"`cat version` (built `date -R 2>/dev/null || date`)\";" > sa-exim.h
+
+clean:
+ @-rm -rf $(OBJECTS) $(DOCS) $(OTHERTARGETS) build-stamp configure-stamp debian/sa-exim debian/sa-exim.postrm.debhelper debian/sa-exim.substvars debian/files 2>/dev/null
+
+deb: ../sa-exim_$(VERSION).orig.tar.gz debian/*
+ @make clean
+ @dpkg-buildpackage -uc -us -sd -rfakeroot
+ @make clean
+
+../sa-exim_$(VERSION).orig.tar.gz: * */*
+ @make clean
+ @( cd ..; tar chvzf sa-exim_$(VERSION).orig.tar.gz sa-exim-$(VERSION) )
+
+# This didn't work too well, I'll just ship the source with the debian tree
+#deb: ../sa-exim_$(VERSION).orig.tar.gz debian/rules
+# @make clean
+# @dpkg-buildpackage -uc -us -sd -rfakeroot
+#
+#
+#../sa-exim_$(VERSION).tar.gz: * */*
+# @make clean
+# @if [ -d debian ]; then echo "Can't rebuild $@ with debian tree unpacked, please remove it"; exit 1; fi
+# @( cd ..; tar chvzf sa-exim_$(VERSION).tar.gz sa-exim-$(VERSION) )
+#
+#
+#../sa-exim_$(VERSION).orig.tar.gz: ../sa-exim_$(VERSION).tar.gz
+# if [ -e ../sa-exim-$(VERSION).tar.gz ] ; then \
+# cp -a ../sa-exim-$(VERSION).tar.gz ../sa-exim_$(VERSION).orig.tar.gz ; \
+# else \
+# wget http://marc.merlins.org/linux/sa-exim-$(VERSION).tar.gz; \
+# mv sa-exim-$(VERSION).tar.gz ../sa-exim_$(VERSION).orig.tar.gz; \
+# fi
+#
+#
+#debian/rules:
+# @wget http://marc.merlins.org/linux/exim/files/debian/sa-exim_diff.gz
+# @zcat sa-exim_diff.gz | patch -s -p1
+# @/bin/rm sa-exim_diff.gz
+# @chmod 755 debian/rules
+#
+
Index: 4.2.1-12/.cvsignore
===================================================================
--- 4.2.1-12/.cvsignore (nonexistent)
+++ 4.2.1-12/.cvsignore (revision 61)
@@ -0,0 +1,7 @@
+.*
+ACKNOWLEDGEMENTS
+CHANGELOG
+sa.html
+sa-exim.h
+sa-exim_short.conf
+