38 #define DT_GREY_SLEEP 10 41 #define DT_GREY_INTERVAL (6 HOURS) 43 #ifndef MIN_CNT_PER_DOMAIN 44 #define MIN_CNT_PER_DOMAIN 5 47 #ifndef GREY_TP_MIN_NORM 48 #define GREY_TP_MIN_NORM 10 MINUTES 50 #ifndef GREY_TP_MIN_NULL 51 #define GREY_TP_MIN_NULL 10 MINUTES 53 #ifndef GREY_TP_MAX_NORM 54 #define GREY_TP_MAX_NORM 3 DAYS 56 #ifndef GREY_TP_MAX_NULL 57 #define GREY_TP_MAX_NULL 4 HOURS 61 #define GREY_TV_MAX 7 DAYS 64 #define GREY_TW_MAX 21 DAYS 67 #define GREY_TB_MAX 7 DAYS 70 #ifndef T_EXPIRE_BAD_MIN 71 #define T_EXPIRE_BAD_MIN 6 HOURS 73 #ifndef T_EXPIRE_PENDING_BAD_MAX 74 #define T_EXPIRE_PENDING_BAD_MAX 24 HOURS 76 #ifndef T_EXPIRE_VALID_BAD_MAX 77 #define T_EXPIRE_VALID_BAD_MAX 5 DAYS 80 static bool grey_compat_domain_check =
TRUE;
82 static bool rdonly =
FALSE;
97 static int max_pending_normal = 1000;
98 static int max_pending_null = 100;
100 static time_t dt_grey_cleanup = 2
MINUTES;
121 bool compat_domain_check;
129 time_t tp_min_no_match;
138 int max_pending_normal;
139 int max_pending_null;
238 static char *grey_key(
char *,
char *,
char *,
int,
int,
int);
241 static char *grey_key_pending(
char *,
char *,
char *,
int,
int,
int);
242 static char *grey_key_valid(
char *,
char *,
char *,
int,
int,
int);
243 static char *grey_key_black(
char *,
char *,
char *,
int,
int,
int);
245 static char *grey_key_white(
char *,
char *);
247 static int grey_count_pending(
char *);
250 static bool db_grey_open(
char *,
bool);
251 static bool db_grey_reopen();
252 static bool db_grey_close();
253 static bool db_grey_flush();
255 static bool grey_add_rec(
ZEDB_T *,
char *,
void *,
size_t);
256 static bool grey_get_rec(
ZEDB_T *,
char *,
void *,
size_t);
257 static bool grey_del_rec(
ZEDB_T *,
char *);
259 static bool grey_cursor_open(
ZEDB_T *,
bool);
260 static bool grey_cursor_get_first(
ZEDB_T *,
char *,
size_t,
void *,
262 static bool grey_cursor_get_next(
ZEDB_T *,
char *,
size_t,
void *,
264 static bool grey_cursor_close(
ZEDB_T *);
273 static pthread_mutex_t grey_crit = PTHREAD_MUTEX_INITIALIZER;
275 #define GREY_CRIT_LOCK() MUTEX_LOCK(&grey_crit) 276 #define GREY_CRIT_UNLOCK() MUTEX_UNLOCK(&grey_crit) 294 static bool tuple_str2rec(
tuple_T *,
char *);
295 static bool tuple_rec2str(
char *,
tuple_T *,
size_t);
328 #define GREY_ENTRY_INITIALIZER {0, 0, NULL, NULL, NULL, NULL, \ 329 NULL, NULL, NULL, NULL, 0, FALSE, NULL, NULL, NULL} 331 static char *grey_separator(
char *s);
332 static bool grey_value_str2entry(
grey_entry_T *,
char *);
333 static bool grey_value_entry2str(
char *,
grey_entry_T *,
size_t);
337 static bool grey_key_entry2str(
char *,
grey_entry_T *,
size_t);
341 #define ISNULLSENDER(x) (((x) == NULL) || \ 342 (strstr((x), "<>") != NULL) || \ 343 (strlen((x)) == 0) || \ 344 (strcasecmp((x), "nullsender") == 0) || \ 345 (strncasecmp((x), "postmaster", 10) == 0) || \ 346 (strncasecmp((x), "mailer-daemon", 13) == 0)) 348 static bool compatible_domainnames(
char *da,
char *db);
360 if (ip == NULL && from == NULL && to == NULL)
364 if (strcasecmp(ip,
"NONE") == 0)
366 if (strcasecmp(ip,
"FULL") == 0)
368 if (strcasecmp(ip,
"NET") == 0)
372 if (strcasecmp(from,
"NONE") == 0)
374 if (strcasecmp(from,
"FULL") == 0)
376 if (strcasecmp(from,
"USER") == 0)
378 if (strcasecmp(from,
"HOST") == 0)
382 if (strcasecmp(to,
"NONE") == 0)
384 if (strcasecmp(to,
"FULL") == 0)
386 if (strcasecmp(to,
"USER") == 0)
388 if (strcasecmp(to,
"HOST") == 0)
406 grey_tp_min_norm = tp_min_norm;
408 grey_tp_max_norm =
MAX(tp_max_norm, tp_min_norm);
410 grey_tp_min_null = tp_min_null;
412 grey_tp_max_null =
MAX(tp_min_null, tp_max_null);
447 max_pending_normal = nbnormal;
449 max_pending_null = nbnull;
463 dt_grey_cleanup = tclean;
476 grey_compat_domain_check = enable;
503 bool null_sender =
FALSE;
504 char *ip, *from, *rcpt, *hostname;
505 bool domain_ok =
TRUE;
511 memset(&entry, 0,
sizeof (entry));
516 ip = from = rcpt = hostname = NULL;
524 kFrom =
"nullsender";
539 if ((from = strdup(kFrom)) != NULL)
546 if ((rcpt = strdup(kRcpt)) != NULL)
551 if (from == NULL || rcpt == NULL)
572 char buf_from[
BF_SZ], *pf;
573 bool nullsender =
FALSE;
576 memset(buf_from, 0,
sizeof (buf_from));
583 while (result !=
GREY_OK && pf != NULL && strlen(pf) > 0) {
586 key = grey_key_white(ip, pf);
588 if (grey_get_rec(&gdata.
gdbw, key, value, sizeof (value))) {
589 grey_entry_free(&entry);
590 (void) grey_value_str2entry(&entry, value);
596 (void) grey_value_entry2str(value, &entry,
sizeof (value));
597 (void) grey_add_rec(&gdata.
gdbw, key, value, strlen(value));
608 if ((p =
strchr(pf,
'.')) != NULL)
619 key = grey_key(ip, from, rcpt, select_ip, select_from, select_rcpt);
631 if (grey_get_rec(&gdata.
gdbv, key, value, sizeof (value))) {
632 grey_entry_free(&entry);
633 (void) grey_value_str2entry(&entry, value);
643 (void) grey_value_entry2str(value, &entry,
sizeof (value));
644 (void) grey_add_rec(&gdata.
gdbv, key, value, strlen(value));
660 memset(value, 0,
sizeof (value));
661 if (grey_get_rec(&gdata.
gdbp, key, value, sizeof (value))) {
663 time_t dt_min, dt_max;
665 grey_entry_free(&entry);
666 (void) grey_value_str2entry(&entry, value);
674 snprintf(tbuf,
sizeof (tbuf),
"%ld:%ld:%s:%s:%s:%s:%d:%s",
680 "FLAGS", entry.
count < 1 ? 1 : entry.
count,
"NULL");
694 dt_min = grey_tp_min_null;
695 dt_max = grey_tp_max_null;
697 dt_min = grey_tp_min_norm;
698 dt_max = grey_tp_max_norm;
701 if (hostname != NULL)
702 domain_ok = compatible_domainnames(from, hostname);
719 if (last + dt_min > now) {
721 (void) grey_entry_free(&entry);
728 (void) grey_del_rec(&gdata.
gdbp, key);
733 if (last == 0 || last + dt_max > now) {
738 if (!null_sender && can_validate) {
740 (void) grey_value_entry2str(value, &entry,
sizeof (value));
741 (void) grey_add_rec(&gdata.
gdbv, key, value, strlen(value));
759 max_pending = max_pending_null;
761 max_pending = max_pending_normal;
763 if (max_pending > 0) {
764 count = grey_count_pending(ip);
768 if (max_pending == 0 || count < max_pending) {
777 grey_entry_free(&entry);
788 (void) grey_value_entry2str(value, &entry,
sizeof (value));
790 r = grey_add_rec(&gdata.
gdbp, key, value, strlen(value));
808 grey_entry_free(&entry);
835 char *ip, *from, *rcpt, *hostname;
839 vkey = ip = from = rcpt = hostname = NULL;
847 kFrom =
"nullsender";
852 ip = from = rcpt = hostname = NULL;
864 from = strdup(kFrom);
867 rcpt = strdup(kRcpt);
873 if (from == NULL || strlen(from) == 0) {
877 if (rcpt == NULL || strlen(rcpt) == 0) {
886 vkey = grey_key(ip, from, rcpt, select_ip, select_from, select_rcpt);
904 memset(&entry, 0,
sizeof (entry));
907 while (pf != NULL && strlen(pf) > 0) {
911 wkey = grey_key_white(ip, pf);
913 if (grey_get_rec(&gdata.
gdbw, wkey, value, sizeof (value))) {
914 grey_entry_free(&entry);
915 (void) grey_value_str2entry(&entry, value);
921 (void) grey_value_entry2str(value, &entry,
sizeof (value));
922 (void) grey_add_rec(&gdata.
gdbw, wkey, value, strlen(value));
930 if ((p =
strchr(pf,
'.')) != NULL)
945 memset(&entry, 0,
sizeof (entry));
947 if (grey_get_rec(&gdata.
gdbv, vkey, value, sizeof (value))) {
948 grey_entry_free(&entry);
949 (void) grey_value_str2entry(&entry, value);
955 (void) grey_value_entry2str(value, &entry,
sizeof (value));
956 (void) grey_entry_free(&entry);
957 (void) grey_add_rec(&gdata.
gdbv, vkey, value, strlen(value));
966 (void) grey_value_entry2str(value, &entry,
sizeof (value));
967 (void) grey_entry_free(&entry);
968 (void) grey_add_rec(&gdata.
gdbv, vkey, value, strlen(value));
975 memset(&entry, 0,
sizeof (entry));
987 (void) grey_value_entry2str(value, &entry,
sizeof (value));
988 (void) grey_entry_free(&entry);
990 (void) grey_add_rec(&gdata.
gdbv, vkey, value, strlen(value));
997 if (grey_get_rec(&gdata.
gdbp, vkey, value, sizeof (value))) {
1001 (void) grey_del_rec(&gdata.
gdbp, vkey);
1044 grey_key(ip, from, rcpt, ipFlags, fromFlags, rcptFlags)
1056 from =
STRNULL(from,
"nullsender");
1064 if ((p = malloc(sz)) == NULL) {
1070 char buf_from[
BF_SZ], *pf = buf_from;
1071 char buf_rcpt[
BF_SZ], *pt = buf_rcpt;
1072 char buf_ip[
BF_SZ], *pi = buf_ip;
1075 bool nullsender =
FALSE;
1077 memset(buf_from, 0,
sizeof (buf_from));
1078 memset(buf_rcpt, 0,
sizeof (buf_rcpt));
1079 memset(buf_ip, 0,
sizeof (buf_ip));
1089 strlcpy(buf_ip, ip,
sizeof (buf_ip));
1095 snprintf(buf_from,
sizeof (buf_from),
"nullsender");
1110 if ((q =
strrchr(buf_ip,
'.')) != NULL)
1115 switch (fromFlags) {
1122 if ((q =
strchr(buf_from,
'@')) != NULL)
1126 if ((q =
strchr(buf_from,
'@')) != NULL)
1131 switch (rcptFlags) {
1138 if ((q =
strchr(buf_rcpt,
'@')) != NULL)
1142 if ((q =
strchr(buf_rcpt,
'@')) != NULL)
1147 for (q = pi; *q !=
'\0'; q++) {
1148 if (iscntrl(*q) || isspace(*q) || (*q ==
';') || (*q ==
'#'))
1151 for (q = pf; *q !=
'\0'; q++) {
1152 if (iscntrl(*q) || isspace(*q) || (*q ==
';') || (*q ==
'#'))
1155 for (q = pt; *q !=
'\0'; q++) {
1156 if (iscntrl(*q) || isspace(*q) || (*q ==
';') || (*q ==
'#'))
1160 snprintf(p, sz,
"%s;%s;%s", pi, pf, pt);
1171 grey_key_white(ip, from)
1179 from =
STRNULL(from,
"nullsender");
1186 if ((p = malloc(sz)) == NULL) {
1192 char buf_from[
BF_SZ], *pf;
1193 char buf_ip[
BF_SZ], *pi;
1196 bool nullsender =
FALSE;
1201 memset(buf_from, 0,
sizeof (buf_from));
1202 memset(buf_ip, 0,
sizeof (buf_ip));
1212 strlcpy(buf_ip, ip,
sizeof (buf_ip));
1217 snprintf(buf_from,
sizeof (buf_from),
"nullsender");
1219 if ((q =
strchr(buf_from,
'@')) != NULL)
1222 for (q = pi; *q !=
'\0'; q++) {
1223 if (iscntrl(*q) || isspace(*q) || (*q ==
'/') || (*q ==
';')
1227 for (q = pf; *q !=
'\0'; q++) {
1228 if (iscntrl(*q) || isspace(*q) || (*q ==
'/') || (*q ==
';')
1233 snprintf(p, sz,
"%s;%s", pi, pf);
1244 grey_count_pending(ip)
1252 if (grey_cursor_open(&gdata.
gdbp,
TRUE)) {
1258 memset(key, 0,
sizeof (key));
1259 memset(data, 0,
sizeof (data));
1261 strlcpy(key, ip,
sizeof (key));
1262 switch (select_ip) {
1269 if ((q =
strrchr(key,
'.')) != NULL)
1273 if (strlen(key) > 0)
1274 strlcat(key,
";",
sizeof (key));
1275 strlcpy(ipk, key,
sizeof (ipk));
1277 if (grey_cursor_get_first
1278 (&gdata.
gdbp, key, sizeof (key), data,
sizeof (data))) {
1287 if (strncmp(key, ipk, strlen(ipk)) != 0)
1290 memset(&entry, 0,
sizeof (entry));
1291 (void) grey_value_str2entry(&entry, data);
1293 grey_entry_free(&entry);
1298 }
while (grey_cursor_get_next(&gdata.
gdbp, key, sizeof (key), data,
1302 (void) grey_cursor_close(&gdata.
gdbp);
1323 static char *greydir = NULL;
1363 res = db_grey_open(greydir, rd);
1384 (void) db_grey_close();
1398 result = db_grey_reopen();
1409 grey_add_rec(h, key, value, size)
1429 grey_get_rec(h, key, value, size)
1449 grey_del_rec(h, key)
1480 res = db_grey_flush();
1492 grey_cursor_open(h, rdonly)
1508 grey_cursor_close(h)
1523 grey_cursor_get_first(h, k, ksz, v, vsz)
1542 grey_cursor_get_next(h, k, ksz, v, vsz)
1582 db_grey_open(workdir, rd)
1590 if (workdir == NULL || strlen(workdir) == 0)
1599 mode = (rdonly ? 0444 : 0644);
1603 snprintf(path,
sizeof (path),
"%s/%s", workdir,
"ze-greypend.db");
1613 snprintf(path,
sizeof (path),
"%s/%s", workdir,
"ze-greyvalid.db");
1623 snprintf(path,
sizeof (path),
"%s/%s", workdir,
"ze-greywhitelist.db");
1633 snprintf(path,
sizeof (path),
"%s/%s", workdir,
"ze-greyblacklist.db");
1686 res = db_grey_open(greydir, rdonly);
1720 "Reloading Greylisting databases after error (pending)");
1740 #define SIGTID ((pthread_t ) 23021957) 1742 static void *grey_task(
void *);
1743 static pthread_t tid =
SIGTID;
1744 static time_t tlast = (time_t) 0;
1751 if (tid !=
SIGTID && (time(NULL) - tlast > 2 * dt_grey_cleanup)) {
1759 if ((r = pthread_create(&tid, NULL, grey_task, (
void *) NULL)) != 0)
1790 if ((ts = strdup(s)) == NULL) {
1795 memset(argv, 0,
sizeof (argv));
1798 for (i = 0; i < argc; i++) {
1799 if (strcasecmp(argv[i],
"ALL") == 0) {
1804 if (strcasecmp(argv[i],
"NONE") == 0) {
1809 if (strcasecmp(argv[i],
"NullSender") == 0) {
1813 if (strcasecmp(argv[i],
"BadResolve") == 0) {
1817 if (strcasecmp(argv[i],
"DomainMatch") == 0) {
1821 if (strcasecmp(argv[i],
"BadRCPT") == 0) {
1825 if (strcasecmp(argv[i],
"SpamTrap") == 0) {
1829 if (strcasecmp(argv[i],
"BadMX") == 0) {
1833 if (strcasecmp(argv[i],
"BadClient") == 0) {
1837 if (strcasecmp(argv[i],
"Spammer") == 0) {
1853 #define TIMER_INIT(t) \ 1858 #define TIMER_NOW(t) (zeTime_ms() - t) 1860 #define TIMER_LOG(s, t) \ 1862 timems_T dt = TIMER_NOW(t); \ 1863 ZE_MessageInfo(0, "%-12s : Elapsed time %ld ms",s, (long ) (dt)); \ 1880 grey_database_expire(h, st, tmax_norm, tmax_null, gdb)
1888 time_t now = time(NULL);
1890 char tkey[3 *
BF_SZ];
1892 size_t ksz =
sizeof (tkey);
1907 label =
"Whitelist";
1910 label =
"Blacklist";
1921 time_t dt = dt_lock_max;
1923 if ((env = getenv(
"GREY_CLEANUP_DT_LOCK_MAX")) != NULL) {
1932 ksz =
sizeof (st->
key);
1933 if (strlen(key) == 0)
1941 memset(kbuf, 0,
sizeof (kbuf));
1942 if (grey_cursor_open(h,
FALSE)) {
1945 bool ip_bad =
FALSE;
1947 bool check_bad_clients;
1948 bool check_domain_match;
1952 check_domain_match =
1958 env = getenv(
"GREY_CHECK_BAD_CLIENTS");
1959 if (env != NULL && strcasecmp(env,
"YES") == 0)
1960 check_bad_clients =
TRUE;
1962 env = getenv(
"GREY_CHECK_DOMAIN_MATCH");
1963 if (env != NULL && strcasecmp(env,
"YES") == 0)
1964 check_domain_match =
TRUE;
1967 memset(data, 0,
sizeof (data));
1968 memset(ip, 0,
sizeof (ip));
1971 for (ok = grey_cursor_get_first(h, key, ksz, data,
sizeof (data));
1972 ok; ok = grey_cursor_get_next(h, key, ksz, data,
sizeof (data))) {
1979 bool nullsender =
FALSE;
1980 time_t t_max = tmax_norm;
1982 char *hostname = NULL;
1984 char *separator =
";";
2000 strlcpy(kbuf, key,
sizeof (kbuf));
2002 if (argck == 0 || argvk[0] == NULL || argvk[1] == NULL
2003 || argvk[2] == NULL) {
2009 separator = grey_separator(data);
2014 (void) grey_cursor_del(h);
2054 if (strcasecmp(argvv[ARG_IP], ip) != 0) {
2057 strlcpy(ip, argvv[ARG_IP],
sizeof (ip));
2059 if (check_bad_clients)
2067 (void) grey_cursor_del(h);
2081 if (check_domain_match && !nullsender) {
2082 char *pfrom, *pname;
2084 pfrom =
strchr(from,
'@');
2091 if ((pname != NULL && strlen(pname) > 0) &&
2092 !compatible_domainnames(pfrom, pname)) {
2115 if (last + t_max < now) {
2117 if (strcmp(why,
"") == 0)
2128 memset(logstr, 0,
sizeof (logstr));
2133 snprintf(logstr,
sizeof (logstr),
2134 "DB=(%s) WHY=(%s) CREATED=(%s) UPDATED=(%s) IP=(%s) " 2135 "HOSTNAME=(%s) FROM=(%s) TO=(%s) KEY=(%s/%s/%s)",
2145 (void) grey_cursor_del(h);
2150 if (last + t_max > now) {
2153 if ((ntp % 1000) == 0) {
2162 "Handling %s database : max delay expired : %d entries handled",
2170 (void) grey_cursor_close(h);
2187 count_members(s, sep)
2193 if (s == NULL || strlen(s) == 0)
2196 while ((s =
strchr(s, sep)) != NULL) {
2206 grey_list2white(dbw, list)
2211 time_t now = time(NULL);
2213 for (lst = list; lst != NULL; lst = lst->
next) {
2214 char wkey[256], wval[256];
2217 int nbdomains, nbentries, nbhits;
2223 memset(&entry, 0,
sizeof (entry));
2228 nbdomains = nbentries = nbhits = 0;
2233 n = strcspn(lst->
key,
";");
2234 if (n == strlen(lst->
key)) {
2242 for (p = list; p != NULL; p = p->
next) {
2244 if (strncasecmp(lst->
key, p->
key, n) == 0) {
2272 snprintf(wval,
sizeof (wval),
"%lu:%lu:%d", now, now, lst->
count);
2284 sizeof (entry.
vrcpt));
2299 grey_value_entry2str(wval, &entry,
sizeof (wval));
2302 (void) grey_add_rec(dbw, wkey, wval, strlen(wval));
2304 grey_entry_free(&entry);
2315 grey_database_whitelist(dba, dbb, st)
2330 if (grey_cursor_open(dba,
FALSE)) {
2333 size_t ksz =
sizeof (key);
2335 char cur_prefix[
BF_SZ];
2336 char new_prefix[
BF_SZ];
2340 time_t now = time(NULL);
2342 memset(key, 0,
sizeof (key));
2343 memset(data, 0,
sizeof (data));
2344 memset(cur_prefix, 0,
sizeof (cur_prefix));
2345 memset(new_prefix, 0,
sizeof (new_prefix));
2349 for (ok = grey_cursor_get_first(dba, key, ksz, data,
sizeof (data));
2350 ok; ok = grey_cursor_get_next(dba, key, ksz, data,
sizeof (data))) {
2367 p =
strchr(argv[1],
'@');
2373 snprintf(new_prefix,
sizeof (new_prefix),
"%s;%s", argv[0], p);
2376 if (strcasecmp(cur_prefix, new_prefix) != 0) {
2377 if (cnt_prefix > 6) {
2382 strlcpy(cur_prefix, new_prefix,
sizeof (cur_prefix));
2385 grey_list2white(dbb, list);
2397 char lkey[256], lval[256];
2400 memset(&entry, 0,
sizeof (entry));
2402 snprintf(lkey,
sizeof (lkey),
"%s %s", argv[0], argv[1]);
2406 if (grey_value_str2entry(&entry, data)) {
2407 char *p = entry.
from;
2418 snprintf(lkey,
sizeof (lkey),
"%s;%s", entry.
ip, p);
2429 if (grey_get_rec(dbb, lkey, lval,
sizeof (lval))) {
2432 (void) grey_cursor_del(dba);
2433 grey_entry_free(&entry);
2451 if (!compatible_domainnames(from, entry.
hostname)) {
2470 grey_list2white(dbb, list);
2474 (void) grey_cursor_close(dba);
2490 #define ST_PENDING 1 2497 #define CHECK_DELAY() \ 2499 if (time(NULL) - now > 2) \ 2503 #define CHECK_DELAY() 2519 tbase = thlast = now;
2521 memset(&p_st, 0,
sizeof (p_st));
2522 memset(&v_st, 0,
sizeof (v_st));
2523 memset(&w_st, 0,
sizeof (w_st));
2524 memset(&b_st, 0,
sizeof (b_st));
2529 time_t dt = dt_grey_sub;
2531 if ((env = getenv(
"GREY_CLEANUP_SUB_INTERVAL")) != NULL) {
2550 if (tbase + dt_grey_cleanup <= now) {
2560 if ((thlast + dt_grey_sub) <= now) {
2572 grey_database_expire(&gdata.
gdbp, &p_st, grey_tp_max_norm,
2576 memset(p_st.
key, 0, sizeof (p_st.
key));
2593 grey_database_expire(&gdata.
gdbv, &v_st, grey_tv_max, 12
HOURS,
2597 (void) grey_database_whitelist(&gdata.
gdbv, &gdata.
gdbw, &v_st);
2600 memset(v_st.
key, 0, sizeof (v_st.
key));
2617 grey_database_expire(&gdata.
gdbw, &w_st, grey_tw_max, 12
HOURS,
2621 memset(w_st.
key, 0, sizeof (w_st.
key));
2638 grey_database_expire(&gdata.
gdbb, &b_st, grey_tb_max, 12
HOURS,
2642 memset(b_st.
key, 0, sizeof (b_st.
key));
2652 "GREY database cleanup : pending=%d/%d valid=%d/%d white=%d/%d",
2713 if (grey_cursor_open(db,
TRUE)) {
2717 memset(key, 0,
sizeof (key));
2718 memset(data, 0,
sizeof (data));
2722 if (grey_cursor_get_first(db, key,
sizeof (key), data,
sizeof (data))) {
2734 strlcpy(buf, data,
sizeof (buf));
2740 if (t == 0 || t + dt <= now)
2744 if (!
sd_printf(fd,
"%s %s\r\n", key, data))
2747 }
while (grey_cursor_get_next
2748 (db, key,
sizeof (key), data,
sizeof (data)));
2751 (void) grey_cursor_close(db);
2801 if (grey_cursor_open(db,
TRUE)) {
2804 memset(key, 0,
sizeof (key));
2805 memset(data, 0,
sizeof (data));
2808 if (grey_cursor_get_first(db, key,
sizeof (key), data,
sizeof (data))) {
2819 strlcpy(buf, data,
sizeof (buf));
2828 }
while (grey_cursor_get_next
2829 (db, key,
sizeof (key), data,
sizeof (data)));
2832 (void) grey_cursor_close(db);
2851 static char *sep =
";";
2853 if (s != NULL && strlen(s) > 0) {
2856 l = strspn(s,
"0123456789");
2870 grey_entry_free(entry)
2876 memset(entry, 0,
sizeof (*entry));
2880 grey_value_str2entry(entry, s)
2888 char *separator =
";";
2894 if ((tstr = strdup(s)) == NULL) {
2899 separator = grey_separator(s);
2906 if (errno != EINVAL && errno != ERANGE)
2907 entry->date_init = t;
2917 if (errno != EINVAL && errno != ERANGE)
2918 entry->date_updt = t;
2925 strlcpy(entry->vip,
STRNULL(argv[ARG_IP],
"0.0.0.0"),
sizeof (entry->vip));
2930 sizeof (entry->hostname));
2931 strlcpy(entry->vhostname,
STRNULL(argv[ARG_HOSTNAME],
"unknown"),
2932 sizeof (entry->vhostname));
2937 sizeof (entry->from));
2939 sizeof (entry->vfrom));
2943 entry->resolve = strcasecmp(argv[
ARG_RESOLVE],
"RESOLVE_OK") == 0;
2961 grey_value_entry2str(s, entry, sz)
2966 if (s == NULL || sz == 0 || entry == NULL)
2976 snprintf(s, sz,
"%ld;%ld;%s;%s;%s;%s;%d;%s",
2978 snprintf(s, sz,
"%ld:%ld:%s:%s:%s:%s:%d:%s",
2985 "FLAGS", entry->
count < 1 ? 1 : entry->
count,
"NULL");
2992 grey_entry_value(s, size, date_init, date_updt, ip, hostname, from, to, count,
3005 if (s == NULL || size == 0)
3008 snprintf(s, size,
"%ld:%ld:%s:%s:%s:%d:%s",
3014 count < 1 ? 1 : count,
STRBOOL(resolve,
"RESOLVE_OK",
"RESOLVE_KO"));
3079 #define SECLEVDOMAINS {"com","org","co","asso","net","gov","edu",NULL} 3081 static bool recursive_compatible_domainnames(
char *da,
char *db,
3085 compatible_domainnames(da, db)
3089 return recursive_compatible_domainnames(da, db, 0);
3094 #define SECLEVDOMAINS {"com","org","co","asso","net","gov","edu",NULL} 3097 recursive_compatible_domainnames(da, db, level)
3106 if (!grey_compat_domain_check)
3111 if (da == NULL || db == NULL)
3114 if (
strchr(da,
'[') != NULL ||
strchr(da,
']') != NULL) {
3118 if (
strchr(db,
'[') != NULL ||
strchr(db,
']') != NULL) {
3123 if ((ta = strdup(da)) == NULL) {
3128 if ((tb = strdup(db)) == NULL) {
3136 if ((p =
strchr(ta,
'@')) != NULL)
3139 if ((p =
strchr(tb,
'@')) != NULL)
3146 int argca, argcb, m;
3155 m =
MIN(argca, argcb);
3158 for (nbe = 0; nbe < m; nbe++)
3159 if (strcasecmp(argva[nbe], argvb[nbe]) != 0)
3164 if (strcasecmp(argva[1], argvb[1]) == 0)
3175 for (p = seclev; *p != NULL; p++) {
3176 if (strcasecmp(argva[1], *p) == 0) {
3199 memset(buf, 0,
sizeof (buf));
3201 if (strlen(buf) > 0) {
3203 for (i = 0; i < argc; i++) {
3204 ok = recursive_compatible_domainnames(db, argv[i], level);
3213 memset(buf, 0,
sizeof (buf));
3215 if (strlen(buf) > 0) {
3217 for (i = 0; i < argc; i++) {
3218 ok = recursive_compatible_domainnames(da, argv[i], level);
#define GREY_DW_NULLSENDER
LISTR_T * zeLinkedList_Add(LISTR_T *, char *, int, void *, size_t)
bool sd_printf(int sd, char *format,...)
bool zeDb_Unlock(ZEDB_T *h)
Database unlock.
void grey_set_compat_domain_check(bool enable)
bool grey_set_cleanup_interval(time_t tclean)
bool zeDb_AddRec(ZEDB_T *h, char *, void *, size_t)
bool zeLinkedList_Clear(LISTR_T *, LISTCLEAR_F)
bool grey_set_tuples(char *ip, char *from, char *to)
bool grey_set_delays(time_t tp_min_norm, time_t tp_max_norm, time_t tp_min_null, time_t tp_max_null)
#define ZE_LogMsgInfo(level,...)
#define DB_BTREE_SEQ_START()
#define ZE_LogMsgError(level,...)
bool zeDb_CursorGetFirst(ZEDB_T *h, char *, size_t, void *, size_t)
bool grey_remove_entry(char *which, char *key)
bool zeStrRegex(char *, char *, long *, long *, bool)
char * extract_email_address(char *, char *, size_t)
bool zeDb_DelRec(ZEDB_T *h, char *)
int grey_check(char *kAddr, char *kFrom, char *kRcpt, char *kName, bool *new, bool can_validate)
#define MIN_CNT_PER_DOMAIN
int zeStr2Tokens(char *, int, char **, char *)
void grey_launch_thread()
bool lookup_policy(char *, char *, char *, size_t, bool)
bool zeDb_Open(ZEDB_T *h, ZEDB_ENV_T *, char *, int, bool, bool, size_t)
bool ipv6_str2rec(ipv6_T *ipv6, char *sin)
int grey_validate(char *kAddr, char *kFrom, char *kRcpt, char *kName)
bool zeDb_Close(ZEDB_T *h)
#define DB_BTREE_SEQ_END()
#define GREY_CRIT_UNLOCK()
bool grey_set_lifetime(time_t tv, time_t tw, time_t tb)
int grey_upload(char *fname, char *which)
#define ZE_MessageInfo(level,...)
bool grey_init(char *workdir, bool rd, int mode)
void log_grey_expire(char *)
bool zeDb_GetRec(ZEDB_T *h, char *, void *, size_t)
char * extract_host_from_email_address(char *, char *, size_t)
#define CF_LOG_GREY_CLEANING
#define ZE_MessageWarning(level,...)
#define ZE_LogSysError(...)
#define ZE_LogSysWarning(...)
bool grey_check_bad_smtp_client(char *ip, uint32_t flags)
bool zeDb_CursorOpen(ZEDB_T *h, bool)
int zeDb_errno(ZEDB_T *h)
void grey_set_dewhite_flags(char *s, bool reset)
bool zeDb_CursorDel(ZEDB_T *h)
#define DB_BTREE_SEQ_CHECK(key, dbname)
#define GREY_DW_DOMAIN_MISMATCH
bool grey_set_max_pending(int nbnormal, int nbnull)
#define GREY_DW_BAD_CLIENT
bool zeDb_CursorClose(ZEDB_T *h)
#define T_EXPIRE_VALID_BAD_MAX
#define GREY_DW_BAD_RESOLVE
#define STRCASEEQUAL(a, b)
unsigned long zeStr2ulong(char *s, int *error, unsigned long dval)
int grey_dbcount(int which)
bool grey_remove_entries_from_file(char *which, char *fname)
void ipv6_prefix_str(ipv6_T *addr, char *buf, size_t size, int n)
int grey_dump(int fd, char *which, time_t dt)
bool grey_remove(int where, char *key)
bool zeDb_CursorGetNext(ZEDB_T *h, char *, size_t, void *, size_t)
bool zeDb_Flush(ZEDB_T *h)
time_t zeStr2time(char *s, int *error, time_t dval)
#define T_EXPIRE_PENDING_BAD_MAX
bool zeDb_Lock(ZEDB_T *h)
Database lock.