ze-filter  (ze-filter-0.8.0-develop-180218)
ze-mailregex.c
Go to the documentation of this file.
1 /*
2  *
3  * ze-filter - Mail Server Filter for sendmail
4  *
5  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
6  *
7  * Auteur : Jose Marcio Martins da Cruz
8  * jose.marcio.mc@gmail.org
9  *
10  * Historique :
11  * Creation : janvier 2002
12  *
13  * This program is free software, but with restricted license :
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * More details about ze-filter license can be found at ze-filter
21  * web site : http://foss.jose-marcio.org
22  */
23 
24 #include <ze-sys.h>
25 
26 #include "ze-filter.h"
27 
28 #undef DEBUG
29 #define DEBUG 0
30 
31 #define LOG_REGEX_IP 1
32 
33 #define REGEX_MAX_LEN 256
34 
35 #define REGCOMP_FLAGS (REG_ICASE | REG_NEWLINE | REG_EXTENDED)
36 
37 #if USE_PCRE
38 #define ZE_PCRE_FLAGS (PCRE_CASELESS | PCRE_DOTALL)
39 #else
40 #define ZE_PCRE_FLAGS (PCRE_CASELESS | PCRE_DOTALL)
41 #endif /* USE_PCRE */
42 
43 #if USE_PCRE
44 static bool use_pcre = TRUE;
45 #else
46 static bool use_pcre = FALSE;
47 #endif /* USE_PCRE */
48 
49 bool log_found_regex(char *, char *, char *, int, int, char *);
50 
51 /* ***************************************************************************
52  * ##### ###### #### ###### # #
53  * # # # # # # # #
54  * # # ##### # ##### ##
55  * ##### # # ### # ##
56  * # # # # # # # #
57  * # # ###### #### ###### # #
58  *****************************************************************************/
59 
60 #define PMATCH_LOCK() MUTEX_LOCK(&p.match.mutex)
61 #define PMATCH_UNLOCK() MUTEX_UNLOCK(&p.match.mutex)
62 
63 /* ***************************************************************************
64  * *
65  * *
66  *****************************************************************************/
67 typedef struct {
68  char action[32];
69  int where;
70  char regex[REGEX_MAX_LEN];
71  char revex[REGEX_MAX_LEN];
72 
73  int score;
74  double lodds;
75 
76  regex_t re;
77  int re_ok;
78 #if USE_PCRE
79  pcre *pcre_rebase;
80  pcre_extra *pcre_rextra;
81  bool pcre_ok;
82 #endif /* USE_PCRE */
83  int count;
84 } RegexRec_T;
85 
86 static zeTbl_T htbl = JTABLE_INITIALIZER;
87 
88 static pthread_mutex_t st_mutex = PTHREAD_MUTEX_INITIALIZER;
89 
90 #define DATA_LOCK() MUTEX_LOCK(&st_mutex)
91 #define DATA_UNLOCK() MUTEX_UNLOCK(&st_mutex)
92 
93 static int db_rurlbl_check(char *, char *, char *, size_t, char *,
94  size_t);
95 
96 static char *ChompDomainName(char *);
97 
98 /* ***************************************************************************
99  * *
100  * *
101  *****************************************************************************/
102 void
104 {
105  RegexRec_T p;
106 
107  printf("*** Regular Expressions lookup table : \n");
108  if (zeTable_Get_First(&htbl, &p) == 0) {
109  printf(" ** WHERE : SCORE - Regular Expression\n");
110  do {
111  printf(" -> %-12s : %5d - /%s/\n", p.action, p.score, p.regex);
112  } while (zeTable_Get_Next(&htbl, &p) == 0);
113  }
114 }
115 
116 /* ***************************************************************************
117  * *
118  * *
119  *****************************************************************************/
120 static int
121 add_regex_rec(vk, vv)
122  void *vk;
123  void *vv;
124 {
125  char *k = (char *) vk;
126  char *v = (char *) vv;
127  RegexRec_T r;
128  int i, j;
129 
130  memset(&r, 0, sizeof (r));
131  if (k == NULL || strlen(k) == 0)
132  return 1;
133  if (v == NULL || strlen(v) == 0)
134  return 1;
135 
136  r.where = MAIL_ANYWHERE;
137  if (strcasecmp(v, "SUBJECT") == 0)
138  r.where = MAIL_SUBJECT;
139  if (strcasecmp(v, "BODY") == 0)
140  r.where = MAIL_BODY;
141  if (strcasecmp(v, "HEADERS") == 0)
142  r.where = MAIL_HEADERS;
143  if (strcasecmp(v, "FROM") == 0)
144  r.where = MAIL_FROM;
145  if (strcasecmp(v, "URLSTR") == 0)
146  r.where = MAIL_URLSTR;
147  if (strcasecmp(v, "URLEXPR") == 0)
148  r.where = MAIL_URLEXPR;
149  if (strcasecmp(v, "HELO") == 0)
150  r.where = MAIL_HELO;
151  if (strcasecmp(v, "EHLO") == 0)
152  r.where = MAIL_HELO;
153  if (strcasecmp(v, "ANYWHERE") == 0)
154  r.where = MAIL_ANYWHERE;
155 
156  r.score = 1;
157 
158  if ((i = strspn(k, "0123456789")) == (j = strcspn(k, " \t"))) {
159  char s[32];
160 
161  if (i > 0) {
162  strlcpy(s, k, sizeof (s));
163 #if HAVE_STRTOL
164  errno = 0;
165  r.score = strtol(k, (char **) NULL, 10);
166  if (errno == ERANGE || errno == EINVAL)
167  r.score = 1;
168 #else
169  r.score = atoi(k);
170 #endif /* HAVE_STRTOL */
171  k += strspn(k, "01234567890");
172  k += strspn(k, " \t");
173  }
174  }
175 
176  strlcpy(r.regex, k, sizeof (r.regex));
177  strlcpy(r.revex, k, sizeof (r.revex));
178  zeStrRev(r.revex);
179 
180  r.re_ok = regcomp(&r.re, r.regex, REGCOMP_FLAGS);
181  if (r.re_ok != 0) {
182  char str[256];
183 
184  regerror(r.re_ok, &r.re, str, sizeof (str));
185  ZE_LogMsgWarning(0, "regcomp error = %s : %s", str, k);
186  return 1;
187  }
188 #if USE_PCRE
189  if (!r.pcre_ok) {
190  const char *errptr = NULL;
191  int erroffset = 0;
192 
193  r.pcre_rebase =
194  pcre_compile(r.regex, ZE_PCRE_FLAGS, &errptr, &erroffset, NULL);
195  if (r.pcre_rebase == NULL)
196  ZE_LogMsgError(0, "pcre_compile error : /%s/ : %s", r.regex,
197  errptr != NULL ? errptr : "(NULL)");
198 
199  if (r.pcre_rebase != NULL) {
200  r.pcre_rextra = pcre_study(r.pcre_rebase, 0, &errptr);
201  if (r.pcre_rextra == NULL) {
202  ZE_LogMsgInfo(12, "pcre_study error : %s",
203  errptr != NULL ? errptr : "(NULL)");
204  }
205  }
206  r.pcre_ok = (r.pcre_rebase != NULL);
207  }
208 #endif /* USE_PCRE */
209 
210  strlcpy(r.action, v, sizeof (r.action));
211 
212  return zeTable_Add(&htbl, &r);
213 }
214 
215 /* ***************************************************************************
216  * *
217  * *
218  *****************************************************************************/
219 static void
220 clear_compiled_regex()
221 {
222  RegexRec_T *q;
223 
224  if ((q = (RegexRec_T *) zeTable_Get_First_Ptr(&htbl)) != NULL) {
225  do {
226  regfree(&q->re);
227 #if USE_PCRE
228  if (q->pcre_rebase != NULL)
229  pcre_free(q->pcre_rebase);
230  if (q->pcre_rextra != NULL)
231  pcre_free(q->pcre_rextra);
232  q->pcre_rebase = NULL;
233  q->pcre_rextra = NULL;
234  q->pcre_ok = FALSE;
235 #endif /* USE_PCRE */
236 
237  } while ((q = (RegexRec_T *) zeTable_Get_Next_Ptr(&htbl)) != NULL);
238  }
239 }
240 
241 /* ***************************************************************************
242  * *
243  * *
244  *****************************************************************************/
245 static bool
246 read_it(path, tag)
247  char *path;
248  char *tag;
249 {
250  int r;
251 
252  r = zm_RdTextFile(path, RD_TWO_COLUMN, RD_REVERSE, tag, add_regex_rec);
253 
254  return r >= 0;
255 }
256 
257 bool
258 load_regex_table(cfdir, fname)
259  char *cfdir;
260  char *fname;
261 {
262  int res = 0;
263  static bool htbl_ok = FALSE;
264  bool result = FALSE;
265 
266  DATA_LOCK();
267 
268  if (htbl_ok == FALSE) {
269  memset(&htbl, 0, sizeof (htbl));
270  res = zeTable_Init(&htbl, sizeof (RegexRec_T), 256, NULL);
271  if (res == 0)
272  htbl_ok = TRUE;
273  }
274 
275  if (res == 0) {
276  clear_compiled_regex();
277  res = zeTable_Clear(&htbl);
278  }
279 
280  if (res == 0)
281  result = read_conf_data_file(cfdir, fname, "ze-regex", read_it);
282 
283  DATA_UNLOCK();
284 
285  return result;
286 }
287 
288 /* ***************************************************************************
289  * *
290  * *
291  *****************************************************************************/
292 #define DIM_VECTOR (3 * 32)
293 
294 int
295 check_regex(id, ip, msg, where)
296  char *id;
297  char *ip;
298  char *msg;
299  int where;
300 {
301  RegexRec_T *q;
302  int result = 0;
303 
304  int score_min = cf_get_int(CF_REGEX_MAX_SCORE);
305 
306  if (msg == NULL || strlen(msg) == 0)
307  return result;
308 
309 #if USE_PCRE
310  use_pcre = TRUE;
311 #endif /* USE_PCRE */
312 
313 
314  DATA_LOCK();
315 
316 
317  if ((q = (RegexRec_T *) zeTable_Get_First_Ptr(&htbl)) != NULL) {
318  do {
319  if ((q->where & where) != 0) {
320  char *ptr = msg;
321  int nb = 0;
322 
323  if (use_pcre) {
324 #if USE_PCRE
325  if (!q->pcre_ok) {
326  const char *errptr = NULL;
327  int erroffset = 0;
328 
329  q->pcre_rebase = pcre_compile(q->regex, ZE_PCRE_FLAGS, &errptr,
330  &erroffset, NULL);
331  if (q->pcre_rebase == NULL)
332  ZE_LogMsgError(0, "pcre_compile error : /%s/ : %s", q->regex,
333  errptr != NULL ? errptr : "(NULL)");
334 
335  if (q->pcre_rebase != NULL) {
336  q->pcre_rextra = pcre_study(q->pcre_rebase, 0, &errptr);
337  if (q->pcre_rextra == NULL) {
338  ZE_LogMsgInfo(12, "pcre_study error : %s", errptr);
339  }
340  }
341  q->pcre_ok = (q->pcre_rebase != NULL);
342  }
343  if (q->pcre_ok) {
344  int ovector[DIM_VECTOR];
345 
346  for (;;) {
347  int rc = 0;
348 
349  if (strlen(ptr) == 0)
350  break;
351 
352  rc = pcre_exec(q->pcre_rebase, q->pcre_rextra, ptr, strlen(ptr),
353  0, 0, ovector, DIM_VECTOR);
354  if (rc < 0)
355  break;
356 
357  ptr += ovector[1];
358  q->count++;
359  if (q->score >= 0)
360  result += q->score;
361  else
362  result++;
363  nb++;
364  if (result >= score_min)
365  break;
366 
367  if (ovector[1] == 0)
368  break;
369 
370  /*
371  * XXX - break if only one is enough
372  */
373  if (1)
374  break;
375  }
376  }
377 #else /* USE_PCRE */
378  ZE_LogMsgError(0,
379  "use_pcre set, but ze-filter wasn't compiled with lib pcre");
380 #endif /* USE_PCRE */
381  } else {
382  regmatch_t rm;
383 
384  if (q->re_ok != 0) {
385  q->re_ok = regcomp(&q->re, q->regex, REGCOMP_FLAGS);
386  if (q->re_ok != 0) {
387  char str[256];
388 
389  regerror(q->re_ok, &q->re, str, sizeof (str));
390  ZE_LogMsgWarning(0, "regcomp error = %s : %s", str, q->regex);
391  break;
392  }
393  }
394  while (regexec(&q->re, ptr, (size_t) 1, &rm, 0) == 0) {
395  ptr += rm.rm_eo;
396  q->count++;
397  if (q->score >= 0)
398  result += q->score;
399  else
400  result++;
401  nb++;
402  if (result >= score_min)
403  break;
404  }
405  }
406 
407  if ((nb > 0) && (result > 0))
408  (void) log_found_regex(id, ip, "REGEX", nb, result, q->regex);
409  if (result >= score_min)
410  break;
411  }
412  } while ((q = (RegexRec_T *) zeTable_Get_Next_Ptr(&htbl)) != NULL);
413  }
414  DATA_UNLOCK();
415 
416  return result;
417 }
418 
419 /* ***************************************************************************
420  * *
421  * # # ###### # ###### #
422  * # # # # # # # #
423  * # # # # # # # #
424  * # # ###### # ###### #
425  * # # # # # # # #
426  * # # # # # # # #
427  * ##### # # ####### ###### #######
428  * *
429  *****************************************************************************/
430 
431 #define URLBL_LOG 12
432 
433 #define DBBL_SCORE 0
434 #define DBBL_DATE 1
435 #define DBBL_RESOLVE 2
436 #define DBBL_ORIGIN 3
437 #define DBBL_DIM 8
438 
439 #define URL_DOMAIN_EXPRESSION "http[s]?://[^ /<>\\(\\)\"\'?]*"
440 #define URL_FULL_EXPRESSION "http[s]?://[^ <>\"\']*"
441 
442 int
444  char *id;
445  char *ip;
446  char *msg;
447 {
448  int result = 0;
449  int score_min = cf_get_int(CF_REGEX_MAX_SCORE);
450 
451  time_t ti = zeTime_ms();
452 
453  if (msg == NULL || strlen(msg) == 0)
454  return result;
455 
456 #if USE_PCRE
457  use_pcre = TRUE;
458 #endif /* USE_PCRE */
459 
460  DATA_LOCK();
461 
462  /*
463  * extract URLs and check domains
464  */
465  {
466  long pi, pf;
467  char *p;
468  LISTR_T *urllist = NULL;
469 
470  p = msg;
471  while (zeStrRegex(p, URL_DOMAIN_EXPRESSION, &pi, &pf, TRUE)) {
472  size_t size = pf - pi + 16;
473  char *buf = NULL;
474  bool alreadydone = FALSE;
475  char *dirurl, *revurl;
476 
477  bool url_found = FALSE;
478 
479  dirurl = revurl = NULL;
480 
481  ZE_MessageInfo(URLBL_LOG + 2, "Hmmm . %s DIR DOMAIN : %s", id, p);
482 
483  if ((buf = (char *) malloc(size)) == NULL) {
484  ZE_LogSysError("malloc(%ld)", (long int ) size);
485  goto url_domain_ok;
486  }
487 
488  memset(buf, 0, size);
489  memcpy(buf, p + pi, pf - pi);
490 
491  {
492  /*
493  ** decode coded URLs on buf
494  */
495  }
496 
497  /*
498  * two empty lines end URL
499  */
500  {
501  long i;
502 
503  if (zeStrRegex(buf, "(\n\n|\r\r|\r\n\r|\n\r\n)", &i, NULL, TRUE))
504  buf[i] = '\0';
505  }
506 
507  /*
508  * delete useless characteres and chomp domainname
509  */
510  {
511  char *q, *r;
512 
513  for (q = r = buf; *q != '\0'; q++) {
514  if (strchr(" \t\n\r", *q) == NULL)
515  *r++ = *q;
516  }
517  *r = '\0';
518 
519  ChompDomainName(buf);
520  }
521 
522  /*
523  * delete port number, if present
524  */
525  {
526  long ia = 0;
527 
528  if (zeStrRegex(buf, ":[0-9]+$", &ia, NULL, TRUE))
529  buf[ia] = '\0';
530  }
531 
532  zeStr2Lower(buf);
533 
534  ZE_MessageInfo(URLBL_LOG + 2, "%s DIR DOMAIN : %s", id, buf);
535  revurl = zeStrDupRev(buf);
536  ZE_MessageInfo(URLBL_LOG + 2, "%s RAW DOMAIN : %s", id, revurl);
537 
538  if (revurl == NULL)
539  goto url_domain_ok;
540 
541  /*
542  ** Extract server name
543  */
544  {
545  char *q;
546 
547  for (q = revurl; *q != '\0'; q++) {
548  if ((*q >= 'A') && (*q <= 'Z'))
549  continue;
550  if ((*q >= 'a') && (*q <= 'z'))
551  continue;
552  if ((*q >= '0') && (*q <= '9'))
553  continue;
554  if (strchr(".-", *q) != NULL)
555  continue;
556  *q = '\0';
557  break;
558  }
559  }
560 
561  ZE_MessageInfo(URLBL_LOG + 2, "%s REV DOMAIN : %s", id, revurl);
562 
563  /*
564  * Check if already handled...
565  */
566  if (!zeLinkedList_Find(urllist, revurl))
567  urllist = zeLinkedList_Add(urllist, revurl, 1, NULL, 0);
568  else
569  alreadydone = TRUE;
570 
571  if (alreadydone)
572  goto url_domain_ok;
573 
574  {
575  RegexRec_T *q;
576 
577  /*
578  ** URLs defined at ze-regex
579  */
580  if ((q = (RegexRec_T *) zeTable_Get_First_Ptr(&htbl)) != NULL) {
581  do {
582  if (q->where == MAIL_URLSTR) {
583  char *sb;
584 
585  sb = q->revex;
586 
587  if (sb != NULL) {
588  if (strncasecmp(revurl, sb, strlen(sb)) == 0) {
589  ZE_MessageNotice(10, "%s URLSTR Found %s", id, q->regex);
590  url_found = TRUE;
591  result += q->score;
592  }
593  }
594 
595  if (url_found && (q->score > 0))
596  (void) log_found_regex(id, ip, "URLSTR", url_found, result,
597  q->regex);
598  if (url_found)
599  break;
600  }
601  } while ((q = (RegexRec_T *) zeTable_Get_Next_Ptr(&htbl)) != NULL);
602  }
603 
604  if (url_found || result >= score_min)
605  goto url_domain_ok;
606 
607  /*
608  ** Check URLBL
609  */
610  if ((dirurl = zeStrDupRev(revurl)) == NULL)
611  ZE_LogSysError("zeStrDupRev(%s)", STRNULL(revurl, "revurl"));
612 
613  /*
614  ** Check URLBL
615  */
616  if (dirurl != NULL) {
617  int v;
618  char *dest = NULL;
619  size_t size;
620 
621  time_t ti = zeTime_ms();
622 
623  char urlbl[64];
624 
625  memset(urlbl, 0, sizeof (urlbl));
626  size = strlen(dirurl) + 1 + 16;
627  dest = (char *) malloc(size);
628  if (dest != NULL)
629  memset(dest, 0, size);
630 
631  if ((v = db_rurlbl_check(id, dirurl, dest, size, urlbl,
632  sizeof (urlbl))) > 0) {
633  result += v;
634 
635  url_found = TRUE;
636  (void) log_found_regex(id, ip, urlbl, 1, result, dest);
637  }
638  ZE_MessageInfo(URLBL_LOG, "%s DB URLBL handling time = %ld ms", id,
639  zeTime_ms() - ti);
640  FREE(dest);
641  }
642 
643  if (url_found || result >= score_min)
644  goto url_domain_ok;
645 
646  /*
647  ** Check DNS RURLBL
648  */
649  if (dirurl != NULL) {
650  time_t ti = zeTime_ms();
651  uint32_t flags;
652 
653  urlbl_T rbl;
654  char *p = dirurl;
655 
656  memset(&rbl, 0, sizeof (rbl));
657 
658 #if 1
659  while (zeStrCountChar(p, '.') > 3) {
660  p = strchr(p, '.');
661  if (p != NULL && *p != '\0')
662  p++;
663  }
664 
665  flags = check_urlbl_table(id, p, &rbl);
666 #else
667  flags = check_urlbl_table(id, dirurl, &rbl);
668 #endif
669  if (flags != 0) {
670  char buf[256];
671 
672  result += rbl.score;
673  url_found = TRUE;
674 
675  snprintf(buf, sizeof (buf), "DNSURLBL:%s", STREMPTY(rbl.bl, ""));
676  (void) log_found_regex(id, ip, buf, 1, result, dirurl);
677  ZE_MessageNotice(9, "%s DNSURLBL : %s : %.1f BLACKLISTED in %s",
678  id, dirurl, rbl.score, rbl.bl);
679  }
680 
681  ZE_MessageInfo(URLBL_LOG, "%s DNS URLBL handling time = %ld ms", id,
682  zeTime_ms() - ti);
683  }
684  if (url_found || result >= score_min)
685  goto url_domain_ok;
686  }
687 
688  url_domain_ok:
689  FREE(dirurl);
690  FREE(revurl);
691  FREE(buf);
692 
693  p += pi + 4;
694  if (result >= score_min)
695  break;
696  }
697  (void) zeLinkedList_Clear(urllist, NULL);
698  }
699 
700  /*
701  * extract URLs and fully check them
702  */
703  if (result < score_min) {
704  long pi, pf;
705  char *p;
706 
707  p = msg;
708  while (zeStrRegex(p, URL_FULL_EXPRESSION, &pi, &pf, TRUE)) {
709  size_t size = pf - pi + 16;
710  char *buf = NULL;
711 
712  if ((buf = (char *) malloc(size)) != NULL) {
713  long i;
714  RegexRec_T *q;
715 
716  memset(buf, 0, size);
717  memcpy(buf, p + pi, pf - pi);
718 
719  /*
720  * two empty lines end URL
721  */
722  if (zeStrRegex(buf, "(\n\n|\r\r|\r\n\r|\n\r\n)", &i, NULL, TRUE))
723  buf[i] = '\0';
724 
725  /*
726  * Check here against MAIL_URLEXPR
727  */
728 
729  /*
730  * To be filled up
731  */
732  if ((q = (RegexRec_T *) zeTable_Get_First_Ptr(&htbl)) != NULL) {
733  do {
734  if (q->where == MAIL_URLEXPR) {
735  bool found = FALSE;
736  char *sb;
737 
738  sb = q->regex;
739  if (sb != NULL) {
740  ZE_MessageInfo(URLBL_LOG + 2, "%s Checking %s against %s", id,
741  buf, q->regex);
742  if (zeStrRegex(buf, sb, NULL, NULL, TRUE)) {
743  ZE_MessageNotice(10, "%s URLEXPR : Found %s", id, q->regex);
744  found = TRUE;
745  result += q->score;
746  }
747  }
748 
749  if (found && (q->score > 0))
750  (void) log_found_regex(id, ip, "URLEXPR", found, result,
751  q->regex);
752 
753  if (found || result >= score_min)
754  break;
755  }
756  } while ((q = (RegexRec_T *) zeTable_Get_Next_Ptr(&htbl)) != NULL);
757  }
758  } else {
759  ZE_LogSysError("malloc(%ld)", (long int ) size);
760  break;
761  }
762 
763  FREE(buf);
764  p += (pi + 4);
765  }
766  }
767 
768  {
769  static int n = 0;
770  char *env = getenv("URLBL_TIMING");
771 
772  if (n < 500 && env != NULL && strcasecmp(env, "yes") == 0) {
773  time_t dt = zeTime_ms() - ti;
774 
775  ZE_MessageInfo(9, "%s URLBL total handling time = %ld ms (%ld)", id, dt,
776  n);
777  }
778 
779  n++;
780  }
781 
782  DATA_UNLOCK();
783 
784  return result;
785 }
786 
787 /* ***************************************************************************
788  * *
789  * *
790  *****************************************************************************/
791 static ZEDB_T hdb = ZEDB_INITIALIZER;
792 
793 bool
795 {
796  bool res = TRUE;
797  char *dbname;
798  char dbpath[1024];
799  char *cfdir = NULL;
800 
801  memset(dbpath, 0, sizeof (dbpath));
802  /*
803  * JOE XXX
804  */
805  cfdir = cf_get_str(CF_CDBDIR);
806  if (cfdir == NULL || strlen(cfdir) == 0)
807  cfdir = ZE_CDBDIR;
808 
809  dbname = cf_get_str(CF_DB_URLBL);
810  ADJUST_FILENAME(dbpath, dbname, cfdir, "ze-urlbl.db");
811 
812  if (zeDb_OK(&hdb))
813  return TRUE;
814 
815  zeDb_Lock(&hdb);
816  if (!zeDb_OK(&hdb))
817  res = zeDb_Open(&hdb, NULL, dbpath, 0444, TRUE, TRUE, 0);
818  zeDb_Unlock(&hdb);
819 
820  return res;
821 }
822 
823 bool
825 {
826  bool res = TRUE;
827 
828  if (!zeDb_OK(&hdb))
829  return TRUE;
830 
831  zeDb_Lock(&hdb);
832  if (zeDb_OK(&hdb))
833  res = zeDb_Close(&hdb);
834  zeDb_Unlock(&hdb);
835 
836  return res;
837 }
838 
839 bool
841 {
842 #if 1
843  bool res = FALSE;
844  char *dbname = NULL;
845  char dbpath[1024];
846  char *cfdir = NULL;
847 
848  memset(dbpath, 0, sizeof (dbpath));
849  /*
850  * JOE XXX
851  */
852  cfdir = cf_get_str(CF_CDBDIR);
853  if (cfdir == NULL || strlen(cfdir) == 0)
854  cfdir = ZE_CDBDIR;
855 
856  dbname = cf_get_str(CF_DB_URLBL);
857  ADJUST_FILENAME(dbpath, dbname, cfdir, "ze-urlbl.db");
858 
859  zeDb_Lock(&hdb);
860  if (zeDb_OK(&hdb))
861  (void) zeDb_Close(&hdb);
862 
863  if (!zeDb_OK(&hdb))
864  res = zeDb_Open(&hdb, NULL, dbpath, 0444, TRUE, TRUE, 0);
865 
866 fin:
867  zeDb_Unlock(&hdb);
868 
869  return res;
870 #else
871  (void) db_close_rurbl_database();
872 
873  return db_open_rurbl_database();
874 #endif
875 }
876 
877 #define MAX_DB_ERROR 16
878 
879 static int
880 db_rurlbl_check(id, url, dest, size, urlbl, szurlbl)
881  char *id;
882  char *url;
883  char *dest;
884  size_t size;
885  char *urlbl;
886  size_t szurlbl;
887 {
888  char key[256], value[256];
889  int res = 0;
890  static int db_error = 0;
891 
892  if ((url == NULL) || (strlen(url) == 0))
893  return 0;
894 
895  if (db_error >= MAX_DB_ERROR)
896  return 0;
897 
898  id = STRNULL(id, "NOID");
899  if (!zeDb_OK(&hdb)) {
900  if (!db_open_rurlbl_database()) {
901  db_error++;
902  return 0;
903  }
904  }
905 
906  db_error = 0;
907 
908  zeDb_Lock(&hdb);
909 
910  {
911  char *p;
912 
913  if ((p = strdup(url)) != NULL) {
914  char *q = p;
915 
916  bool isIPAddr = FALSE;
917 
918  isIPAddr = zeStrRegex(url, IPV4_ADDR_REGEX, NULL, NULL, TRUE);
919 
920  while (strlen(q) > 0) {
921  snprintf(key, sizeof (key), "URLBL:%s", q);
922 
923  ZE_MessageInfo(URLBL_LOG + 2, " Will look for %s", key);
924  if (zeDb_GetRec(&hdb, key, value, sizeof (value))) {
925  char *r = strchr(key, ':');
926 
927  if (r == NULL)
928  r = key;
929  else
930  r++;
931 
932  strlcpy(dest, r, size);
933 
934  ZE_MessageNotice(URLBL_LOG, " Found : %s %s", key, value);
935 
936  {
937  char *s, *ptr;
938  char *fields[DBBL_DIM];
939  int n = 0;
940 
941  n = zeStr2Tokens(value, DBBL_DIM, fields, ":");
942 
943  if (fields[DBBL_SCORE] != NULL) {
944  res = atoi(fields[DBBL_SCORE]);
945  if (res <= 0)
946  res = 1;
947  }
948  if (fields[DBBL_ORIGIN] != NULL) {
949  snprintf(urlbl, szurlbl, "DBURLBL:%s", fields[DBBL_ORIGIN]);
950  ZE_MessageNotice(11, "%s Found in %s", key,
951  STRNULL(urlbl, "--"));
952  }
953  }
954 
955  break;
956  }
957  if (!isIPAddr) {
958  if ((q = strchr(q, '.')) == NULL)
959  break;
960  q++;
961  } else {
962  char *r;
963 
964  if ((r = strrchr(q, '.')) == NULL)
965  break;
966  *r = '\0';
967  }
968 
969  }
970  }
971  FREE(p);
972  }
973 
974  {
975  int level = URLBL_LOG;
976 
977  if (res > 0)
978  level = 9;
979 
980  ZE_MessageNotice(level, "%s DBURLBL : %s : %3d %s in %s", id, url, res,
981  STRBOOL(res > 0, "BLACKLISTED", "OK"), STRNULL(urlbl,
982  "--"));
983  }
984 
985  zeDb_Unlock(&hdb);
986 
987  return res;
988 }
989 
990 /* ****************************************************************************
991  * *
992  * *
993  **************************************************************************** */
994 static char *
995 ChompDomainName(s)
996  char *s;
997 {
998  int n;
999 
1000  if ((s == NULL) || (strlen(s) == 0))
1001  return s;
1002 
1003  n = strlen(s) - 1;
1004 
1005  while ((n = strlen(s)) > 0) {
1006  char c = tolower(s[n - 1]);
1007 
1008  if ((c >= 'a') && (c <= 'z'))
1009  break;
1010  if ((c >= '0') && (c <= '9'))
1011  break;
1012  s[n - 1] = '\0';
1013  }
1014 
1015  return s;
1016 }
int check_regex(char *id, char *ip, char *msg, int where)
Definition: ze-mailregex.c:295
LISTR_T * zeLinkedList_Add(LISTR_T *, char *, int, void *, size_t)
Definition: zeLinkedList.c:34
bool zeDb_Unlock(ZEDB_T *h)
Database unlock.
Definition: zeDb.c:907
#define STRBOOL(x, t, f)
Definition: macros.h:87
char * zeStrRev(char *)
Definition: zeStrings.c:34
#define REGCOMP_FLAGS
Definition: ze-mailregex.c:35
void dump_regex_table()
Definition: ze-mailregex.c:103
#define CF_CDBDIR
Definition: cfh-defs.h:78
bool zeLinkedList_Clear(LISTR_T *, LISTCLEAR_F)
Definition: zeLinkedList.c:195
#define strrchr
Definition: ze-sys.h:219
#define MAIL_URLSTR
Definition: ze-mailregex.h:42
bool zeDb_OK(ZEDB_T *h)
Definition: zeDb.c:649
char revex[REGEX_MAX_LEN]
Definition: ze-mailregex.c:71
#define FREE(x)
Definition: macros.h:37
pcre_extra * pcre_rextra
Definition: ze-mailregex.c:80
#define ZE_CDBDIR
Definition: defs.h:34
#define DATA_LOCK()
Definition: ze-mailregex.c:90
uint64_t zeTime_ms()
Definition: zeTime.c:34
#define STRNULL(x, r)
Definition: macros.h:81
#define ZE_PCRE_FLAGS
Definition: ze-mailregex.c:38
#define ZE_LogMsgInfo(level,...)
Definition: zeSyslog.h:110
Definition: zeDb.h:47
#define FALSE
Definition: macros.h:160
int check_rurlbl(char *id, char *ip, char *msg)
Definition: ze-mailregex.c:443
#define strlcpy
Definition: zeString.h:32
#define ZE_LogMsgError(level,...)
Definition: zeSyslog.h:113
#define ADJUST_FILENAME(path, fname, cfdir, defval)
Definition: macros.h:236
void * zeTable_Get_Next_Ptr(zeTbl_T *)
Definition: zeTable.c:327
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
#define URLBL_LOG
Definition: ze-mailregex.c:431
bool db_open_rurlbl_database()
Definition: ze-mailregex.c:794
void * zeTable_Get_First_Ptr(zeTbl_T *)
Definition: zeTable.c:305
int cf_get_int(int id)
Definition: ze-cf.c:803
int zeStr2Tokens(char *, int, char **, char *)
Definition: zeStrings.c:610
bool load_regex_table(char *cfdir, char *fname)
Definition: ze-mailregex.c:258
bool read_conf_data_file(char *cfdir, char *fname, char *dfile, read_conf_data_file_F func)
#define strchr
Definition: ze-sys.h:218
#define JTABLE_INITIALIZER
Definition: zeTable.h:44
bool zeDb_Open(ZEDB_T *h, ZEDB_ENV_T *, char *, int, bool, bool, size_t)
Definition: zeDb.c:462
double lodds
Definition: ze-mailregex.c:74
int zeTable_Clear(zeTbl_T *)
Definition: zeTable.c:136
#define DBBL_DIM
Definition: ze-mailregex.c:437
#define ZE_MessageNotice(level,...)
Definition: zeSyslog.h:91
regex_t re
Definition: ze-mailregex.c:76
bool zeDb_Close(ZEDB_T *h)
Definition: zeDb.c:667
char action[32]
Definition: ze-mailregex.c:68
int zeTable_Add(zeTbl_T *, void *)
Definition: zeTable.c:155
int zm_RdTextFile(char *, int, int, char *, int(*)(void *, void *))
#define MAIL_BODY
Definition: ze-mailregex.h:37
int zeTable_Get_First(zeTbl_T *, void *)
Definition: zeTable.c:250
char bl[64]
Definition: ze-dns-urlbl.h:36
char * zeStrDupRev(char *)
Definition: zeStrings.c:59
uint32_t check_urlbl_table(char *id, char *name, urlbl_T *bl)
Definition: ze-dns-urlbl.c:440
#define MAX_DB_ERROR
Definition: ze-mailregex.c:877
#define URL_DOMAIN_EXPRESSION
Definition: ze-mailregex.c:439
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
int nb
Definition: ze-connopen.c:61
bool zeDb_GetRec(ZEDB_T *h, char *, void *, size_t)
Definition: zeDb.c:791
#define RD_REVERSE
Definition: ze-rdfile.h:30
#define TRUE
Definition: macros.h:157
#define MAIL_SUBJECT
Definition: ze-mailregex.h:38
int zeStrCountChar(char *, int)
Definition: zeStrings.c:202
#define REGEX_MAX_LEN
Definition: ze-mailregex.c:33
bool log_found_regex(char *, char *, char *, int, int, char *)
Definition: ze-log-regex.c:79
#define memcpy(d, s, n)
Definition: ze-sys.h:224
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
char * cf_get_str(int id)
Definition: ze-cf.c:854
#define DBBL_SCORE
Definition: ze-mailregex.c:433
int zeTable_Get_Next(zeTbl_T *, void *)
Definition: zeTable.c:277
#define CF_DB_URLBL
Definition: cfh-defs.h:114
#define STREMPTY(x, r)
Definition: macros.h:82
#define URL_FULL_EXPRESSION
Definition: ze-mailregex.c:440
#define DIM_VECTOR
Definition: ze-mailregex.c:292
#define ZE_LogMsgWarning(level,...)
Definition: zeSyslog.h:112
LISTR_T * zeLinkedList_Find(LISTR_T *, char *)
Definition: zeLinkedList.c:172
#define MAIL_ANYWHERE
Definition: ze-mailregex.h:36
int zeTable_Init(zeTbl_T *, size_t, int, int(*)(const void *, const void *))
#define CF_REGEX_MAX_SCORE
Definition: cfh-defs.h:118
char * zeStr2Lower(char *)
Definition: zeStrings.c:295
bool db_close_rurbl_database()
Definition: ze-mailregex.c:824
#define MAIL_HELO
Definition: ze-mailregex.h:40
#define MAIL_URLEXPR
Definition: ze-mailregex.h:43
#define MAIL_HEADERS
Definition: ze-mailregex.h:39
pcre * pcre_rebase
Definition: ze-mailregex.c:79
#define MAIL_FROM
Definition: ze-mailregex.h:41
#define DBBL_ORIGIN
Definition: ze-mailregex.c:436
double score
Definition: ze-dns-urlbl.h:45
bool db_reopen_rurlbl_database()
Definition: ze-mailregex.c:840
#define IPV4_ADDR_REGEX
Definition: macros.h:218
#define RD_TWO_COLUMN
Definition: ze-rdfile.h:27
bool pcre_ok
Definition: ze-mailregex.c:81
char regex[REGEX_MAX_LEN]
Definition: ze-mailregex.c:70
#define ZEDB_INITIALIZER
Definition: zeDb.h:111
long uint32_t
Definition: ze-sys.h:489
int msg[MAX_SCORE+2]
Definition: ze-stats.c:41
#define DATA_UNLOCK()
Definition: ze-mailregex.c:91
bool zeDb_Lock(ZEDB_T *h)
Database lock.
Definition: zeDb.c:896