File: greylist.c

package info (click to toggle)
postfix-gld 1.7-8
  • links: PTS
  • area: main
  • in suites: bullseye, buster, stretch
  • size: 480 kB
  • sloc: ansic: 1,447; sql: 169; sh: 112; makefile: 109
file content (168 lines) | stat: -rw-r--r-- 3,826 bytes parent folder | download | duplicates (7)
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);

}