ze-filter  (ze-filter-0.8.0-develop-180218)
ze-callbackchecks.c
Go to the documentation of this file.
1 
2 /*
3  *
4  * ze-filter - Mail Server Filter for sendmail
5  *
6  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
7  *
8  * Auteur : Jose Marcio Martins da Cruz
9  * jose.marcio.mc@gmail.org
10  *
11  * Historique :
12  * Creation : Mon Nov 15 23:04:23 CET 2004
13  *
14  * This program is free software, but with restricted license :
15  *
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * More details about ze-filter license can be found at ze-filter
22  * web site : http://foss.jose-marcio.org
23  */
24 
25 #include <ze-sys.h>
26 #include <ze-filter.h>
27 #include <ze-filter-data.h>
28 #include <ze-spool.h>
29 #include <ze-callbackchecks.h>
30 
31 static bool check_condition(char *cond,
32  char *header, msg_scores_T * scoreRec);
33 
34 
35 /* ****************************************************************************
36  * *
37  * *
38  ******************************************************************************/
39 
40 int
42  SMFICTX *ctx;
43 {
44  CTXPRIV_T *priv = MLFIPRIV(ctx);
45  int nbad = 0;
46  char *sbad = NULL;
47  static bool macro_error_logged = FALSE;
48 
49  ASSERT(ctx != NULL);
50  ASSERT(priv != NULL);
51 
52  if (IS_KNOWN(priv->netclass.class))
53  return 0;
54 
55  nbad = priv->dbrcpt_msg_unknown + priv->dbrcpt_access + priv->dbrcpt_reject +
57  priv->nb_mbadrcpt = nbad;
58 
59  return nbad;
60 }
61 
62 
63 /* ****************************************************************************
64  * *
65  * *
66  ******************************************************************************/
67 bool
68 check_helo_myself(ip, hostname, helo)
69  char *ip;
70  char *hostname;
71  char *helo;
72 {
73  char *myself = cf_get_str(CF_MYSELF);
74  char *s, *ptr, *x = NULL;
75 
76  if (myself != NULL) {
77  if ((x = strdup(myself)) != NULL) {
78  for (s = strtok_r(x, " ", &ptr); s != NULL; s = strtok_r(NULL, " ", &ptr)) {
79  /*
80  * s
81  */
82 
83  }
84  } else
85  ZE_LogSysError("strdup(%s) error", myself);
86  FREE(x);
87  }
88 
89  return TRUE;
90 }
91 
92 
93 /* ****************************************************************************
94  * *
95  * *
96  ******************************************************************************/
97 bool
98 passport_ok(to, key)
99  char *to;
100  char *key;
101 {
102  long pi, pf;
103  bool ok = FALSE;
104 
105  if (zeStrRegex(to, "[+][0-9]{6,6}-.+@", &pi, &pf, TRUE)) {
106  time_t now;
107  struct tm tm;
108  char tstr[64];
109  char buf[64];
110  char *ri;
111 
112  memset(tstr, 0, sizeof (tstr));
113 
114  ri = to + pi;
115 
116  now = time(NULL);
117  if (gmtime_r(&now, &tm) == NULL)
118  goto fin;
119  (void) strftime(tstr, sizeof (tstr), "+%d%m%y-", &tm);
120  if (strncasecmp(ri, tstr, strlen(tstr)) == 0)
121  ok = TRUE;
122 
123  if (!ok) {
124  now -= 86400;
125  if (gmtime_r(&now, &tm) == NULL)
126  goto fin;
127  (void) strftime(tstr, sizeof (tstr), "+%d%m%y-", &tm);
128  if (strncasecmp(ri, tstr, strlen(tstr)) == 0)
129  ok = TRUE;
130  }
131  if (!ok)
132  goto fin;
133 
134  ri += strlen("+DDMMYY-");
135 
136  if (check_policy("Passport", ri, buf, sizeof (buf), FALSE))
137  ok = (strcasecmp(buf, "OK") == 0);
138  }
139 
140 fin:
141  return ok;
142 }
143 
144 /* ****************************************************************************
145  * *
146  * *
147  ******************************************************************************/
148 bool
150  SMFICTX *ctx;
151 {
152  CTXPRIV_T *priv = MLFIPRIV(ctx);
153  int ip_class = priv->netclass.class;
154  bool doit = TRUE;
155 
156  if (priv == NULL)
157  return FALSE;
158 
159 #if 0
160  if (priv->peer_addr != NULL && STREQUAL(priv->peer_addr, "127.0.0.1"))
161  return FALSE;
162 #endif
163 
164  if ((cf_get_int(CF_SPAM_REGEX) == OPT_NO) &&
168  return FALSE;
169 
170  doit =
171  check_policy_all_rcpts("ContentCheck", priv->peer_addr, priv->peer_name,
172  CTX_NETCLASS_LABEL(priv),
173  priv->env_from, priv->env_rcpt, TRUE, OPT_DEFAULT);
174 
175  return doit;
176 }
177 
178 /* ****************************************************************************
179  * *
180  * *
181  ******************************************************************************/
182 bool
184  SMFICTX *ctx;
185 {
186  CTXPRIV_T *priv = MLFIPRIV(ctx);
187  int ip_class = priv->netclass.class;
188  bool doit = TRUE;
189 
190  if (cf_get_int(CF_XFILES) == OPT_OK)
191  return FALSE;
192 
193  doit = check_policy_all_rcpts("XFilesCheck", priv->peer_addr, priv->peer_name,
194  CTX_NETCLASS_LABEL(priv),
195  priv->env_from, priv->env_rcpt, TRUE,
196  OPT_DEFAULT);
197 
198  return doit;
199 }
200 
201 /* ****************************************************************************
202  * *
203  * *
204  ******************************************************************************/
205 bool
207  SMFICTX *ctx;
208 {
209  CTXPRIV_T *priv = MLFIPRIV(ctx);
210  int ip_class = priv->netclass.class;
211  bool doit = TRUE;
212 
214  return FALSE;
215 
216  doit = check_policy_all_rcpts("VirusCheck", priv->peer_addr, priv->peer_name,
217  CTX_NETCLASS_LABEL(priv),
218  priv->env_from, priv->env_rcpt, TRUE,
219  OPT_DEFAULT);
220 
221  return doit;
222 }
223 
224 /* ****************************************************************************
225  * *
226  * *
227  ******************************************************************************/
228 bool
230  SMFICTX *ctx;
231  char *rcpt;
232 {
233  CTXPRIV_T *priv = MLFIPRIV(ctx);
234  bool doit = FALSE;
235 
236  if (priv == NULL)
237  return FALSE;
238 
239  doit = check_policy_all_rcpts("Archive", priv->peer_addr, priv->peer_name,
240  CTX_NETCLASS_LABEL(priv),
241  priv->env_from, priv->env_rcpt, FALSE,
242  OPT_ONE_WIN);
243 
244  return doit;
245 }
246 
247 /* ****************************************************************************
248  * *
249  * *
250  ******************************************************************************/
251 bool
253  char *da;
254  char *db;
255 {
256  int le;
257  int n;
258 
259  if ((da == NULL) || (db == NULL))
260  return TRUE;
261 
262  if (strcasecmp(da, db) == 0)
263  return TRUE;
264 
265  le = zeStrlEqual(da, db);
266  if (le == 0)
267  return FALSE;
268 
269  n = strcspn(da, ".");
270  if (le <= n + 1)
271  return FALSE;
272 
273  return TRUE;
274 }
275 
276 /* ****************************************************************************
277  * *
278  * *
279  ******************************************************************************/
280 bool
282  char *from;
283 {
284  if (from == NULL)
285  return FALSE;
286  if (zeStrRegex(from, NULLSENDER, NULL, NULL, TRUE))
287  return TRUE;
288  if (zeStrRegex(from, "postmaster@", NULL, NULL, TRUE))
289  return TRUE;
290  if (zeStrRegex(from, "mailer-daemon@", NULL, NULL, TRUE))
291  return TRUE;
292  return FALSE;
293 }
294 
295 /* ****************************************************************************
296  * *
297  * *
298  ******************************************************************************/
299 int
300 check_valid_postmaster(env_from, from, nbrcpt)
301  char *env_from;
302  char *from;
303  int nbrcpt;
304 {
305  if ((env_from == NULL) || (from == NULL))
306  return NOT_POSTMASTER;
307 
308  if (!enveloppe_postmaster(env_from))
309  return NOT_POSTMASTER;
310 
311  if (nbrcpt > 1)
312  return POSTMASTER_FORGED;
313 
314  if (zeStrRegex(from, "postmaster@", NULL, NULL, TRUE))
315  return POSTMASTER_OK;
316  if (zeStrRegex(from, "root@", NULL, NULL, TRUE))
317  return POSTMASTER_OK;
318  if (zeStrRegex(from, "mailer-daemon@", NULL, NULL, TRUE))
319  return POSTMASTER_OK;
320 
321  return POSTMASTER_FORGED;
322 }
323 
324 /* ****************************************************************************
325  * *
326  * *
327  ******************************************************************************/
328 sfsistat
330  SMFICTX *ctx;
331 {
332  CTXPRIV_T *priv = MLFIPRIV(ctx);
333  int result = SMFIS_CONTINUE;
334  size_t maxsize;
335 
336  int ip_class;
337  int postmaster = 0;
338 
339  spamchk_T *checks = NULL;
340  msg_flags_T flags;
341 
342  ASSERT(priv != NULL);
343 
344  ip_class = priv->netclass.class;
345 
346  memset(&flags, 0, sizeof (flags));
347  if (!shall_check_content(ctx))
348  return SMFIS_CONTINUE;
349 
353 
354  if (!priv->rawScores.do_regex && !priv->rawScores.do_oracle
355  && !priv->rawScores.do_urlbl)
356  return SMFIS_CONTINUE;
357 
358  priv->rawScores.oracle = 0;
359 
361 
362  checks = &priv->spamchk;
363 
364  checks->scores = priv->rawScores;
365  checks->ip = priv->peer_addr;
366  checks->id = priv->id;
367  checks->nb_badrcpt = priv->nb_mbadrcpt;
368  checks->hdrs = priv->headers;
369 
370  /*
371  ** Some preliminary oracle checks...
372  */
373 
374  /*
375  * check postmaster... XXX
376  */
377  postmaster =
379 
380  if (priv->rawScores.do_oracle) {
381  switch (priv->resolve_res) {
382  case RESOLVE_FAIL:
385  ZE_MessageInfo(10, "%s SPAM CHECK - C%02d SMTP client resolve failed",
387  break;
388  case RESOLVE_FORGED:
391  ZE_MessageInfo(10, "%s SPAM CHECK - C%02d SMTP client resolve forged",
393  break;
394  case RESOLVE_TEMPFAIL:
397  ZE_MessageInfo(10,
398  "%s SPAM CHECK - C%02d SMTP client resolve tempfail",
400  break;
401  default:
402  break;
403  }
404 
405  if (priv->rbwl.odds > 1) {
406  SET_BIT(checks->flags.conn, SPAM_CONN_RBL);
407 
408  ZE_MessageInfo(10, "%s SPAM CHECK - C%02d SMTP client blacklisted %s %s",
409  CONNID_STR(priv->id), SPAM_CONN_RBL,
410  priv->peer_addr, priv->peer_name);
411  }
412 
413  if ((strcasecmp(priv->peer_name, "localhost") == 0) &&
414  (strcasecmp(priv->peer_addr, "127.0.0.1") != 0)) {
417  ZE_MessageInfo(10,
418  "%s SPAM CHECK - C%02d false DNS declared localhost %s/%s ",
420  priv->peer_addr, priv->peer_name);
421  }
422 
423  switch (postmaster) {
424  case POSTMASTER_OK:
425  break;
426  case POSTMASTER_FORGED:
427  if (IS_UNKNOWN(ip_class)) {
430  ZE_MessageInfo(10, "%s SPAM CHECK - M%02d Forged postmaster",
432  }
433  break;
434  default:
435  break;
436  }
437 
438  if (checks->nb_badrcpt > 0) {
441  ZE_MessageInfo(10,
442  "%s SPAM CHECK - M%02d message with bad recipients (%d)",
444  checks->nb_badrcpt);
445  }
446 
447  if (priv->dbrcpt_conn_spamtrap > 0) {
450  ZE_MessageInfo(10,
451  "%s SPAM CHECK - M%02d message with spamtrap rcpt (%d)",
453  priv->dbrcpt_conn_spamtrap);
454  }
455 
456  if (IS_UNKNOWN(ip_class)) {
457  if (priv->msg_size < 16) {
460  ZE_MessageInfo(10,
461  "%s SPAM CHECK - M%02d too short message - length = %d",
463  priv->msg_size);
464  }
465  }
466 
467  if (IS_UNKNOWN(ip_class)) {
468  int n;
469 
470  if ((n = livehistory_check_host(priv->peer_addr, 3600, LH_SPAMTRAP)) > 0) {
473  ZE_MessageInfo(10,
474  "%s SPAM CHECK - M%02d client sending to spamtrap (%d)",
475  CONNID_STR(priv->id), SPAM_CONN_BL_SPAMTRAP, n);
476  }
477  }
478 
479  {
480  if ((priv->env_nb_rcpt > 1) && (strstr(priv->env_from, "<>") != NULL)) {
483  ZE_MessageInfo(10, "%s SPAM CHECK - M%02d NULL sender with %d RCPTS",
485  priv->env_nb_rcpt);
486  }
487  }
488 
489  }
490 
491  /*
492  ** Evaluate message scores
493  */
494  (void) scan_body_contents(CONNID_STR(priv->id),
495  priv->peer_addr, priv->fname, maxsize, checks,
496  &flags, &priv->rawScores);
497  priv->rawScores = checks->scores;
498 
499  return result;
500 }
501 
502 /* ****************************************************************************
503  * *
504  * *
505  ******************************************************************************/
506 #define BCONDSZ 512
507 
508 static bool
509 check_condition(cond, header, rScore)
510  char *cond;
511  char *header;
512  msg_scores_T *rScore;
513 {
514  bool result = FALSE;
515  char *s = NULL;
516  char buf[BCONDSZ];
517  char *argv[32];
518  int argc;
519  int i;
520 
521  if (cond == NULL || strlen(cond) == 0)
522  goto fin;
523 
524  {
525  char *p = cond;
526  int i;
527 
528  for (p = cond, i = 0; *p != '\0' && i < BCONDSZ - 1; p++) {
529  if (*p != ' ')
530  buf[i++] = *p;
531  }
532  buf[i] = '\0';
533  }
534  argc = zeStr2Tokens(buf, 32, argv, ";");
535  for (i = 0; i < argc && !result; i++) {
536  char *pcond;
537 
538  pcond = argv[i];
539 
540  ZE_MessageInfo(19, "Checking %2d %s", i, pcond);
541 
542  if (rScore != NULL) {
543  s = "score";
544  if (STRNCASEEQUAL(pcond, s, strlen(s))) {
545  double value;
546 
547  pcond += strlen(s);
548  if (*pcond == '\0')
549  continue;
550 
551  errno = 0;
552  value = strtod(pcond + 1, NULL);
553  if (errno != 0)
554  continue;
555  switch (*pcond) {
556  case '>':
557  if ((double) rScore->combined > value)
558  result = TRUE;
559  break;
560  case '<':
561  if ((double) rScore->combined < value)
562  result = TRUE;
563  break;
564  }
565 
566  if (result)
567  break;
568  continue;
569  }
570 
571  s = "bayes";
572  if (STRNCASEEQUAL(pcond, s, strlen(s))) {
573  double value;
574 
575  pcond += strlen(s);
576  if (*pcond == '\0')
577  continue;
578 
579  errno = 0;
580  value = strtod(pcond + 1, NULL);
581  if (errno != 0)
582  continue;
583  switch (*pcond) {
584  case '>':
585  if ((double) rScore->bayes > value)
586  result = TRUE;
587  break;
588  case '<':
589  if ((double) rScore->bayes < value)
590  result = TRUE;
591  break;
592  }
593 
594  if (result)
595  break;
596  continue;
597  }
598 
599  s = "regex+urlbl";
600  if (STRNCASEEQUAL(pcond, s, strlen(s))) {
601  double value;
602 
603  pcond += strlen(s);
604  if (*pcond == '\0')
605  continue;
606 
607  errno = 0;
608  value = strtod(pcond + 1, NULL);
609  if (errno != 0)
610  continue;
611 
612  switch (*pcond) {
613  case '>':
614  if ((double) (rScore->body + rScore->headers + rScore->urlbl) >
615  value)
616  result = TRUE;
617  break;
618  case '<':
619  if ((double) (rScore->body + rScore->headers + rScore->urlbl) <
620  value)
621  result = TRUE;
622  break;
623  }
624 
625  if (result)
626  break;
627  continue;
628  }
629 
630  s = "urlbl+regex";
631  if (STRNCASEEQUAL(pcond, s, strlen(s))) {
632  double value;
633 
634  pcond += strlen(s);
635  if (*pcond == '\0')
636  continue;
637 
638  errno = 0;
639  value = strtod(pcond + 1, NULL);
640  if (errno != 0)
641  continue;
642 
643  switch (*pcond) {
644  case '>':
645  if ((double) (rScore->body + rScore->headers + rScore->urlbl) >
646  value)
647  result = TRUE;
648  break;
649  case '<':
650  if ((double) (rScore->body + rScore->headers + rScore->urlbl) <
651  value)
652  result = TRUE;
653  break;
654  }
655 
656  if (result)
657  break;
658  continue;
659  }
660 
661  s = "urlbl";
662  if (STRNCASEEQUAL(pcond, s, strlen(s))) {
663  double value;
664 
665  pcond += strlen(s);
666  if (*pcond == '\0')
667  continue;
668 
669  errno = 0;
670  value = strtod(pcond + 1, NULL);
671  if (errno != 0)
672  continue;
673 
674  switch (*pcond) {
675  case '>':
676  if ((double) rScore->urlbl > value)
677  result = TRUE;
678  break;
679  case '<':
680  if ((double) rScore->urlbl < value)
681  result = TRUE;
682  break;
683  }
684 
685  if (result)
686  break;
687  continue;
688  }
689 
690  s = "regex";
691  if (STRNCASEEQUAL(pcond, s, strlen(s))) {
692  double value;
693 
694  pcond += strlen(s);
695  if (*pcond == '\0')
696  continue;
697 
698  errno = 0;
699  value = strtod(pcond + 1, NULL);
700  if (errno != 0)
701  continue;
702 
703  switch (*pcond) {
704  case '>':
705  if ((double) (rScore->body + rScore->headers) > value)
706  result = TRUE;
707  break;
708  case '<':
709  if ((double) (rScore->body + rScore->headers) < value)
710  result = TRUE;
711  break;
712  }
713 
714  if (result)
715  break;
716  continue;
717  }
718  }
719 
720  s = "header~";
721  if (STRNCASEEQUAL(pcond, s, strlen(s))) {
722  pcond += strlen(s);
723  if (*pcond == '\0')
724  continue;
725 
726  if (zeStrRegex(header, pcond, NULL, NULL, TRUE))
727  result = TRUE;
728 
729  if (result)
730  break;
731  continue;
732  }
733 
734  if (header != NULL || strlen(header) > 0) {
735  if (zeStrRegex(header, pcond, NULL, NULL, TRUE))
736  result = TRUE;
737  }
738  }
739 
740 fin:
741  return result;
742 }
743 
744 /* ****************************************************************************
745  * *
746  * *
747  ******************************************************************************/
748 sfsistat
750  SMFICTX *ctx;
751  bool *do_log;
752 {
753  CTXPRIV_T *priv = MLFIPRIV(ctx);
754  int result = SMFIS_CONTINUE;
755  bool log_it = FALSE;
756 
757  msg_scores_T rScores;
758  scores_scale_T scale;
759 
760  char sbufold[256], sbufnew[256];
761  char sScoreStr[32];
762 
763  ASSERT(priv != NULL);
764 
765  memset(sbufold, 0, sizeof (sbufold));
766  memset(sbufnew, 0, sizeof (sbufnew));
767  memset(sScoreStr, 0, sizeof (sScoreStr));
768 
769  memset(&rScores, 0, sizeof (rScores));
770  fill_msg_scale(&scale);
771 
772  if (do_log != NULL)
773  *do_log = FALSE;
774 
775  /*
776  * Compute oracle score...
777  */
778  if (priv->rawScores.do_oracle)
780  else
781  priv->rawScores.oracle = 0;
782 
783  if (!priv->rawScores.do_urlbl)
784  priv->rawScores.urlbl = 0;
785 
786  if (!priv->rawScores.do_regex) {
787 #if 1
788  if (priv->rawScores.body + priv->rawScores.headers > 0)
789  priv->rawScores.do_regex = TRUE;
790 #else
791  priv->rawScores.body = 0;
792  priv->rawScores.headers = 0;
793 #endif
794  }
795 
796  if (priv->rawScores.bayes < 0)
797  priv->rawScores.bayes = 0.;
798 
799 #if 0 && _FFR_MODULES
800  /*
801  ** ze-filter modules
802  **
803  */
804  if (do_module_callback(ctx, 0, &result))
805  goto fin;
806  if (result != SMFIS_CONTINUE)
807  goto fin;
808 #endif /* _FFR_MODULES */
809 
810  if (!
811  (priv->rawScores.do_regex || priv->rawScores.do_oracle
812  || priv->rawScores.do_bayes || priv->rawScores.do_urlbl))
813  goto fin;
814 
815  /*
816  ** Score evaluation
817  **
818  */
819  {
820  double score = 0.;
821  char *hname = NULL;
822 
823  hname = sm_macro_get_str(priv->sm, "j");
824  hname = STREMPTY(hname, my_hostname);
825 
826  priv->rawScores.scale = scale;
827  rScores = priv->rawScores;
828  score = compute_msg_score(&rScores);
829  priv->rawScores = rScores;
830 
831  (void) create_msg_score_header(sbufnew, sizeof (sbufnew),
832  CONNID_STR(priv->id), hname, &rScores);
833 
834  smfi_addheader(ctx, "X-ze-filter-Score", sbufnew);
836  FREE(priv->score_str);
837  if ((priv->score_str = strdup(sbufnew)) == NULL)
838  ZE_LogSysError("strdup(%s)", sbufnew);
839  }
840 
841  {
842  char *xspam = NULL;
843  bool doit = FALSE;
844  char *xstatus = NULL;
845 
847  doit = check_condition(xspam, sbufold, &priv->rawScores);
848  if (doit) {
849 #if 0
850  if ((priv->score_str = strdup(sbufnew)) == NULL)
851  ZE_LogSysError("strdup(%s)", sbufnew);
852 #endif
853  DO_QUARANTINE_MESSAGE(priv, WHY_SPAM, NULL);
854  priv->rej_regex++;
855  result = SMFIS_DISCARD;
856  log_it = TRUE;
857  if (do_log != NULL)
858  *do_log = TRUE;
859  priv->rawScores.spam = TRUE;
860 
861  goto fin;
862  }
863 
865  doit = check_condition(xspam, sbufold, &priv->rawScores);
866  if (doit) {
867  (void) jsmfi_setreply(ctx, "550", "5.7.1", MSG_BODY_CONTENTS);
868  priv->rej_regex++;
869  result = SMFIS_REJECT;
870  log_it = TRUE;
871  if (do_log != NULL)
872  *do_log = TRUE;
873  priv->rawScores.spam = TRUE;
874 
875  goto fin;
876  }
877 
878  xstatus = cf_get_str(CF_XSTATUS_HEADER);
879  if (xstatus == NULL || strlen(xstatus) == 0)
880  xstatus = "X-ze-filter-Status";
881 
883  doit = check_condition(xspam, sbufold, &priv->rawScores);
884  if (doit) {
885  smfi_addheader(ctx, xstatus, "Spam HI");
886  FREE(priv->status_str);
887  if ((priv->status_str = strdup("Spam HI")) == NULL)
888  ZE_LogSysError("strdup(%s)", "Spam HI");
889 
890  /*
891  * add tag to subject ???
892  */
894  char *tag = cf_get_str(CF_SCORE_ON_SUBJECT_TAG);
895  char buf[32];
896  char *p = NULL;
897 
898  if (tag == NULL || strlen(tag) == 0) {
899  snprintf(buf, sizeof (buf), "[J-%s]", sScoreStr);
900  p = buf;
901  } else
902  p = tag;
903 
904  ZE_MessageInfo(12, "Adding tag %s to subject", p);
905  add_tag2subject(ctx, p);
906  }
907  log_it = TRUE;
908  if (do_log != NULL)
909  *do_log = TRUE;
910  priv->rawScores.spam = TRUE;
911 
912  goto ok;
913  }
914 
916  doit = check_condition(xspam, sbufold, &priv->rawScores);
917  if (doit) {
918  smfi_addheader(ctx, xstatus, "Spam LO");
919  FREE(priv->status_str);
920  if ((priv->status_str = strdup("Spam LO")) == NULL)
921  ZE_LogSysError("strdup(%s)", "Spam LO");
922  log_it = TRUE;
923  if (do_log != NULL)
924  *do_log = TRUE;
925  goto ok;
926  }
927 
929  doit = check_condition(xspam, sbufold, &priv->rawScores);
930  if (doit) {
931  smfi_addheader(ctx, xstatus, "Unsure");
932  FREE(priv->status_str);
933  if ((priv->status_str = strdup("Unsure")) == NULL)
934  ZE_LogSysError("strdup(%s)", "Unsure");
935  log_it = TRUE;
936  if (do_log != NULL)
937  *do_log = TRUE;
938  goto ok;
939  }
940 
942  doit = check_condition(xspam, sbufold, &priv->rawScores);
943  if (doit) {
944  smfi_addheader(ctx, xstatus, "Ham");
945  FREE(priv->status_str);
946  if ((priv->status_str = strdup("Ham")) == NULL)
947  ZE_LogSysError("strdup(%s)", "Ham");
948 #if 1
949  if (do_log != NULL)
950  *do_log = TRUE;
951 #endif /* XXX */
952  goto ok;
953  }
954  }
955 
956 ok:
957  ;
958 
959 fin:
960  /*
961  * update stats
962  */
963  if (priv->rawScores.do_regex && (priv->rawScores.body > 0))
965 
966  if (priv->rawScores.do_urlbl && (priv->rawScores.urlbl > 0))
967  stats_inc(STAT_URLBL, 1);
968 
969  if (priv->rawScores.do_oracle && (priv->rawScores.oracle > 0)) {
970  priv->nb_oracle++;
972  }
973 
974  if (priv->rawScores.do_bayes) {
975  if (priv->rawScores.bayes > BSCORE_HI)
977  if (priv->rawScores.bayes < BSCORE_LO)
979  if (priv->rawScores.bayes >= BSCORE_LO
980  && priv->rawScores.bayes <= BSCORE_HI)
982  }
983 
984  if (priv->rawScores.spam)
985  priv->nb_spams++;
986 
987 #if 0
988  if (log_it && ze_logLevel >= 8) {
989  char logbuf[256];
990 
991  snprintf(logbuf, sizeof (logbuf), "%s : B=%.3f U=%d R=%d O=%d -> G=%.3f",
992  "Content Check",
993  priv->rawScores.bayes, priv->rawScores.urlbl,
994  priv->rawScores.body + priv->rawScores.headers,
995  priv->rawScores.oracle, priv->rawScores.combined);
996 
997  log_msg_context(ctx, logbuf);
998  }
999 #if 0
1000  (void) smtprate_add_entry(RATE_SCORE, priv->peer_addr, priv->peer_name,
1001  gScore, time(NULL));
1002 #endif
1003  (void) smtprate_add_entry(RATE_SPAM, priv->peer_addr, priv->peer_name,
1004  priv->rawScores.bayes > BSCORE_HI ? 1 : 0,
1005  time(NULL));
1006  (void) smtprate_add_entry(RATE_HAM, priv->peer_addr, priv->peer_name,
1007  priv->rawScores.bayes < BSCORE_LO ? 1 : 0,
1008  time(NULL));
1009 #endif
1010 
1011  return result;
1012 }
1013 
1014 
1015 /* ****************************************************************************
1016  * *
1017  * *
1018  ******************************************************************************/
1019 bool
1020 check_spamtrap_rcpt(id, ip, from, rcpt, ip_class)
1021  char *id;
1022  char *ip;
1023  char *from;
1024  char *rcpt;
1025  int ip_class;
1026 {
1027  bool result = FALSE;
1028 
1029  if (rcpt == NULL || strlen(rcpt) == 0)
1030  return FALSE;
1031 
1032  ZE_MessageInfo(12, "%s : Checking spamtrap from %s %s %s : %s",
1033  STRNULL(id, "00000000.000"),
1034  STRNULL(ip, "IP"),
1035  STRNULL(from, "FROM"),
1036  STRNULL(rcpt, "TO"), STRBOOL(result, "YES", "NO"));
1037 
1038  if (IS_UNKNOWN(ip_class)) {
1039  char buf[256];
1040 
1041  if (check_policy("SpamTrap", rcpt, buf, sizeof (buf), FALSE)) {
1042  result = (strcasecmp(buf, "NO") != 0);
1043  ZE_MessageInfo(10, "SPAMTRAP - %s found at policy database", rcpt);
1044  }
1045  }
1046 
1047  if (result) {
1048  (void) livehistory_add_entry(ip, time(NULL), 1, LH_SPAMTRAP);
1049  result = TRUE;
1050  }
1051 
1052  if (result || (ze_logLevel > 12)) {
1053  ZE_MessageInfo(11, "%s : Checked spamtrap from %s %s %s : %s",
1054  STRNULL(id, "00000000.000"),
1055  STRNULL(ip, "IP"),
1056  STRNULL(from, "FROM"),
1057  STRNULL(rcpt, "TO"), STRBOOL(result, "YES", "NO"));
1058  }
1059 
1060  return result;
1061 }
1062 
1063 /* ****************************************************************************
1064  * *
1065  * *
1066  ******************************************************************************/
1067 #define EHLO_OK 0x0000
1068 #define EHLO_NONE 0x0000
1069 #define EHLO_INVALID_CHAR 0x0001
1070 #define EHLO_FORGED_IP 0x0002
1071 #define EHLO_IP_NO_BRACKET 0x0004
1072 #define EHLO_NOT_FQDN 0x0008
1073 #define EHLO_IDENTITY_THEFT 0x0010
1074 #define EHLO_FAKE_LOCALHOST 0x0020
1075 #define EHLO_REGEX 0x0040
1076 #define EHLO_ALL 0x0FFF
1077 
1078 static name2id_T ehlo_checks[] = {
1079  {"ALL", EHLO_ALL},
1080  {"NONE", EHLO_NONE},
1081  {"InvalidChar", EHLO_INVALID_CHAR},
1082  {"ForgedIP", EHLO_FORGED_IP},
1083  {"NotBracketedIP", EHLO_IP_NO_BRACKET},
1084  {"NotFQDN", EHLO_NOT_FQDN},
1085  {"IdentityTheft", EHLO_IDENTITY_THEFT},
1086  {"FakeLocalhost", EHLO_FAKE_LOCALHOST},
1087  {"Regex", EHLO_REGEX},
1088  {NULL, -1}
1089 };
1090 
1091 /* ****************************************************************************
1092  * *
1093  * *
1094  ******************************************************************************/
1095 uint32_t
1097  SMFICTX *ctx;
1098 {
1099  CTXPRIV_T *priv = MLFIPRIV(ctx);
1100  int ip_class = (priv != NULL ? priv->netclass.class : 0);
1101  uint32_t ehlo_flags = 0, ehlo_res = 0;
1102  char *helohost = NULL;
1103 
1104  bool is_bracketed = FALSE;
1105  bool is_ipv4 = FALSE;
1106  bool is_ipv6 = FALSE;
1107 
1108  static time_t last_update = (time_t) 0;
1109  static uint32_t ehlo_check_rules = EHLO_ALL;
1110 
1111  if (IS_KNOWN(ip_class))
1112  return ehlo_flags;
1113 
1114  if (last_update < last_reconf_date) {
1115  char *checks = NULL;
1116  int nok = 0;
1117 
1118  checks = cf_get_str(CF_BADEHLO_CHECKS);
1119  if (checks != NULL && strlen(checks) > 0) {
1120  char *argv[32];
1121  int argc = 0, i;
1122  int id;
1123 
1124  ehlo_check_rules = EHLO_NONE;
1125  memset(argv, 0, sizeof (argv));
1126  argc = zeStr2Tokens(checks, 32, argv, " ,");
1127 
1128  for (i = 0; i < argc; i++) {
1129  id = get_id_by_name(ehlo_checks, argv[i]);
1130  switch (id) {
1131  case EHLO_INVALID_CHAR:
1132  case EHLO_FORGED_IP:
1133  case EHLO_IP_NO_BRACKET:
1134  case EHLO_NOT_FQDN:
1135  case EHLO_IDENTITY_THEFT:
1136  case EHLO_REGEX:
1137  case EHLO_FAKE_LOCALHOST:
1138  ehlo_check_rules |= (uint32_t) id;
1139  nok++;
1140  break;
1141  case EHLO_NONE:
1142  case EHLO_ALL:
1143  ehlo_check_rules = (uint32_t) id;
1144  nok++;
1145  break;
1146  }
1147  }
1148  }
1149 
1150  if (nok == 0)
1151  ehlo_check_rules = EHLO_ALL;
1152 
1153  last_update = time(NULL);
1154  }
1155 
1156  ehlo_flags = ehlo_res = 0;
1157 
1158  if (ISSTREMPTY(priv->helohost))
1159  return 0;
1160 
1161  if ((helohost = strdup(priv->helohost)) == NULL) {
1162  ZE_LogSysError("helohost : strdup(%s)", priv->helohost);
1163  goto fin;
1164  }
1165 
1166  /*
1167  ** remove brackets if there are at beginning and end
1168  */
1169  {
1170  int len;
1171 
1172  len = strlen(helohost);
1173  if (helohost[0] == '[' && helohost[len - 1] == ']') {
1174  int i;
1175 
1176  for (i = 0; i < len - 2; i++)
1177  helohost[i] = helohost[i + 1];
1178  helohost[len - 2] = '\0';
1179  is_bracketed = TRUE;
1180  }
1181  }
1182 
1183  if (zeStrRegex(helohost, IPV4_ADDR_REGEX, NULL, NULL, TRUE))
1184  is_ipv4 = TRUE;
1185 
1186  /*
1187  ** Invalid characters
1188  */
1189  if (zeStrRegex(helohost, "[^a-z0-9:.-]+", NULL, NULL, TRUE)) {
1190  ehlo_flags |= EHLO_INVALID_CHAR;
1191  SET_BIT(ehlo_res, SPAM_CONN_BAD_EHLO);
1192  ZE_MessageInfo(10, "%s SPAM CHECK - C%02d EHLO : Invalid character %s",
1193  CONNID_STR(priv->id), SPAM_CONN_BAD_EHLO, helohost);
1194  }
1195 
1196  /*
1197  **
1198  */
1199  if (is_ipv4 && !STREQUAL(helohost, priv->peer_addr)) {
1200  ehlo_flags |= EHLO_FORGED_IP;
1201  SET_BIT(ehlo_res, SPAM_CONN_FORGED_EHLO);
1202  ZE_MessageInfo(10,
1203  "%s SPAM CHECK - C%02d EHLO : doesn't match peer addr %s/%s",
1204  CONNID_STR(priv->id), SPAM_CONN_FORGED_EHLO, helohost,
1205  priv->peer_addr);
1206  }
1207 
1208  if ((is_ipv4 || is_ipv6) && !is_bracketed) {
1209  ehlo_flags |= EHLO_IP_NO_BRACKET;
1210  SET_BIT(ehlo_res, SPAM_CONN_BAD_EHLO);
1211  ZE_MessageInfo(10, "%s SPAM CHECK - C%02d EHLO : IP without brackets %s",
1212  CONNID_STR(priv->id), SPAM_CONN_BAD_EHLO, helohost);
1213  }
1214 
1215  if (!is_ipv4 && !is_ipv6 && strchr(helohost, '.') == NULL) {
1216  /*
1217  * Non FQDN
1218  */
1219  ehlo_flags |= EHLO_NOT_FQDN;
1220  SET_BIT(ehlo_res, SPAM_CONN_BAD_EHLO);
1221  ZE_MessageInfo(10, "%s SPAM CHECK - C%02d EHLO : non FQDN parameter %s",
1222  CONNID_STR(priv->id), SPAM_CONN_BAD_EHLO, helohost);
1223  }
1224 
1225  /*
1226  * Check against localhost
1227  */
1228  if (is_ipv6 && zeStrRegex(helohost, "(::1)", NULL, NULL, TRUE)) {
1229  ehlo_flags |= EHLO_FAKE_LOCALHOST;
1230  SET_BIT(ehlo_res, SPAM_CONN_FORGED_EHLO);
1231  ZE_MessageInfo(10,
1232  "%s SPAM CHECK - C%02d EHLO : presents as being localhost %s/%s",
1234  priv->peer_addr, helohost);
1235  }
1236 
1237  if (is_ipv4 && STRNCASEEQUAL(helohost, "127.", strlen("127."))) {
1238  ehlo_flags |= EHLO_FAKE_LOCALHOST;
1239  SET_BIT(ehlo_res, SPAM_CONN_FORGED_EHLO);
1240  ZE_MessageInfo(10,
1241  "%s SPAM CHECK - C%02d EHLO : presents as being localhost %s/%s",
1243  priv->peer_addr, helohost);
1244  }
1245 
1246  if (!is_ipv4 && !is_ipv6
1247  && zeStrRegex(helohost, "^localhost", NULL, NULL, TRUE)) {
1248  ehlo_flags |= EHLO_FAKE_LOCALHOST;
1249  SET_BIT(ehlo_res, SPAM_CONN_FORGED_EHLO);
1250  ZE_MessageInfo(10,
1251  "%s SPAM CHECK - C%02d EHLO : presents as being localhost %s/%s",
1253  priv->peer_addr, helohost);
1254  }
1255 
1256  /*
1257  * Check against myself
1258  */
1259  {
1260  char *myself = NULL;
1261  char tme[2048];
1262 
1263  int argc;
1264  char *argv[64];
1265  int i;
1266 
1267  myself = cf_get_str(CF_MYSELF);
1268  myself = STRNULL(myself, "");
1269  strlcpy(tme, myself, sizeof (tme));
1270 
1271  argc = zeStr2Tokens(tme, 64, argv, ", ");
1272  for (i = 0; i < argc; i++) {
1273  char *expr = argv[i];
1274 
1275  if (STRCASEEQUAL(expr, "HOSTNAME") && (strlen(my_hostname) > 0)) {
1276  if (!STRCASEEQUAL(my_hostname, "localhost")
1277  && strchr(my_hostname, '.') == NULL)
1278  continue;
1279  expr = my_hostname;
1280  }
1281 
1282  ZE_MessageInfo(19, "Checking helo %s against %s", helohost, expr);
1283 
1284  if (zeStrRegex(helohost, expr, NULL, NULL, TRUE)
1285  /*
1286  * && (strlen(helohost) - strlen(expr) <= 2)
1287  */
1288  ) {
1289  ehlo_flags |= EHLO_IDENTITY_THEFT;
1290  SET_BIT(ehlo_res, SPAM_CONN_FORGED_EHLO);
1291  ZE_MessageInfo(10,
1292  "%s SPAM CHECK - C%02d EHLO : presents as being myself %s/%s",
1294  priv->peer_addr, helohost);
1295  break;
1296  }
1297  }
1298  }
1299 
1300  /*
1301  * Check against regular expression
1302  */
1303  if ((ehlo_check_rules & EHLO_REGEX) != 0) {
1304  int score;
1305 
1306  score =
1307  check_regex(CONNID_STR(priv->id), priv->peer_addr, helohost, MAIL_HELO);
1308 
1309  if (score > 1) {
1310  ehlo_flags |= EHLO_REGEX;
1311  SET_BIT(ehlo_res, SPAM_CONN_BAD_EHLO);
1312  ZE_MessageInfo(10,
1313  "%s SPAM CHECK - C%02d EHLO (%s) matches regular expression",
1314  CONNID_STR(priv->id), SPAM_CONN_BAD_EHLO, helohost);
1315  }
1316  }
1317 
1318  if (ehlo_res != 0)
1319  ZE_MessageInfo(9, "%s EHLO CHECK - Bad value ip/value = %s/%s (%08X)",
1320  CONNID_STR(priv->id), priv->peer_addr, helohost, ehlo_flags);
1321 
1322 fin:
1323  FREE(helohost);
1324 
1325  priv->spamchk.flags.conn |= ehlo_res;
1326  priv->spamchk.flags.ehlo |= ehlo_res;
1327 
1328  ehlo_flags &= ehlo_check_rules;
1329  priv->ehlo_flags = ehlo_flags;
1330 
1331  return ehlo_flags;
1332 }
1333 
1334 /* ****************************************************************************
1335  * *
1336  * *
1337  ******************************************************************************/
1338 
1339 /*
1340 ** Domain Key definitions
1341 */
1342 #define DKF_STATUS_GOOD 0
1343 #define DKF_STATUS_BAD 1
1344 #define DKF_STATUS_NOKEY 2
1345 #define DKF_STATUS_REVOKED 3
1346 #define DKF_STATUS_NOSIGNATURE 4
1347 #define DKF_STATUS_BADFORMAT 6
1348 #define DKF_STATUS_NONPART 7
1349 #define DKF_STATUS_UNKNOWN 8
1350 
1351 struct lookup {
1352  char *str;
1353  int code;
1354 };
1355 
1356 struct lookup dkf_status[] = {
1357  {"unknown", DKF_STATUS_UNKNOWN},
1358  {"good", DKF_STATUS_GOOD},
1359  {"bad", DKF_STATUS_BAD},
1360  {"no key", DKF_STATUS_NOKEY},
1361  {"revoked", DKF_STATUS_REVOKED},
1362  {"no signature", DKF_STATUS_NOSIGNATURE},
1363  {"bad format", DKF_STATUS_BADFORMAT},
1364  {"non-participant", DKF_STATUS_NONPART},
1365  {NULL, -1},
1366 };
1367 
1368 
1369 int
1371  char *s;
1372 {
1373  struct lookup *p = dkf_status;
1374 
1375  if (s == NULL)
1376  return DKF_STATUS_UNKNOWN;
1377 
1378  for (p = dkf_status; p->str != NULL; p++)
1379  if (strcasecmp(p->str, s) == 0)
1380  return p->code;
1381 
1382  return DKF_STATUS_UNKNOWN;
1383 }
1384 
1385 int
1387  SMFICTX *ctx;
1388 {
1389  CTXPRIV_T *priv = MLFIPRIV(ctx);
1390 
1391  int dkresult = DKF_STATUS_UNKNOWN;
1392 
1393  /*
1394  * DomainKeys check
1395  */
1396  {
1397  header_T *h;
1398 
1399  if ((h = get_msgheader(priv->headers, "DomainKey-Status")) != NULL) {
1400  int iStatus, iSignature;
1401 
1402  dkresult = decode_dk_result(h->value);
1403 
1404  iStatus = get_msgheader_index(priv->headers, "DomainKey-Status");
1405  iSignature = get_msgheader_index(priv->headers, "DomainKey-Signature");
1406 
1407  if (iStatus >= 0 && iSignature < 0) {
1408  ZE_MessageNotice(9, "DK Status without DK Signature");
1409  }
1410 
1411  if ((iStatus >= 0) && (iSignature >= 0)) {
1412  if (iStatus > iSignature) {
1413  ZE_MessageNotice(9, "DK Status inserted after DK Signature");
1414  }
1415  }
1416  }
1417  }
1418 
1419  return dkresult;
1420 }
1421 
1422 /* ****************************************************************************
1423  * *
1424  * *
1425  ******************************************************************************/
1426 
1427 /*
1428 ** Shall check
1429 ** user
1430 ** user@domain.com
1431 ** @domain.com
1432 **
1433 ** rcpt_host : paris.ensmp.fr.
1434 ** rcpt_addr : martins@paris.ensmp.fr
1435 ** rcpt_to : <martins@paris.ensmp.fr>
1436 **
1437 */
1438 bool
1439 shall_notify_user(user_addr, to)
1440  char *user_addr;
1441  bool to;
1442 {
1443  bool result = FALSE;
1444 
1445  char buf[256];
1446 
1447  memset(buf, 0, sizeof (buf));
1448  if (check_policy("NotifyUser", user_addr, buf, sizeof (buf), FALSE)) {
1449  if (strcasecmp(buf, "NO") == 0)
1450  return FALSE;
1451  if (strcasecmp(buf, "YES") == 0)
1452  return TRUE;
1453  if (strcasecmp(buf, "RECIPIENT") == 0)
1454  return to;
1455  if (strcasecmp(buf, "SENDER") == 0)
1456  return !to;
1457  if (strcasecmp(buf, "DAILY") == 0)
1458  return FALSE;
1459  }
1460 
1461  return result;
1462 }
int check_regex(char *, char *, char *, int)
Definition: ze-mailregex.c:295
int smtprate_add_entry(int, char *, char *, int, time_t)
Definition: ze-smtprate.c:363
#define OPT_DEFAULT
Definition: ze-cf.h:79
double combined
Definition: ze-msg-score.h:73
rcpt_addr_T * env_rcpt
#define EHLO_FAKE_LOCALHOST
char * ip
Definition: ze-chkcontent.h:57
#define BCONDSZ
#define STRBOOL(x, t, f)
Definition: macros.h:87
msg_scores_T rawScores
bool check_helo_myself(char *ip, char *hostname, char *helo)
bool check_policy_all_rcpts(char *prefix, char *ip, char *name, char *netclass, char *from, rcpt_addr_T *rcpt, bool result, int conflict)
Definition: ze-policy.c:470
char * fname
#define CF_XSTATUS_HEADER_UNSURE_CONDITION
Definition: cfh-defs.h:134
#define OPT_ONE_WIN
Definition: ze-cf.h:80
void stats_inc(int, long)
Definition: ze-stats.c:401
bool check_policy(char *prefix, char *key, char *buf, size_t size, bool cdef)
Definition: ze-policy.c:119
#define STAT_BAYES_SPAM
Definition: ze-stats.h:64
uint32_t ehlo
Definition: ze-chkcontent.h:37
#define DKF_STATUS_UNKNOWN
int decode_dk_result(char *s)
#define ASSERT(a)
Definition: macros.h:27
#define CF_XSTATUS_HEADER_LO_CONDITION
Definition: cfh-defs.h:133
#define NULLSENDER
Definition: macros.h:229
time_t last_reconf_date
Definition: ze-cf.c:53
#define ISSTREMPTY(x)
Definition: macros.h:85
int jsmfi_setreply(SMFICTX *, char *, char *, char *)
Definition: ze-libmilter.c:99
#define DKF_STATUS_NOSIGNATURE
header_T * get_msgheader(header_T *, char *)
Definition: ze-headers.c:144
#define FREE(x)
Definition: macros.h:37
#define SPAM_CONN_RESOLVE_FAIL
bool add_tag2subject(SMFICTX *, char *)
#define EHLO_ALL
#define SPAM_CONN_FALSE_LOCALHOST
#define SPAM_MSG_HAS_SPAMTRAP
char * peer_addr
int ze_logLevel
Definition: zeSyslog.c:34
#define STRNULL(x, r)
Definition: macros.h:81
int check_domainkeys(SMFICTX *ctx)
#define WHY_SPAM
Definition: ze-spool.h:31
#define STRNCASEEQUAL(a, b, n)
Definition: macros.h:75
#define DKF_STATUS_BAD
bool ok
Definition: ze-connopen.c:59
uint32_t conn
Definition: ze-chkcontent.h:36
#define CF_XFILES
Definition: cfh-defs.h:92
#define STAT_URLBL
Definition: ze-stats.h:56
#define CF_SPAM_ORACLE
Definition: cfh-defs.h:123
int dbrcpt_bad_network
#define FALSE
Definition: macros.h:160
#define SMFIS_CONTINUE
#define SMFIS_REJECT
#define strlcpy
Definition: zeString.h:32
#define CF_MYSELF
Definition: cfh-defs.h:30
#define SPAM_MSG_TOO_SHORT
bool check_spamtrap_rcpt(char *id, char *ip, char *from, char *rcpt, int ip_class)
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
#define STREQUAL(a, b)
Definition: macros.h:78
#define LH_SPAMTRAP
#define RESOLVE_TEMPFAIL
Definition: ze-filter.h:174
#define OPT_YES
Definition: ze-cf.h:45
#define RESOLVE_FORGED
Definition: ze-filter.h:173
#define SPAM_MSG_HAS_BADRCPT
bool compatible_domains(char *da, char *db)
#define CF_LOG_LEVEL_ORACLE
Definition: cfh-defs.h:126
int zeStrlEqual(char *, char *)
Definition: zeStrings.c:81
#define CF_XSTATUS_HEADER
Definition: cfh-defs.h:131
#define POSTMASTER_OK
Definition: macros.h:231
double odds
Definition: ze-dns-iprbwl.h:46
#define EHLO_IDENTITY_THEFT
int cf_get_int(int id)
Definition: ze-cf.c:803
#define MLFIPRIV(ctx)
#define SET_BIT(p, i)
Definition: macros.h:166
int zeStr2Tokens(char *, int, char **, char *)
Definition: zeStrings.c:610
#define CF_BAYESIAN_FILTER
Definition: cfh-defs.h:105
#define STAT_PATTERN_MATCHING
Definition: ze-stats.h:50
#define DO_QUARANTINE_MESSAGE(priv, why, suffix)
#define DKF_STATUS_NOKEY
#define STAT_ORACLE
Definition: ze-stats.h:55
#define strchr
Definition: ze-sys.h:218
char my_hostname[]
Definition: ze-filter.c:89
#define CF_SCORE_ON_SUBJECT_TAG
Definition: cfh-defs.h:130
#define OPT_OK
Definition: ze-cf.h:47
#define CF_SCANNER_ACTION
Definition: cfh-defs.h:97
CONNID_T id
#define RATE_HAM
Definition: ze-smtprate.h:55
unsigned long msg_size
bool fill_msg_scale(scores_scale_T *scale)
Definition: ze-msg-score.c:810
scores_scale_T scale
Definition: ze-msg-score.h:93
#define CF_XSTATUS_HEADER_HI_CONDITION
Definition: cfh-defs.h:132
sfsistat check_msg_contents(SMFICTX *ctx)
#define BSCORE_LO
Definition: ze-msg-score.h:33
#define IS_KNOWN(class)
Definition: ze-netclass.h:50
#define ZE_MessageNotice(level,...)
Definition: zeSyslog.h:91
bool create_msg_score_header(char *buf, size_t size, char *id, char *hostname, msg_scores_T *scores)
Definition: ze-msg-score.c:737
#define SPAM_CONN_RESOLVE_TEMPFAIL
msg_flags_T flags
Definition: ze-chkcontent.h:68
iprbwl_T rbwl
uint32_t check_ehlo_value(SMFICTX *ctx)
char * value
Definition: ze-headers.h:36
#define EHLO_NONE
#define EHLO_REGEX
#define IS_UNKNOWN(class)
Definition: ze-netclass.h:51
#define CF_SCORE_ON_SUBJECT
Definition: cfh-defs.h:129
#define EHLO_FORGED_IP
void msg_score_stats_update(msg_scores_T *scores)
Definition: ze-stats.c:52
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define OPT_NO
Definition: ze-cf.h:44
#define SPAM_MSG_BAD_NULL_SENDER
int dbrcpt_conn_spamtrap
#define RATE_SPAM
Definition: ze-smtprate.h:56
#define SMFIS_DISCARD
#define TRUE
Definition: macros.h:157
#define SPAM_CONN_BL_SPAMTRAP
#define SPAM_CONN_FORGED_EHLO
int dbrcpt_msg_unknown
#define SPAM_CONN_BAD_EHLO
void oracle_stats_update(int)
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
#define MSG_BODY_CONTENTS
Definition: ze-reply.h:161
char * cf_get_str(int id)
Definition: ze-cf.c:854
#define SPAM_MSG_FORGED_POSTMASTER
#define STAT_BAYES_HAM
Definition: ze-stats.h:65
header_T * hdrs
header_T * headers
double bayes
Definition: ze-msg-score.h:88
#define STREMPTY(x, r)
Definition: macros.h:82
char * peer_name
#define CTX_NETCLASS_LABEL(priv)
uint32_t msg
Definition: ze-chkcontent.h:41
#define SPAM_CONN_RESOLVE_FORGED
char * env_from
#define RATE_SCORE
Definition: ze-smtprate.h:57
bool do_module_callback(SMFICTX *ctx, int step, int *result)
Definition: ze-mod-tools.c:84
#define EHLO_IP_NO_BRACKET
#define SPAM_CONN_RBL
bool passport_ok(char *to, char *key)
char * helohost
char * score_str
bool shall_check_virus(SMFICTX *ctx)
#define DKF_STATUS_REVOKED
uint32_t ehlo_flags
sm_mac_T * sm
#define STAT_BAYES_DUB
Definition: ze-stats.h:66
#define CF_BADEHLO_CHECKS
Definition: cfh-defs.h:172
#define BSCORE_HI
Definition: ze-msg-score.h:35
#define MAIL_HELO
Definition: ze-mailregex.h:40
char * status_str
#define CONNID_STR(connid)
Definition: ze-filter.h:113
sfsistat evaluate_message_score(SMFICTX *ctx, bool *do_log)
int get_msgheader_index(header_T *, char *)
Definition: ze-headers.c:191
int update_nb_badrcpts(SMFICTX *ctx)
#define CF_XSTATUS_REJECT_CONDITION
Definition: cfh-defs.h:136
#define DKF_STATUS_BADFORMAT
#define STRCASEEQUAL(a, b)
Definition: macros.h:72
struct lookup dkf_status[]
int get_id_by_name(name2id_T *, char *)
Definition: ze-name2id.c:35
bool shall_check_content(SMFICTX *ctx)
CONNID_T id
Definition: ze-chkcontent.h:58
#define CF_SPAM_REGEX
Definition: cfh-defs.h:116
char * hdr_from
bool shall_check_xfiles(SMFICTX *ctx)
netclass_T netclass
int livehistory_check_host(char *, time_t, int)
int livehistory_add_entry(char *, time_t, int, int)
#define EHLO_NOT_FQDN
msg_scores_T scores
Definition: ze-chkcontent.h:72
#define DKF_STATUS_GOOD
#define EHLO_INVALID_CHAR
int nb_badrcpt
Definition: ze-chkcontent.h:75
bool enveloppe_postmaster(char *from)
#define DKF_STATUS_NONPART
double compute_msg_score(msg_scores_T *scores)
Definition: ze-msg-score.c:634
char * sm_macro_get_str(sm_mac_T *, char *)
Definition: ze-smmacros.c:191
void log_msg_context(SMFICTX *ctx, char *why)
#define IPV4_ADDR_REGEX
Definition: macros.h:218
#define CF_XSTATUS_HEADER_HAM_CONDITION
Definition: cfh-defs.h:135
bool shall_notify_user(char *user_addr, bool to)
#define POSTMASTER_FORGED
Definition: macros.h:232
#define CF_SPAM_REGEX_MAX_MSG_SIZE
Definition: cfh-defs.h:119
#define CF_XSTATUS_QUARANTINE_CONDITION
Definition: cfh-defs.h:138
long uint32_t
Definition: ze-sys.h:489
int check_valid_postmaster(char *env_from, char *from, int nbrcpt)
bool shall_designated_quarantine(SMFICTX *ctx, char *rcpt)
int scan_body_contents(char *, char *, char *, size_t, spamchk_T *, msg_flags_T *, msg_scores_T *)
#define CF_SPAM_URLBL
Definition: cfh-defs.h:113
spamchk_T spamchk
#define NOT_POSTMASTER
Definition: macros.h:233
#define RESOLVE_FAIL
Definition: ze-filter.h:172