Archive for June 5th, 2009
Sendmail filter
/* ————————————————————
* “FilterRules” feature to log any message through this MTA
* (c) /Invisible VR Corp. 2001
*
* ABSTRACT
* This routine sends every message which match the FilterRules.
*
* IMPLEMENTATION
* The FilterRules code is compiled into the sendmail binary.
* To check whether a message was already filtered it writes
* log in /var/log/filter.log
*
* CONFIGURATION
* The FilterRules is configuerd in /etc/sendmail.fil as:
* <Sender> <Recipient> <Subject> <SendTo>
*
* ———-/etc/sendmail.fil example:————-
* a@a.com b@b.com * c@c.com
* * * This|is|the|Rules d@d.com
* * e@e.com * d@d.com
* * * * f@f.com
* * * Love|letter|for|you #!virusbox@antivirus.com
* * * * *
* —————— END ————————–
* That means :
* 1/ If From a@a.com To b@b.com then send the
* message to c@c.com
* 2/ If the subject content “This is the Rules” then
* send the message to d@d.com
* 3/ If the recipient is e@e.com then send the
* message to d@d.com
* 4/ Send all message to f@f.com
* 5/ If the subject content “Love letter for you” then
* - Drop(!) the message and send a copy to virusbox@antivirus.com
* - Ignore(#) other rules. It scans from the bottom to top.
* 6/ Enable Log function, It writes activities log
* to /var/log/filter.log
*
*
*
*
* COMPATIBILITY
* FilterRules is tested with sendmail-8.8.5 and sendmail-8.11.2
* under Linux RedHat 7.1
*
* AUTHOR
* Hieu Nguyen Trung - hieu@vpnvietnam.com
*
* LICENSE/WARRANTY
* The software is provided “AS IS” without warranties of any kind,
* either expressed or implied, including, but not limited to the
* implied warranties of merchantability and fitness for a particular
* purpose. The entire risc of the software is with you. In no event
* we will be liable for any damages, including any lost profits,
* lost savings or other incidental damages arising out of the use
* or inability to use the software, even if we have been advised
* of the possibility of such damages, or for any claim by another party.
*
* INSTALLATION
* This source fragment must be included into the source-file:
* …/sendmail-8.x.y/src/srvrsmtp.c
* at the following position
*
* the sendmail binary must be remaked and reinstalled at
* its proper position (normally /usr/sbin/sendmail).
* —————————————————————
*/
/* Insert [-My Filter Code-] before these lines
*
* SmtpPhase = “delivery”;
* (void) bftruncate(e->e_xfp);
*
*/
// —————- My Filter Code———————
my_filter(e);
if (clearlist)
for (a = e->e_sendqueue; a != NULL; a = a->q_next)
{
/* make this “go away” */
a->q_state = QS_REMOVED;
}
while (sendtos!=NULL)
{
a = parseaddr(sendtos->sendto, NULLADDR, RF_COPYALL, ‘ ‘, &delimptr, e);
if (a != NULL )
a = recipient(a, &e->e_sendqueue, 0, e);
pst=sendtos;
sendtos=sendtos->next;
free(pst);
}
//—————-End My Filter ———————————
/* And Insert All The below Codes before these lines
*
* void smtp(nullserver, d_flags, e)
* char *volatile nullserver;
* register ENVELOPE *volatile e;
*/
//———————- Insert this —————————-
struct filter //Rules List
{
char subject[200];
char from[100];
char to[100];
char sendto[100];
struct filter * next;
};
typedef struct filter FILTER;
struct sendto //Sendtos List
{
char sendto[100];
struct sendto * next;
};
typedef struct sendto SENDTO;
SENDTO * sendtos, * pst;
FILTER * filters;
bool clearlist;
^Mbool exitrule;
bool fdebug;
//Add Rule to Rules List
void addchains(char *sfrom,char *sto,char *ssubject,char *ssendto)
{
FILTER *p;
p = (FILTER *)malloc(520);
if (p==NULL) return;
strcpy(p->subject,ssubject);
strcpy(p->from,sfrom);
strcpy(p->to,sto);
strcpy(p->sendto,ssendto);
p->next=filters;
filters=p;
}
void deletechains(void) //Delete Rules List
{
FILTER *p;
while (filters!=NULL)
{
p=filters;
filters=filters->next;
free(p);
}
}
void sendlist(receipient) // Add Matchs to sendtos list
char *receipient;
{
SENDTO *r;
char *p;
p = strchr(receipient,’#');
if (p != NULL)
{
receipient++;
exitrule=TRUE;
}
p = strchr(receipient,’!');
if (p != NULL)
{
receipient++;
clearlist=TRUE;
}
r = (SENDTO *)malloc(120);
if (r==NULL) return;
strcpy(r->sendto,receipient);
r->next=sendtos;
sendtos=r;
}
void cmpchains(e,fdebug) //Scan Rules
ENVELOPE *volatile e;
bool fdebug;
{
ADDRESS *b,*c;
HDR *h;
char *delimptr;
FILTER *p;
char subject[200]=”-None-”;
time_t t;
FILE *logfile;
for (h = e->e_header; h != NULL; h = h->h_link)
{ //Get subject from HDR
if (strcasecmp(h->h_field,”subject”)==0) strcpy(subject,h->h_value);
}
if (fdebug)
{ //Open Log File
logfile = fopen(”/var/log/filter.log”,”a”);
if (logfile == NULL ) fdebug=FALSE;
}
if (fdebug)
{
time(&t);
fprintf(logfile,”\n\nDate : %s”,ctime(&t));
fprintf(logfile,”Message From:[%s] To:[%s] Subject:[%s]\n”,
e->e_sender,e->e_sendqueue->q_paddr,subject);
}
for (p=filters;p!=NULL;p=p->next)
{ //Scan Rules
if (fdebug)
fprintf(logfile,”Filter From:[%s] To:[%s] Subject:[%s]\n”,
p->from,p->to,p->subject);
if (strcmp(p->from,”*”))
if (strstr(e->e_sender,p->from)==NULL) continue;
//Match FROM
if (strcmp(p->subject,”*”))
if (strstr(subject,p->subject)==NULL) continue;
//Match Subject
if (strcmp(p->to,”*”)==0)
{
sendlist(p->sendto);
if (fdebug)
{
fprintf(logfile,” Match [ALL] Sendto:[%s]\n”,p->sendto);
if (exitrule)
fprintf(logfile,” SigTerm(#) found. Ignore other rules.\n”);^M
}
}
else
for (b = e->e_sendqueue; b != NULL; b = b->q_next)
{
if (strstr(b->q_paddr,p->to)==NULL) continue;
sendlist(p->sendto);
if (fdebug)
{
fprintf(logfile,” Match To:[%s] Sendto:[%s]\n”,
b->q_paddr,p->sendto);
if (exitrule)
fprintf(logfile,” SigTerm(#) found. Ignore other rules.\n”);^M
}
break;
}
if (exitrule)
break;
}
if (fdebug) fclose(logfile);
}
void my_filter(e) //My filter
ENVELOPE *volatile e;
{
int handle,i;
char sFrom[100],sTo[100],sSubject[200],sSendto[100];
FILE *stream;
fdebug=FALSE;
exitrule=FALSE;
clearlist=FALSE;
filters= NULL;
handle = open(”/etc/sendmail.fil”,O_CREAT|S_IREAD);
stream = fdopen(handle,”r”);
if (stream == NULL ) return;
while (fscanf(stream,”%s %s %s %s”,sFrom,sTo,sSubject,sSendto)==4)
{
if (strcmp(sSendto,”*”)==0)
{
fdebug=TRUE;
continue;
}
//convert Subject “This|is|the|subject” -> “This is the subject”
for (i=0;i<strlen(sSubject);i++) if (sSubject[i]==’|') sSubject[i]=’ ‘;
addchains(sFrom,sTo,sSubject,sSendto);
}
cmpchains(e,fdebug);
deletechains();
fclose(stream);
}
// ————————-END———————-