1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
#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);
}
|