Subversion Repositories sa-exim

Compare Revisions

Ignore whitespace Rev 30 → Rev 29

/branches/splitpkg/LICENSE
File deleted
/branches/splitpkg/debian/15_sa-exim_plugin_path
File deleted
/branches/splitpkg/debian/config
File deleted
/branches/splitpkg/debian/watch
File deleted
/branches/splitpkg/debian/copyright
File deleted
/branches/splitpkg/debian/NEWS
File deleted
/branches/splitpkg/debian/po/pt.po
File deleted
/branches/splitpkg/debian/po/da.po
File deleted
/branches/splitpkg/debian/po/cs.po
File deleted
/branches/splitpkg/debian/po/es.po
File deleted
/branches/splitpkg/debian/po/fr.po
File deleted
/branches/splitpkg/debian/po/sv.po
File deleted
/branches/splitpkg/debian/po/de.po
File deleted
/branches/splitpkg/debian/po/nl.po
File deleted
/branches/splitpkg/debian/po/ja.po
File deleted
/branches/splitpkg/debian/po/it.po
File deleted
/branches/splitpkg/debian/po/POTFILES.in
File deleted
/branches/splitpkg/debian/po/vi.po
File deleted
/branches/splitpkg/debian/po/gl.po
File deleted
/branches/splitpkg/debian/po/templates.pot
File deleted
/branches/splitpkg/debian/README.Debian
File deleted
/branches/splitpkg/debian/control
File deleted
/branches/splitpkg/debian/compat
File deleted
/branches/splitpkg/debian/postinst
File deleted
/branches/splitpkg/debian/postrm
File deleted
/branches/splitpkg/debian/changelog
File deleted
/branches/splitpkg/debian/docs
File deleted
/branches/splitpkg/debian/rules
File deleted
Property changes:
Deleted: svn:executable
Index: splitpkg/debian/templates
===================================================================
--- splitpkg/debian/templates (revision 30)
+++ splitpkg/debian/templates (nonexistent)
@@ -1,11 +0,0 @@
-Template: sa-exim/purge_spool
-Type: boolean
-Default: false
-_Description: Remove saved mails in spool directory?
- 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.
- .
- You can keep them for further analysis and later remove them manually or
- decide to delete them now.
Index: splitpkg/debian/dirs
===================================================================
--- splitpkg/debian/dirs (revision 30)
+++ splitpkg/debian/dirs (nonexistent)
@@ -1,7 +0,0 @@
-usr/lib/exim4/local_scan
-usr/share/doc/sa-exim/patches
-etc/exim4/conf.d/main
-usr/share/perl5/Mail/SpamAssassin/Plugin
-usr/share/sa-exim
-etc/cron.d
-usr/sbin
Index: splitpkg/sa-exim.c
===================================================================
--- splitpkg/sa-exim.c (revision 30)
+++ splitpkg/sa-exim.c (nonexistent)
@@ -1,1538 +0,0 @@
-/* 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)
- primary_hostname = expand_string("$primary_hostname");
-
- /* 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: splitpkg/version
===================================================================
--- splitpkg/version (revision 30)
+++ splitpkg/version (nonexistent)
@@ -1 +0,0 @@
-4.2.1
Index: splitpkg/sa-exim.conf
===================================================================
--- splitpkg/sa-exim.conf (revision 30)
+++ splitpkg/sa-exim.conf (nonexistent)
@@ -1,376 +0,0 @@
-# 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: splitpkg/localscan_dlopen_exim_4.20_or_better.patch
===================================================================
--- splitpkg/localscan_dlopen_exim_4.20_or_better.patch (revision 30)
+++ splitpkg/localscan_dlopen_exim_4.20_or_better.patch (nonexistent)
@@ -1,268 +0,0 @@
-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: splitpkg/Changelog.html
===================================================================
--- splitpkg/Changelog.html (revision 30)
+++ splitpkg/Changelog.html (nonexistent)
@@ -1,291 +0,0 @@
-<!-- <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: splitpkg/eximinc/README
===================================================================
--- splitpkg/eximinc/README (revision 30)
+++ splitpkg/eximinc/README (nonexistent)
@@ -1,6 +0,0 @@
-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: splitpkg/eximinc/mytypes.h
===================================================================
--- splitpkg/eximinc/mytypes.h (revision 30)
+++ splitpkg/eximinc/mytypes.h (nonexistent)
@@ -1,95 +0,0 @@
-/*************************************************
-* 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: splitpkg/eximinc/store.h
===================================================================
--- splitpkg/eximinc/store.h (revision 30)
+++ splitpkg/eximinc/store.h (nonexistent)
@@ -1,53 +0,0 @@
-/*************************************************
-* 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: splitpkg/eximinc/local_scan.h
===================================================================
--- splitpkg/eximinc/local_scan.h (revision 30)
+++ splitpkg/eximinc/local_scan.h (nonexistent)
@@ -1,150 +0,0 @@
-/*************************************************
-* 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: splitpkg/eximinc/version
===================================================================
--- splitpkg/eximinc/version (revision 30)
+++ splitpkg/eximinc/version (nonexistent)
@@ -1 +0,0 @@
-exim-4.14
Index: splitpkg/localscan_dlopen_up_to_exim_4.14.patch
===================================================================
--- splitpkg/localscan_dlopen_up_to_exim_4.14.patch (revision 30)
+++ splitpkg/localscan_dlopen_up_to_exim_4.14.patch (nonexistent)
@@ -1,287 +0,0 @@
-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: splitpkg/README.greylisting
===================================================================
--- splitpkg/README.greylisting (revision 30)
+++ splitpkg/README.greylisting (nonexistent)
@@ -1,258 +0,0 @@
- 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: splitpkg/Acknowledgements.html
===================================================================
--- splitpkg/Acknowledgements.html (revision 30)
+++ splitpkg/Acknowledgements.html (nonexistent)
@@ -1,119 +0,0 @@
-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: splitpkg/README
===================================================================
--- splitpkg/README (revision 30)
+++ splitpkg/README (nonexistent)
@@ -1,355 +0,0 @@
-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: splitpkg/contrib/sa-exim-stats.txt
===================================================================
--- splitpkg/contrib/sa-exim-stats.txt (revision 30)
+++ splitpkg/contrib/sa-exim-stats.txt (nonexistent)
@@ -1,3 +0,0 @@
-See this page:
-
-http://nossie.addicts.nl/projects/sa-exim-stats/
Index: splitpkg/contrib/spam_resend.txt
===================================================================
--- splitpkg/contrib/spam_resend.txt (revision 30)
+++ splitpkg/contrib/spam_resend.txt (nonexistent)
@@ -1,70 +0,0 @@
-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: splitpkg/SA-greylisting-2.4x.diff
===================================================================
--- splitpkg/SA-greylisting-2.4x.diff (revision 30)
+++ splitpkg/SA-greylisting-2.4x.diff (nonexistent)
@@ -1,264 +0,0 @@
-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: splitpkg/TODO
===================================================================
--- splitpkg/TODO (revision 30)
+++ splitpkg/TODO (nonexistent)
@@ -1 +0,0 @@
-Do per-user SA runs with the exiscan 45x trick
Index: splitpkg/greylistclean.cron
===================================================================
--- splitpkg/greylistclean.cron (revision 30)
+++ splitpkg/greylistclean.cron (nonexistent)
@@ -1,3 +0,0 @@
-# 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: splitpkg/greylistclean
===================================================================
--- splitpkg/greylistclean (revision 30)
+++ splitpkg/greylistclean (nonexistent)
@@ -1,177 +0,0 @@
-#!/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);
- }
-}
/splitpkg/greylistclean
Property changes:
Deleted: svn:executable
Index: splitpkg/INSTALL
===================================================================
--- splitpkg/INSTALL (revision 30)
+++ splitpkg/INSTALL (nonexistent)
@@ -1,100 +0,0 @@
-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: splitpkg/Greylisting.pm
===================================================================
--- splitpkg/Greylisting.pm (revision 30)
+++ splitpkg/Greylisting.pm (nonexistent)
@@ -1,296 +0,0 @@
-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;
- $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)
- $connectip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
- my ($ipbyte1, $ipbyte2, $ipbyte3, $ipbyte4) = ($1, $2, $3, $4);
- 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";
- 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: splitpkg/SA-greylisting-2.6.diff
===================================================================
--- splitpkg/SA-greylisting-2.6.diff (revision 30)
+++ splitpkg/SA-greylisting-2.6.diff (nonexistent)
@@ -1,304 +0,0 @@
-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: splitpkg/.cvsignore
===================================================================
--- splitpkg/.cvsignore (revision 30)
+++ splitpkg/.cvsignore (nonexistent)
@@ -1,7 +0,0 @@
-.*
-ACKNOWLEDGEMENTS
-CHANGELOG
-sa.html
-sa-exim.h
-sa-exim_short.conf
-
Index: splitpkg/Makefile
===================================================================
--- splitpkg/Makefile (revision 30)
+++ splitpkg/Makefile (nonexistent)
@@ -1,107 +0,0 @@
-# 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: splitpkg/sa.html.template
===================================================================
--- splitpkg/sa.html.template (revision 30)
+++ splitpkg/sa.html.template (nonexistent)
@@ -1,221 +0,0 @@
-<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: splitpkg/accept.c
===================================================================
--- splitpkg/accept.c (revision 30)
+++ splitpkg/accept.c (nonexistent)
@@ -1,45 +0,0 @@
-/*************************************************
-* 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 */