#include "gld.h"
#include "sockets.h"
int GreyList(char *ip,char *sender,char *recipient,config *conf)
{
char query[QLEN];
long n,x;
int ts;
char *domain;
char netw[32];
int i,l;
char oip[32];
int a,b,c,d;
int pid;
char osender[BLEN];
char orecipient[BLEN];
pid=getpid();
ts=time(0);
strncpy(oip,ip,sizeof(oip)-1);
strncpy(osender,sender,sizeof(osender)-1);
strncpy(orecipient,recipient,sizeof(orecipient)-1);
if(conf->debug==1) printf("%d: Starting the greylist algo\n",pid);
//
// If we do lightgreylisting, then we just keep the network part of ip
//
if(conf->light==1)
{
if(conf->debug==1) printf("%d: lightgrey is on, let's remove the last octet of ip\n",pid);
l=strlen(ip);
for(i=l-1;i>=0;i--)
{
if(ip[i]=='.')
{
ip[i+1]='0';
ip[i+2]=0;
break;
}
}
}
//
// Do we have this entry in our database?
//
snprintf(query,sizeof(query)-1,"select first from greylist where ip='%s' and sender='%s' and recipient='%s'",ip,sender,recipient);
n=SQLQuery(query);
if(conf->debug==1) printf("%d: Query=(%s) result=%ld\n",pid,query,n);
//
// If request failed, return the error
//
if(n<0)
{
return(-1);
}
//
// If the triplet is in our db
//
if(n>0)
{
// and mintime+, always update last timestamp (cleanup needs this) and accept it
if(ts-n>conf->mini)
{
snprintf(query,sizeof(query)-1,"update greylist set last=%d,n=n+1 where ip='%s' and sender='%s' and recipient='%s'",ts,ip,sender,recipient);
SQLQuery(query);
if(conf->debug==1) printf("%d: Query=(%s)\n",pid,query);
return(1);
}
// any other case (mintime-), refuse it
else
{
if(conf->debug==1) printf("%d: MINTIME has not been reached yet\n",pid);
return(0);
}
}
// #########################################################
// From this point to the end, the triplet WAS NOT in the db
// #########################################################
//
// Now we do some whitelist checks before inserting it
//
//
// First we check our local whitelist
//
if(conf->whitelist==1)
{
if(conf->debug==1) printf("%d: whitelist is on\n",pid);
domain=(char *)strstr(osender,"@");
if(domain==NULL) domain=osender;
strncpy(netw,oip,sizeof(netw)-1);
l=strlen(netw);
for(i=l-1;i>=0;i--)
{
if(netw[i]=='.')
{
netw[i]=0;
break;
}
}
snprintf(query,sizeof(query)-1,"select count(mail) from whitelist where mail in ('%s','%s','%s','%s')",osender,domain,oip,netw);
n=SQLQuery(query);
if(conf->debug==1) printf("%d: Query=(%s) result=%ld\n",pid,query,n);
if(n>0)
{
if(conf->syslog==1) Log(conf,orecipient,osender,oip,MSGLOCALWL);
return(1);
}
}
//
// then we check the DNS whitelist
//
if(conf->dnswl[0]!=0)
{
if(conf->debug==1) printf("%d: DNS whitelist is on\n",pid);
x=sscanf(oip,"%d.%d.%d.%d",&a,&b,&c,&d);
if(x==4)
{
snprintf(query,sizeof(query)-1,"%d.%d.%d.%d.%s",d,c,b,a,conf->dnswl);
n=DnsIp(query,NULL);
if(conf->debug==1) printf("%d: DNSQuery=(%s) result=%ld\n",pid,query,n);
if(n==0)
{
if(conf->syslog==1) Log(conf,orecipient,osender,oip,MSGDNSWL);
return(1);
}
}
}
//
// If we are here, The mail was not in our database
// was not whitelisted and thus we have to insert it
//
snprintf(query,sizeof(query)-1,"insert into greylist values('%s','%s','%s',%d,%d,1)",ip,sender,recipient,ts,ts);
SQLQuery(query);
if(conf->debug==1) printf("%d: Query=(%s)\n",pid,query);
//
// If we have activated the mxgrey
// Let's accept the mail if this ip already succeded the required number of greylists
//
if(conf->mxgrey>0)
{
// check for unique triplets already graylisted from the IP
snprintf(query,sizeof(query)-1,"select count(first) from greylist where ip='%s' and n>1",ip);
n=SQLQuery(query);
if(conf->debug==1) printf("%d: Mxgrey Query=(%s) result=%ld (minimum needed is %d)\n",pid,query,n,conf->mxgrey);
// if found, accept it
if(n>=conf->mxgrey)
{
return(1);
}
}
return(0);
}
syntax highlighted by Code2HTML, v. 0.9.1