ze-filter  (ze-filter-0.8.0-develop-180218)
ze-check-connection.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 : Tue Jan 2 22:39:53 CET 2007
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 
26 #include <ze-sys.h>
27 #include <libze.h>
28 
29 #include <ze-filter.h>
30 #include <ze-filter-data.h>
31 #include <ze-check-connection.h>
32 
33 #define RATE_LOG_LEVEL 12
34 
35 /* ****************************************************************************
36  * *
37  * *
38  ******************************************************************************/
39 #define GET_RESOLVE_COEF(resolve, coef) \
40  do { \
41  /* Let's setup Throttle coefficient */ \
42  switch (resolve) \
43  { \
44  case RESOLVE_NULL: \
45  coef = 1; \
46  break; \
47  case RESOLVE_OK: \
48  coef = 1; \
49  break; \
50  case RESOLVE_FAIL: \
51  coef = 2; \
52  break; \
53  case RESOLVE_FORGED: \
54  coef = 2; \
55  break; \
56  case RESOLVE_TEMPFAIL: \
57  coef = 2; \
58  break; \
59  default: \
60  coef = 1; \
61  } \
62  } while (0)
63 
64 /* ****************************************************************************
65  * *
66  * *
67  ******************************************************************************/
68 sfsistat
70  SMFICTX *ctx;
71 {
72  CTXPRIV_T *priv = MLFIPRIV(ctx);
73  int result = SMFIS_CONTINUE;
74 
75  ASSERT(priv != NULL);
76 
77  if (IS_KNOWN(priv->netclass.class))
78  return result;
79 
80  if ((priv->resolve_res == RESOLVE_NULL) || (priv->resolve_res == RESOLVE_OK))
81  return result;
82 
83  {
84  int nb;
85  time_t now;
86  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
87  char s[256];
88 
89  char *reply = NULL, *why = NULL;
90  int which = -1;
91 
92  switch (priv->resolve_res) {
93  /*
94  * DNS lookup FAIL
95  */
96  case RESOLVE_FAIL:
98  return result;
99  reply = MSG_RESOLVE_FAIL;
101  which = STAT_RESOLVE_FAIL;
102  break;
103 
104  /*
105  * forged hostname
106  */
107  case RESOLVE_FORGED:
109  return result;
110  reply = MSG_RESOLVE_FORGED;
112  which = STAT_RESOLVE_FORGED;
113  break;
114  default:
115  return result;
116  break;
117  }
118 
119  MUTEX_LOCK(&mutex);
120 
122  if (nb < cf_get_int(CF_MAX_BAD_RESOLVE)) {
123  now = time(NULL);
124  (void) livehistory_add_entry(priv->peer_addr, now, 1, LH_BAD_RESOLVE);
125 
126  } else
127  result = SMFIS_TEMPFAIL;
128 
129  MUTEX_UNLOCK(&mutex);
130 
131  if (result == SMFIS_CONTINUE)
132  goto fin;
133 
134  reply = STRNULL(reply, "DNS address resolution error");
135  why = STRNULL(why, "DNS IP address resolution error");
136  (void) jsmfi_setreply(ctx, "451", "4.1.8", reply);
137  snprintf(s, sizeof (s), "%s : %d", why, nb);
138  log_msg_context(ctx, s);
139 
140  if (which > 0)
141  stats_inc(which, 1);
142 
143  goto fin;
144  }
145 
146 
147 fin:
148  if (result != SMFIS_CONTINUE)
149  priv->rej_resolve = TRUE;
150 
151  return result;
152 }
153 
154 /* ****************************************************************************
155  * *
156  * *
157  ******************************************************************************/
158 sfsistat
160  SMFICTX *ctx;
161 {
162  CTXPRIV_T *priv = MLFIPRIV(ctx);
163  int result = SMFIS_CONTINUE;
164 
166 #if 0
167  if (priv->conn_rate <= 1)
168  return result;
169 #endif
170 
172  int ip_class = priv->netclass.class;
173  int n;
174  char s[256];
175 
176  priv->conn_rate =
178  n = priv->conn_rate;
179 
181  "%-12s ConnRate : %-20s %4d ip_class=[%02X - %s]",
182  CONNID_STR(priv->id), priv->peer_addr, n, ip_class,
183  CTX_NETCLASS_LABEL(priv));
184 
185  {
186  char buf[256];
187  bool ok = FALSE;
188  int vmax = 0;
189 
191 
192  if (check_host_policy("ConnRate", priv->peer_addr, priv->peer_name,
193  priv->netclass.label, buf, sizeof (buf), TRUE))
194  vmax = zeStr2long(buf, NULL, 0);
195 
196  if (vmax > 0 && n > vmax)
197  result = SMFIS_TEMPFAIL;
198  }
199 
200  if (result != SMFIS_CONTINUE) {
202  (void) jsmfi_setreply(ctx, "421", "4.5.1", MSG_CONN_RATE);
203  snprintf(s, sizeof (s), "%s : %d [%02X - %s]",
204  MSG_SHORT_CONN_RATE, n, ip_class, CTX_NETCLASS_LABEL(priv));
205 
206  log_msg_context(ctx, s);
207 
208  priv->result = result;
209  priv->rej_conn_rate = TRUE;
210  }
211  }
212 
213  return result;
214 }
215 
216 /* ****************************************************************************
217  * *
218  * *
219  ******************************************************************************/
220 sfsistat
222  SMFICTX *ctx;
223 {
224  CTXPRIV_T *priv = MLFIPRIV(ctx);
225  int result = SMFIS_CONTINUE;
226 
228 #if 0
229  if (priv->msg_rate <= 1)
230  return result;
231 #endif
232 
234  int ip_class = priv->netclass.class;
235  int n;
236  char s[256];
237 
239  n = priv->msg_rate;
240 
242  "%-12s MsgsRate : %-20s %4d ip_class=[%02X - %s]",
243  CONNID_STR(priv->id), priv->peer_addr, n, ip_class,
244  CTX_NETCLASS_LABEL(priv));
245 
246  {
247  char buf[256];
248  bool ok = FALSE;
249  int vmax = 0;
250 
251  vmax = cf_get_int(CF_MAX_MSG_RATE);
252 
253  if (check_host_policy("MsgRate", priv->peer_addr, priv->peer_name,
254  priv->netclass.label, buf, sizeof (buf), TRUE))
255  vmax = zeStr2long(buf, NULL, 0);
256 
257  if (vmax > 0 && n > vmax)
258  result = SMFIS_TEMPFAIL;
259 
260  if (result != SMFIS_CONTINUE) {
262  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_MSG_RATE);
263  snprintf(s, sizeof (s), "%s : %d [%02X - %s]",
264  MSG_SHORT_MSG_RATE, n, ip_class, CTX_NETCLASS_LABEL(priv));
265 
266  log_msg_context(ctx, s);
267 
268  priv->result = result;
269  priv->rej_msg_rate = TRUE;
270  }
271  }
272 
273  {
274  int fromRate;
275 
276  bool addrPlusEmail = FALSE;
277  char *sEnv = NULL;
278 
279  if ((sEnv = getenv("FROMRATEFULL")) != NULL) {
280  if (zeStrRegex(sEnv, "yes|oui|true", NULL, NULL, TRUE))
281  addrPlusEmail = TRUE;
282  }
283 
284  if (addrPlusEmail) {
285  char cbuf[256];
286 
287  snprintf(cbuf, sizeof (cbuf), "%s-%s", priv->peer_addr, priv->env_from);
288  fromRate =
290  } else {
291  fromRate =
293  }
294 
296  "%-12s MsgsRateFrom : %-20s %4d %s ip_class=[%02X - %s]",
297  CONNID_STR(priv->id), priv->peer_addr, fromRate,
298  priv->env_from, ip_class, CTX_NETCLASS_LABEL(priv));
299  {
300  char buf[256];
301  bool ok = FALSE;
302  int vmax = 0;
303  char fBuf[256];
304 
305  memset(fBuf, 0, sizeof (fBuf));
306  extract_email_address(fBuf, priv->env_from, sizeof (fBuf));
307  if (strlen(fBuf) == 0)
308  strlcpy(fBuf, "nullsender", sizeof (fBuf));
309 
311  if (PolicyLookupEmailAddr("MsgRateFrom", fBuf, buf, sizeof (buf)))
312  vmax = zeStr2long(buf, NULL, 0);
313 
314  if (vmax > 0 && fromRate > vmax)
315  result = SMFIS_TEMPFAIL;
316 
317  if (result != SMFIS_CONTINUE) {
319  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_MSG_RATE);
320  snprintf(s, sizeof (s), "%s : %d [%02X - %s]",
321  MSG_SHORT_MSG_RATE, n, ip_class, CTX_NETCLASS_LABEL(priv));
322 
323  log_msg_context(ctx, s);
324 
325  priv->result = result;
326  priv->rej_msg_rate = TRUE;
327  }
328  }
329  }
330 
331  {
332  int authRate;
333 
335 
337  "%-12s MsgsRateAuth : %-20s %4d %s ip_class=[%02X - %s]",
338  CONNID_STR(priv->id), priv->peer_addr, authRate,
339  priv->env_from, ip_class, CTX_NETCLASS_LABEL(priv));
340  {
341  char buf[256];
342  bool ok = FALSE;
343  int vmax = 0;
344  char fBuf[256];
345 
346  memset(fBuf, 0, sizeof (fBuf));
347  extract_email_address(fBuf, priv->env_from, sizeof (fBuf));
348  if (strlen(fBuf) == 0)
349  strlcpy(fBuf, "nullsender", sizeof (fBuf));
350 
352  if (PolicyLookupEmailAddr("MsgRateAuth", fBuf, buf, sizeof (buf)))
353  vmax = zeStr2long(buf, NULL, 0);
354 
355  if (vmax > 0 && authRate > vmax)
356  result = SMFIS_TEMPFAIL;
357 
358  if (result != SMFIS_CONTINUE) {
360  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_MSG_RATE);
361  snprintf(s, sizeof (s), "%s : %d [%02X - %s]",
362  MSG_SHORT_MSG_RATE, n, ip_class, CTX_NETCLASS_LABEL(priv));
363 
364  log_msg_context(ctx, s);
365 
366  priv->result = result;
367  priv->rej_msg_rate = TRUE;
368  }
369  }
370  }
371 
372  }
373 
374  return result;
375 }
376 
377 /* ****************************************************************************
378  * *
379  * *
380  ******************************************************************************/
381 sfsistat
383  SMFICTX *ctx;
384 {
385  CTXPRIV_T *priv = MLFIPRIV(ctx);
386  int result = SMFIS_CONTINUE;
387  int nb_from = 0;
388 
390  int ip_class = priv->netclass.class;
391  char s[256];
392 
393  nb_from = priv->nb_from;
394 
396  "%-12s MsgCount : %-20s %4d ip_class=[%02X - %s]",
397  CONNID_STR(priv->id), priv->peer_addr, nb_from, ip_class,
398  CTX_NETCLASS_LABEL(priv));
399 
400  {
401  char buf[256];
402  bool ok = FALSE;
403  int vmax = 0;
404 
405  vmax = cf_get_int(CF_MAX_MSGS);
406 
407  if (check_host_policy("MaxMsgs", priv->peer_addr, priv->peer_name,
408  priv->netclass.label, buf, sizeof (buf), TRUE))
409  vmax = zeStr2long(buf, NULL, 0);
410 
411  if (vmax > 0 && nb_from > vmax)
412  result = SMFIS_TEMPFAIL;
413  }
414 
415  if (result != SMFIS_CONTINUE) {
417  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_TOO_MUCH_MSGS);
418  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
419  MSG_TOO_MUCH_MSGS, priv->peer_addr, nb_from, ip_class,
420  CTX_NETCLASS_LABEL(priv));
421 
422  log_msg_context(ctx, s);
423 
424  priv->rej_msgs++;
425  priv->result = result;
426  }
427 
428  }
429 
430  return result;
431 }
432 
433 
434 /* ****************************************************************************
435  * *
436  * *
437  ******************************************************************************/
438 sfsistat
440  SMFICTX *ctx;
441 {
442  CTXPRIV_T *priv = MLFIPRIV(ctx);
443  int result = SMFIS_CONTINUE;
444  int rate = 0;
445 
447 #if 0
448  if (rate <= 1)
449  return result;
450 #endif
451 
453  goto fin;
454 
455  {
456  int ip_class = priv->netclass.class;
457  char s[256];
458 
460  /*
461  * XXX\A0shall n be saved on some priv member ???
462  */
463 
465  "%-12s RcptRate : %-20s %4d ip_class=[%02X - %s]",
466  CONNID_STR(priv->id), priv->peer_addr, rate, ip_class,
467  CTX_NETCLASS_LABEL(priv));
468 
469  {
470  char buf[256];
471  bool ok = FALSE;
472  int vmax = 0;
473 
475 
476  if (check_host_policy("RcptRate", priv->peer_addr, priv->peer_name,
477  priv->netclass.label, buf, sizeof (buf), TRUE))
478  vmax = zeStr2long(buf, NULL, 0);
479 
480  if (vmax > 0 && rate > vmax)
481  result = SMFIS_TEMPFAIL;
482  }
483 
484  if (result != SMFIS_CONTINUE) {
486  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_RCPT_RATE);
487  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
488  MSG_SHORT_RCPT_RATE, priv->peer_addr, rate, ip_class,
489  CTX_NETCLASS_LABEL(priv));
490 
491  log_msg_context(ctx, s);
492 
493  priv->result = result;
494  priv->rej_conn_rate = TRUE;
495  }
496  }
497 
498  {
499  int ip_class = priv->netclass.class;
500  char s[256];
501  int COEF = 1;
502  char fBuf[256];
503 
504  bool addrPlusEmail = FALSE;
505  char *sEnv = NULL;
506 
507  if ((sEnv = getenv("FROMRATEFULL")) != NULL) {
508  if (zeStrRegex(sEnv, "yes|oui|true", NULL, NULL, TRUE))
509  addrPlusEmail = TRUE;
510  }
511 
512  if (addrPlusEmail) {
513  char cbuf[256];
514 
515  snprintf(cbuf, sizeof (cbuf), "%s-%s", priv->peer_addr, priv->env_from);
517  } else {
519  }
520  /*
521  * XXX\A0shall n be saved on some priv member ???
522  */
523 
525  "%-12s RcptRateFrom : %-20s %4d %s ip_class=[%02X - %s]",
526  CONNID_STR(priv->id), priv->peer_addr, rate, priv->env_from,
527  ip_class, CTX_NETCLASS_LABEL(priv));
528 
529  {
530  char buf[256];
531  bool ok = FALSE;
532  int vmax = 0;
533 
534  memset(fBuf, 0, sizeof (fBuf));
535  extract_email_address(fBuf, priv->env_from, sizeof (fBuf));
536  if (strlen(fBuf) == 0)
537  strlcpy(fBuf, "nullsender", sizeof (fBuf));
538 
540  if (PolicyLookupEmailAddr("RcptRateFrom", fBuf, buf, sizeof (buf)))
541  vmax = zeStr2long(buf, NULL, 0);
542 
543  if (vmax > 0 && rate > vmax)
544  result = SMFIS_TEMPFAIL;
545  }
546 
547  if (result != SMFIS_CONTINUE) {
549  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_RCPT_RATE);
550  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
551  MSG_SHORT_RCPT_RATE, fBuf, rate, ip_class,
552  CTX_NETCLASS_LABEL(priv));
553 
554  log_msg_context(ctx, s);
555 
556  priv->result = result;
557  priv->rej_conn_rate = TRUE;
558  }
559  }
560 
561  {
562  int ip_class = priv->netclass.class;
563  char s[256];
564  int COEF = 1;
565  char fBuf[256];
566 
568  /*
569  * XXX shall n be saved on some priv member ???
570  */
571 
573  "%-12s RcptRateAuth : %-20s %4d %s ip_class=[%02X - %s]",
574  CONNID_STR(priv->id), priv->peer_addr, rate, priv->env_from,
575  ip_class, CTX_NETCLASS_LABEL(priv));
576 
577  {
578  char buf[256];
579  bool ok = FALSE;
580  int vmax = 0;
581 
582  memset(fBuf, 0, sizeof (fBuf));
583  extract_email_address(fBuf, priv->env_from, sizeof (fBuf));
584  if (strlen(fBuf) == 0)
585  strlcpy(fBuf, "nullsender", sizeof (fBuf));
586 
588  if (PolicyLookupEmailAddr("RcptRateAuth", fBuf, buf, sizeof (buf)))
589  vmax = zeStr2long(buf, NULL, 0);
590 
591  if (vmax > 0 && rate > vmax)
592  result = SMFIS_TEMPFAIL;
593  }
594 
595  if (result != SMFIS_CONTINUE) {
597  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_RCPT_RATE);
598  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
599  MSG_SHORT_RCPT_RATE, fBuf, rate, ip_class,
600  CTX_NETCLASS_LABEL(priv));
601 
602  log_msg_context(ctx, s);
603 
604  priv->result = result;
605  priv->rej_conn_rate = TRUE;
606  }
607  }
608 
609 fin:
610  return result;
611 }
612 
613 /* ****************************************************************************
614  * *
615  * *
616  ******************************************************************************/
617 sfsistat
619  SMFICTX *ctx;
620 {
621  CTXPRIV_T *priv = MLFIPRIV(ctx);
622  int result = SMFIS_CONTINUE;
623  int nb_rcpt = 0;
624 
626  int ip_class = priv->netclass.class;
627  char s[256];
628  int COEF = 1;
629 
630  GET_RESOLVE_COEF(priv->resolve_res, COEF);
631 
632  if ((COEF == 1) && (priv->ehlo_flags != 0))
633  COEF = 2;
634 
635  nb_rcpt = priv->env_nb_rcpt;
636 
638  "%-12s RcptCount : %-20s %4d ip_class=[%02X - %s]",
639  CONNID_STR(priv->id), priv->peer_addr, nb_rcpt, ip_class,
640  CTX_NETCLASS_LABEL(priv));
641 
642  {
643  char buf[256];
644  bool ok = FALSE;
645  int vmax = 0;
646 
647  vmax = cf_get_int(CF_MAX_RCPT);
648 
649  if (check_host_policy("MaxRcpt", priv->peer_addr, priv->peer_name,
650  priv->netclass.label, buf, sizeof (buf), TRUE))
651  vmax = zeStr2long(buf, NULL, 0);
652 
653  if (vmax > 0 && (nb_rcpt * COEF) > vmax)
654  result = SMFIS_TEMPFAIL;
655 
656  if (result != SMFIS_CONTINUE) {
658  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_TOO_MUCH_RCPT);
659  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
660  MSG_TOO_MUCH_RCPT, priv->peer_addr, nb_rcpt, ip_class,
661  CTX_NETCLASS_LABEL(priv));
662 
663  log_msg_context(ctx, s);
664 
665  priv->rej_rcpt++;
666  priv->result = result;
667  }
668  }
669 
670  {
671  char buf[256];
672  bool ok = FALSE;
673  int vmax = 0;
674 
675  char fBuf[256];
676 
677  memset(fBuf, 0, sizeof (fBuf));
678  extract_email_address(fBuf, priv->env_from, sizeof (fBuf));
679  if (strlen(fBuf) == 0)
680  strlcpy(fBuf, "nullsender", sizeof (fBuf));
681 
683  if (PolicyLookupEmailAddr("MaxRcptFrom", fBuf, buf, sizeof (buf)))
684  vmax = zeStr2long(buf, NULL, 0);
685 
686  if (vmax > 0 && nb_rcpt > vmax)
687  result = SMFIS_TEMPFAIL;
688 
689  if (result != SMFIS_CONTINUE) {
691  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_TOO_MUCH_RCPT);
692  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
693  MSG_TOO_MUCH_RCPT, priv->peer_addr, nb_rcpt, ip_class,
694  CTX_NETCLASS_LABEL(priv));
695 
696  log_msg_context(ctx, s);
697 
698  priv->rej_rcpt++;
699  priv->result = result;
700  }
701  }
702  }
703 
704  return result;
705 }
706 
707 /* ****************************************************************************
708  * *
709  * *
710  ******************************************************************************/
711 sfsistat
713  SMFICTX *ctx;
714 {
715  CTXPRIV_T *priv = MLFIPRIV(ctx);
716  int result = SMFIS_CONTINUE;
717 
718  if (priv->peer_addr == NULL)
719  return SMFIS_CONTINUE;
720 
722  int ip_class = priv->netclass.class;
723  int nb = priv->nb_open;
724  char s[256];
725  int COEF = 1;
726 
727  nb = priv->nb_open =
728  connopen_check_host(priv->peer_addr, priv->peer_name, 0);
729 
730  GET_RESOLVE_COEF(priv->resolve_res, COEF);
731 
732  nb *= COEF;
733 
734  if (nb > 5) {
736  "%-12s Open Connections : %-20s %4d ip_class=[%02X - %s]",
737  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
738  CTX_NETCLASS_LABEL(priv));
739  } else {
741  "%-12s Open Connections : %-20s %4d ip_class=[%02X - %s]",
742  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
743  CTX_NETCLASS_LABEL(priv));
744  }
745 
746  /*
747  * FALSE && _FFR_DBPOLICY
748  */
749  {
750  char buf[256];
751  bool ok = FALSE;
752  int vmax = 0;
753 
755 
756  if (check_host_policy("ConnOpen", priv->peer_addr, priv->peer_name,
757  priv->netclass.label, buf, sizeof (buf), TRUE))
758  vmax = zeStr2long(buf, NULL, 0);
759 
760  if (vmax > 0 && nb > vmax)
761  result = SMFIS_TEMPFAIL;
762  }
763 
764 
765  if (result != SMFIS_CONTINUE) {
767 
768  (void) jsmfi_setreply(ctx, "421", "4.5.1", MSG_TOO_MUCH_OPEN);
769 
770  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
772  nb, ip_class, CTX_NETCLASS_LABEL(priv));
773 
774  log_msg_context(ctx, s);
775  }
776  }
777 
778  return result;
779 }
780 
781 /* ****************************************************************************
782  * *
783  * *
784  ******************************************************************************/
785 sfsistat
787  SMFICTX *ctx;
788 {
789  CTXPRIV_T *priv = MLFIPRIV(ctx);
790  int result = SMFIS_CONTINUE;
791 
793  int ip_class = priv->netclass.class;
794  int nb = 0;
795  char s[256];
796  int COEF = 1;
797 
798  /*
799  * XXXXXXXXXXXX 3600 ?????
800  */
801  nb = livehistory_check_host(priv->peer_addr, 3600, LH_EMPTYCONN);
802 
803  GET_RESOLVE_COEF(priv->resolve_res, COEF);
804 
805 #if 1
806  nb *= COEF;
807 #endif
808 
809  if (nb > 15) {
811  "%-12s Empty Connections : %-20s %4d ip_class=[%02X - %s]",
812  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
813  CTX_NETCLASS_LABEL(priv));
814  } else {
816  "%-12s Empty Connections : %-20s %4d ip_class=[%02X - %s]",
817  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
818  CTX_NETCLASS_LABEL(priv));
819  }
820 
821  if (IS_UNKNOWN(ip_class) && (nb > cf_get_int(CF_MAX_EMPTY_CONN)))
822  result = SMFIS_TEMPFAIL;
823 
824  if (result != SMFIS_CONTINUE) {
826  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_TOO_MUCH_EMPTY);
827  snprintf(s, sizeof (s), MSG_SHORT_TOO_MUCH_EMPTY, priv->peer_addr, nb,
828  ip_class);
829 
830  log_msg_context(ctx, s);
831  }
832  }
833 
834  return result;
835 }
836 
837 /* ****************************************************************************
838  * *
839  * *
840  ******************************************************************************/
841 sfsistat
843  SMFICTX *ctx;
844 {
845  CTXPRIV_T *priv = MLFIPRIV(ctx);
846  int result = SMFIS_CONTINUE;
847 
849  int nb = 0;
850  int COEF = 1;
851 
852  /*
853  * XXXXXXXXXX 3600 ????
854  */
855  nb = livehistory_check_host(priv->peer_addr, 3600, LH_SPAMTRAP);
856 
857  if (nb == 0)
858  return SMFIS_CONTINUE;
859 
860  GET_RESOLVE_COEF(priv->resolve_res, COEF);
861 
862 #if 0
863 #if 1
864  nb *= COEF;
865 #endif
866 
867  if (nb > 5) {
869  "%-12s Bad Recipients : %-20s %4d ip_class=[%02X - %s]",
870  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
871  CTX_NETCLASS_LABEL(priv));
872  } else {
874  "%-12s Bad Recipients : %-20s %4d ip_class=[%02X - %s]",
875  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
876  CTX_NETCLASS_LABEL(priv));
877  }
878 
879  if (IS_UNKNOWN(ip_class) && (nb > cf_get_int(CF_MAX_BADRCPTS))) {
880  result = SMFIS_TEMPFAIL;
881 
883  switch (result) {
884  case SMFIS_REJECT:
885  (void) jsmfi_setreply(ctx, "550", "5.7.1", MSG_TOO_MUCH_BADRCPT);
886  break;
887  case SMFIS_TEMPFAIL:
888  (void) jsmfi_setreply(ctx, "421", "4.5.1", MSG_TOO_MUCH_BADRCPT);
889  break;
890  }
891  snprintf(s, sizeof (s), MSG_SHORT_TOO_MUCH_BADRCPT,
892  priv->peer_addr, nb, ip_class);
893 
894  log_msg_context(ctx, s);
895  }
896 #endif
897  }
898 
899  return result;
900 }
901 
902 /* ****************************************************************************
903  * *
904  * *
905  ******************************************************************************/
906 sfsistat
908  SMFICTX *ctx;
909 {
910  CTXPRIV_T *priv = MLFIPRIV(ctx);
911  int result = SMFIS_CONTINUE;
912 
914  int ip_class = priv->netclass.class;
915  int nb = 0;
916  char s[256];
917  int COEF = 1;
918 
919  /*
920  * XXXXXXXXXX 3600 ????
921  */
922  nb = livehistory_check_host(priv->peer_addr, 3600, LH_BADRCPT) +
923  priv->nb_cbadrcpt + priv->nb_mbadrcpt;
924 
925  if (nb == 0)
926  return SMFIS_CONTINUE;
927 
928  GET_RESOLVE_COEF(priv->resolve_res, COEF);
929 
930  nb *= COEF;
931 
932  if (nb > 5) {
934  "%-12s Bad Recipients : %-20s %4d ip_class=[%02X - %s]",
935  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
936  CTX_NETCLASS_LABEL(priv));
937  } else {
939  "%-12s Bad Recipients : %-20s %4d ip_class=[%02X - %s]",
940  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
941  CTX_NETCLASS_LABEL(priv));
942  }
943 
944  if (IS_UNKNOWN(ip_class) && (nb > cf_get_int(CF_MAX_BADRCPTS))) {
945  result = SMFIS_TEMPFAIL;
947 #if 1
948  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_TOO_MUCH_BADRCPT);
949 #else
950  (void) jsmfi_setreply(ctx, "451", "4.7.1", MSG_TOO_MUCH_BADRCPT);
951 #endif
952  snprintf(s, sizeof (s), "%s : %s : %d [%02X - %s]",
954  priv->peer_addr, nb, ip_class, CTX_NETCLASS_LABEL(priv));
955 
956  log_msg_context(ctx, s);
957  }
958  }
959 
960  return result;
961 }
962 
963 /* ****************************************************************************
964  * *
965  * *
966  ******************************************************************************/
967 sfsistat
969  SMFICTX *ctx;
970 {
971  CTXPRIV_T *priv = MLFIPRIV(ctx);
972  int result = SMFIS_CONTINUE;
973 
974  int ip_class;
975  char s[256];
976  int COEF = 1;
977  char *why = "bad behaviour in previous MAIL command";
978 
979  ASSERT(priv != NULL);
980 
981  if (priv->nb_from <= 1)
982  goto fin;
983 
984  ip_class = priv->netclass.class;
985  if (IS_KNOWN(ip_class))
986  goto fin;
987 
988  if (priv->dbrcpt_conn_spamtrap > 0) {
989  why = "spamtraps";
990  result = SMFIS_TEMPFAIL;
991  goto fin;
992  }
993 
994  /*
995  * bad MX
996  */
997  if (priv->rej_badmx > 0) {
998  why = "bad MX";
999  result = SMFIS_TEMPFAIL;
1000  goto fin;
1001  }
1002 
1003 
1004  /*
1005  * XFiles
1006  */
1007  if (priv->nb_xfiles > 0) {
1008  why = "XFiles";
1009  result = SMFIS_TEMPFAIL;
1010  goto fin;
1011  }
1012 
1013  /*
1014  * Virus
1015  */
1016  if (priv->nb_virus > 0) {
1017  why = "Virus";
1018  result = SMFIS_TEMPFAIL;
1019  goto fin;
1020  }
1021 #if 0
1023  "%-12s Bad Recipients : %-20s %4d ip_class=[%02X - %s]",
1024  CONNID_STR(priv->id), priv->peer_addr, nb, ip_class,
1025  CTX_NETCLASS_LABEL(priv));
1026 #endif
1027 
1028 fin:
1029  if (result != SMFIS_CONTINUE) {
1031 
1032  result = SMFIS_TEMPFAIL;
1033  (void) jsmfi_setreply(ctx, "451", "4.3.2", MSG_SINGLE_MESSAGE);
1034 
1035  snprintf(s, sizeof (s), "%s : %s [%s]",
1037 
1038  log_msg_context(ctx, s);
1039  }
1040 
1041  return result;
1042 }
1043 
1044 /* ****************************************************************************
1045  * *
1046  * *
1047  ******************************************************************************/
1048 
1049 sfsistat
1051  SMFICTX *ctx;
1052 {
1053  CTXPRIV_T *priv = MLFIPRIV(ctx);
1054  int result = SMFIS_CONTINUE;
1055 
1056  if (ctx == NULL || priv == NULL)
1057  return result;
1058 
1059  result = check_open_connections(ctx);
1060  if (result != SMFIS_CONTINUE) {
1061  priv->rej_open = TRUE;
1062  goto fin;
1063  }
1064 
1065  if (priv->callback_id < CALLBACK_MAIL &&
1067  goto fin;
1068 
1069  result = check_connrate(ctx);
1070  if (result != SMFIS_CONTINUE) {
1071  priv->rej_conn_rate = TRUE;
1072  goto fin;
1073  }
1074 
1075  if (priv->callback_id == CALLBACK_CONNECT)
1076  goto fin;
1077 
1078  /*
1079  ** if client resolv limit is set on :
1080  ** connections -> CALLBACK_EHLO
1081  ** messages -> CALLBACK_MAIL
1082  */
1083  if (priv->callback_id == CALLBACK_MAIL) {
1084  result = check_dns_resolve(ctx);
1085 
1086  if (result != SMFIS_CONTINUE) {
1087  priv->rej_resolve = TRUE;
1088  goto fin;
1089  }
1090 
1091  result = check_single_message(ctx);
1092  if (result != SMFIS_CONTINUE) {
1093  /*
1094  * priv->rej_resolve = TRUE;
1095  */
1096  goto fin;
1097  }
1098  }
1099 #if 0
1100  result = check_spamtrap(ctx);
1101  if (result != SMFIS_CONTINUE) {
1102  priv->rej_badrcpt = TRUE;
1103  goto fin;
1104  }
1105 #endif
1106 
1107  (void) update_nb_badrcpts(ctx);
1108  result = check_nb_badrcpts(ctx);
1109  if (result != SMFIS_CONTINUE) {
1110  priv->rej_badrcpt = TRUE;
1111  goto fin;
1112  }
1113 
1114  result = check_empty_connections(ctx);
1115  if (result != SMFIS_CONTINUE) {
1116  priv->rej_empty = TRUE;
1117  goto fin;
1118  }
1119 
1120 fin:
1121  priv->reject_connect = (result != SMFIS_CONTINUE);
1122  if (result != SMFIS_CONTINUE)
1123  priv->result = result;
1124 
1125  return result;
1126 }
#define MSG_RCPT_RATE
Definition: ze-reply.h:129
#define MSG_SHORT_SINGLE_MESSAGE
Definition: ze-reply.h:235
#define MSG_TOO_MUCH_OPEN
Definition: ze-reply.h:121
#define CF_CHECK_RESOLVE_FAIL
Definition: cfh-defs.h:185
#define GET_RESOLVE_COEF(resolve, coef)
#define CF_CHECK_EMPTY_CONNECTIONS
Definition: cfh-defs.h:146
sfsistat check_nb_badrcpts(SMFICTX *ctx)
bool rej_conn_rate
#define CF_CHECK_SPAMTRAP_HISTORY
Definition: cfh-defs.h:154
void stats_inc(int, long)
Definition: ze-stats.c:401
#define CF_CHECK_NB_RCPT
Definition: cfh-defs.h:157
#define MSG_TOO_MUCH_EMPTY
Definition: ze-reply.h:113
bool PolicyLookupEmailAddr(char *prefix, char *key, char *buf, size_t size)
Definition: zePolicy.c:230
#define STAT_SINGLE_MESSAGE
Definition: ze-stats.h:68
#define CALLBACK_CONNECT
Definition: ze-callback.h:28
#define CF_MAX_CONN_OPEN
Definition: cfh-defs.h:145
#define ASSERT(a)
Definition: macros.h:27
#define SMFIS_TEMPFAIL
#define MSG_MSG_RATE
Definition: ze-reply.h:133
int jsmfi_setreply(SMFICTX *, char *, char *, char *)
Definition: ze-libmilter.c:99
bool check_host_policy(char *prefix, char *addr, char *name, char *class, char *buf, size_t size, bool cdef)
Definition: ze-policy.c:205
#define CF_MAX_EMPTY_CONN
Definition: cfh-defs.h:147
#define CF_MAX_FROM_RCPT
Definition: cfh-defs.h:166
#define MUTEX_UNLOCK(mutex)
Definition: macros.h:101
#define CF_CHECK_RCPT_RATE
Definition: cfh-defs.h:155
char * peer_addr
#define STRNULL(x, r)
Definition: macros.h:81
#define MSG_SINGLE_MESSAGE
Definition: ze-reply.h:145
bool ok
Definition: ze-connopen.c:59
#define MUTEX_LOCK(mutex)
Definition: macros.h:93
pthread_mutex_t mutex
Definition: ze-connopen.c:63
#define CF_MAX_RCPT_RATE
Definition: cfh-defs.h:156
#define CF_CHECK_CONN_RATE
Definition: cfh-defs.h:142
#define MSG_SHORT_TOO_MUCH_BADRCPT
Definition: ze-reply.h:251
bool rej_msg_rate
#define FALSE
Definition: macros.h:160
#define SMFIS_CONTINUE
#define STAT_EMPTY_CONN
Definition: ze-stats.h:72
#define SMFIS_REJECT
#define strlcpy
Definition: zeString.h:32
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
char * extract_email_address(char *, char *, size_t)
#define LH_SPAMTRAP
#define OPT_YES
Definition: ze-cf.h:45
#define MSG_TOO_MUCH_RCPT
Definition: ze-reply.h:97
sfsistat check_empty_connections(SMFICTX *ctx)
#define RESOLVE_FORGED
Definition: ze-filter.h:173
bool reject_connect
sfsistat check_spamtrap(SMFICTX *ctx)
#define CF_MAX_BAD_RESOLVE
Definition: cfh-defs.h:187
#define CF_MAX_RCPT
Definition: cfh-defs.h:158
int cf_get_int(int id)
Definition: ze-cf.c:803
#define MLFIPRIV(ctx)
#define CF_MAX_FROM_RCPT_RATE
Definition: cfh-defs.h:164
#define RATE_AUTH_MSGS
Definition: ze-smtprate.h:67
#define CF_MAX_MSGS
Definition: cfh-defs.h:162
sfsistat check_connrate(SMFICTX *ctx)
#define MSG_SHORT_RESOLVE_FORGED
Definition: ze-reply.h:215
bool rej_resolve
#define MSG_SHORT_MSG_RATE
Definition: ze-reply.h:231
#define LH_EMPTYCONN
#define MSG_TOO_MUCH_MSGS
Definition: ze-reply.h:137
#define STAT_RCPT_RATE
Definition: ze-stats.h:45
#define CF_MAX_MSG_RATE
Definition: cfh-defs.h:160
CONNID_T id
sfsistat check_msgrate(SMFICTX *ctx)
#define LH_BADRCPT
long zeStr2long(char *s, int *error, long dval)
Definition: zeStrConvert.c:35
#define MSG_TOO_MUCH_BADRCPT
Definition: ze-reply.h:117
#define CF_MAX_FROM_MSG_RATE
Definition: cfh-defs.h:168
#define IS_KNOWN(class)
Definition: ze-netclass.h:50
#define MSG_SHORT_RESOLVE_FAIL
Definition: ze-reply.h:219
#define MSG_RESOLVE_FAIL
Definition: ze-reply.h:101
#define RESOLVE_OK
Definition: ze-filter.h:171
#define IS_UNKNOWN(class)
Definition: ze-netclass.h:51
#define CALLBACK_MAIL
Definition: ze-callback.h:30
#define MSG_SHORT_RCPT_RATE
Definition: ze-reply.h:227
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
int nb
Definition: ze-connopen.c:61
#define OPT_NO
Definition: ze-cf.h:44
sfsistat check_rcptrate(SMFICTX *ctx)
int dbrcpt_conn_spamtrap
#define RATE_MSGS
Definition: ze-smtprate.h:54
#define STAT_CONN_RATE
Definition: ze-stats.h:44
#define TRUE
Definition: macros.h:157
#define STAT_RESOLVE_FAIL
Definition: ze-stats.h:41
#define STAT_MAX_RCPT
Definition: ze-stats.h:43
sfsistat check_msgcount(SMFICTX *ctx)
#define MSG_SHORT_TOO_MUCH_EMPTY
Definition: ze-reply.h:247
#define RATE_RCPT
Definition: ze-smtprate.h:52
sfsistat validate_connection(SMFICTX *ctx)
#define MSG_SHORT_CONN_RATE
Definition: ze-reply.h:223
#define CF_CHECK_OPEN_CONNECTIONS
Definition: cfh-defs.h:144
char * peer_name
#define CTX_NETCLASS_LABEL(priv)
int smtprate_check(int, char *, time_t)
Definition: ze-smtprate.c:479
char * env_from
int connopen_check_host(char *, char *, int)
Definition: ze-connopen.c:151
#define STAT_BAD_RCPT
Definition: ze-stats.h:74
#define CF_CHECK_BADRCPTS
Definition: cfh-defs.h:149
#define CF_MAX_CONN_RATE
Definition: cfh-defs.h:143
uint32_t ehlo_flags
#define CF_MAX_BADRCPTS
Definition: cfh-defs.h:150
#define CONNID_STR(connid)
Definition: ze-filter.h:113
sfsistat check_dns_resolve(SMFICTX *ctx)
#define HOURS
Definition: macros.h:144
#define CF_CHECK_NB_MSGS
Definition: cfh-defs.h:161
#define MSG_RESOLVE_FORGED
Definition: ze-reply.h:105
sfsistat check_single_message(SMFICTX *ctx)
int update_nb_badrcpts(SMFICTX *)
#define STAT_MSG_RATE
Definition: ze-stats.h:69
bool rej_badrcpt
netclass_T netclass
#define MSG_CONN_RATE
Definition: ze-reply.h:125
int livehistory_check_host(char *, time_t, int)
int livehistory_add_entry(char *, time_t, int, int)
#define MSG_SHORT_TOO_MUCH_OPEN
Definition: ze-reply.h:243
#define RATE_FROM_MSGS
Definition: ze-smtprate.h:63
#define CF_DELAY_CHECKS
Definition: cfh-defs.h:148
char label[32]
Definition: ze-netclass.h:72
void log_msg_context(SMFICTX *ctx, char *why)
#define RATE_LOG_LEVEL
#define RATE_FROM_RCPT
Definition: ze-smtprate.h:64
#define CF_CHECK_MSG_RATE
Definition: cfh-defs.h:159
sfsistat check_open_connections(SMFICTX *ctx)
#define STAT_OPEN_CONN
Definition: ze-stats.h:71
#define CF_CHECK_RESOLVE_FORGED
Definition: cfh-defs.h:186
#define LH_BAD_RESOLVE
#define RESOLVE_NULL
Definition: ze-filter.h:170
#define STAT_RESOLVE_FORGED
Definition: ze-stats.h:42
#define STAT_MAX_MSGS
Definition: ze-stats.h:46
#define RATE_CONN
Definition: ze-smtprate.h:51
sfsistat check_rcptcount(SMFICTX *ctx)
#define RESOLVE_FAIL
Definition: ze-filter.h:172
#define DEFAULT_WINDOW
Definition: ze-smtprate.h:72