git-svn: trunk@2376
Nigel Horne authored on 2006/10/13 23:44:01... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Fri Oct 13 15:42:43 BST 2006 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/mbox.c: Fix compilation warning on FreeBSD |
|
4 |
+ * clamav-milter: Fix compilation error on FreeBSD |
|
5 |
+ Blacklist multiple emails in the same connexion |
|
6 |
+ |
|
1 | 7 |
Wed Oct 11 01:05:37 CEST 2006 (tk) |
2 | 8 |
---------------------------------- |
3 | 9 |
* libclamav: apply patches for the anti-phish code from Edwin: |
... | ... |
@@ -2,7 +2,7 @@ |
2 | 2 |
* clamav-milter.c |
3 | 3 |
* .../clamav-milter/clamav-milter.c |
4 | 4 |
* |
5 |
- * Copyright (C) 2003-2006 Nigel Horne <njh@bandsman.co.uk> |
|
5 |
+ * Copyright (C) 2003- Nigel Horne <njh@bandsman.co.uk> |
|
6 | 6 |
* |
7 | 7 |
* This program is free software; you can redistribute it and/or modify |
8 | 8 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -23,9 +23,9 @@ |
23 | 23 |
* |
24 | 24 |
* For installation instructions see the file INSTALL that came with this file |
25 | 25 |
*/ |
26 |
-static char const rcsid[] = "$Id: clamav-milter.c,v 1.290 2006/09/28 12:36:45 njh Exp $"; |
|
26 |
+static char const rcsid[] = "$Id: clamav-milter.c,v 1.291 2006/10/13 14:42:15 njh Exp $"; |
|
27 | 27 |
|
28 |
-#define CM_VERSION "devel-270906" |
|
28 |
+#define CM_VERSION "devel-131006" |
|
29 | 29 |
|
30 | 30 |
#if HAVE_CONFIG_H |
31 | 31 |
#include "clamav-config.h" |
... | ... |
@@ -86,6 +86,9 @@ static char const rcsid[] = "$Id: clamav-milter.c,v 1.290 2006/09/28 12:36:45 nj |
86 | 86 |
#include <arpa/nameser.h> /* for HEADER */ |
87 | 87 |
#include <resolv.h> |
88 | 88 |
#endif |
89 |
+#ifdef HAVE_UNISTD_H |
|
90 |
+#include <unistd.h> |
|
91 |
+#endif |
|
89 | 92 |
|
90 | 93 |
#if HAVE_MMAP |
91 | 94 |
#if HAVE_SYS_MMAN_H |
... | ... |
@@ -178,13 +181,13 @@ typedef unsigned int in_addr_t; |
178 | 178 |
*/ |
179 | 179 |
|
180 | 180 |
struct header_node_t { |
181 |
- char *header; |
|
182 |
- struct header_node_t *next; |
|
181 |
+ char *header; |
|
182 |
+ struct header_node_t *next; |
|
183 | 183 |
}; |
184 | 184 |
|
185 | 185 |
struct header_list_struct { |
186 |
- struct header_node_t *first; |
|
187 |
- struct header_node_t *last; |
|
186 |
+ struct header_node_t *first; |
|
187 |
+ struct header_node_t *last; |
|
188 | 188 |
}; |
189 | 189 |
|
190 | 190 |
typedef struct header_list_struct *header_list_t; |
... | ... |
@@ -2565,93 +2568,114 @@ clamfi_envfrom(SMFICTX *ctx, char **argv) |
2565 | 2565 |
privdata = smfi_getpriv(ctx); |
2566 | 2566 |
|
2567 | 2567 |
if(privdata == NULL) { |
2568 |
- /* More than one message on this connection */ |
|
2569 |
- /* FIXME: if the last one sent a virus we should blacklist */ |
|
2570 | 2568 |
privdata = (struct privdata *)cli_calloc(1, sizeof(struct privdata)); |
2571 | 2569 |
if(privdata == NULL) |
2572 | 2570 |
return cl_error; |
2573 |
- |
|
2574 |
-#ifdef SESSION |
|
2575 |
- privdata->dataSocket = -1; |
|
2576 |
-#else |
|
2577 |
- privdata->dataSocket = privdata->cmdSocket = -1; |
|
2578 |
-#endif |
|
2579 |
- |
|
2580 | 2571 |
if(smfi_setpriv(ctx, privdata) != MI_SUCCESS) { |
2581 | 2572 |
free(privdata); |
2582 | 2573 |
return cl_error; |
2583 | 2574 |
} |
2584 |
- } |
|
2575 |
+ if(max_children > 0) { |
|
2576 |
+ int rc = 0; |
|
2585 | 2577 |
|
2586 |
- if(max_children > 0) { |
|
2587 |
- int rc = 0; |
|
2578 |
+ pthread_mutex_lock(&n_children_mutex); |
|
2588 | 2579 |
|
2589 |
- pthread_mutex_lock(&n_children_mutex); |
|
2590 |
- |
|
2591 |
- /* |
|
2592 |
- * Wait a while since sendmail doesn't like it if we |
|
2593 |
- * take too long replying. Effectively this means that |
|
2594 |
- * max_children is more of a hint than a rule |
|
2595 |
- */ |
|
2596 |
- if(n_children >= max_children) { |
|
2597 |
- struct timespec timeout; |
|
2598 |
- struct timeval now; |
|
2599 |
- struct timezone tz; |
|
2600 |
- |
|
2601 |
- logg((dont_wait) ? |
|
2602 |
- _("hit max-children limit (%u >= %u)\n") : |
|
2603 |
- _("hit max-children limit (%u >= %u): waiting for some to exit\n"), |
|
2604 |
- n_children, max_children); |
|
2605 |
- |
|
2606 |
- if(dont_wait) { |
|
2607 |
- pthread_mutex_unlock(&n_children_mutex); |
|
2608 |
- smfi_setreply(ctx, "451", "4.3.2", _("AV system temporarily overloaded - please try later")); |
|
2609 |
- free(privdata); |
|
2610 |
- smfi_setpriv(ctx, NULL); |
|
2611 |
- return SMFIS_TEMPFAIL; |
|
2612 |
- } |
|
2613 | 2580 |
/* |
2614 |
- * Wait for an amount of time for a child to go |
|
2615 |
- * |
|
2616 |
- * Use pthread_cond_timedwait rather than |
|
2617 |
- * pthread_cond_wait since the sendmail which calls |
|
2618 |
- * us will have a timeout that we don't want to exceed, |
|
2619 |
- * stops sendmail getting fidgety. |
|
2620 |
- * |
|
2621 |
- * Patch from Damian Menscher <menscher@uiuc.edu> to |
|
2622 |
- * ensure it wakes up when a child goes away |
|
2581 |
+ * Wait a while since sendmail doesn't like it if we |
|
2582 |
+ * take too long replying. Effectively this means that |
|
2583 |
+ * max_children is more of a hint than a rule |
|
2623 | 2584 |
*/ |
2624 |
- gettimeofday(&now, &tz); |
|
2625 |
- do { |
|
2626 |
- logg(_("n_children %d: waiting %d seconds for some to exit"), |
|
2627 |
- n_children, child_timeout); |
|
2585 |
+ if(n_children >= max_children) { |
|
2586 |
+ struct timespec timeout; |
|
2587 |
+ struct timeval now; |
|
2588 |
+ struct timezone tz; |
|
2589 |
+ |
|
2590 |
+ logg((dont_wait) ? |
|
2591 |
+ _("hit max-children limit (%u >= %u)\n") : |
|
2592 |
+ _("hit max-children limit (%u >= %u): waiting for some to exit\n"), |
|
2593 |
+ n_children, max_children); |
|
2594 |
+ |
|
2595 |
+ if(dont_wait) { |
|
2596 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
2597 |
+ smfi_setreply(ctx, "451", "4.3.2", _("AV system temporarily overloaded - please try later")); |
|
2598 |
+ free(privdata); |
|
2599 |
+ smfi_setpriv(ctx, NULL); |
|
2600 |
+ return SMFIS_TEMPFAIL; |
|
2601 |
+ } |
|
2602 |
+ /* |
|
2603 |
+ * Wait for an amount of time for a child to go |
|
2604 |
+ * |
|
2605 |
+ * Use pthread_cond_timedwait rather than |
|
2606 |
+ * pthread_cond_wait since the sendmail which |
|
2607 |
+ * calls us will have a timeout that we don't |
|
2608 |
+ * want to exceed, stops sendmail getting |
|
2609 |
+ * fidgety. |
|
2610 |
+ * |
|
2611 |
+ * Patch from Damian Menscher |
|
2612 |
+ * <menscher@uiuc.edu> to ensure it wakes up |
|
2613 |
+ * when a child goes away |
|
2614 |
+ */ |
|
2615 |
+ gettimeofday(&now, &tz); |
|
2616 |
+ do { |
|
2617 |
+ logg(_("n_children %d: waiting %d seconds for some to exit"), |
|
2618 |
+ n_children, child_timeout); |
|
2619 |
+ |
|
2620 |
+ if(child_timeout == 0) { |
|
2621 |
+ pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
2622 |
+ rc = 0; |
|
2623 |
+ } else { |
|
2624 |
+ timeout.tv_sec = now.tv_sec + child_timeout; |
|
2625 |
+ timeout.tv_nsec = 0; |
|
2628 | 2626 |
|
2629 |
- if(child_timeout == 0) { |
|
2630 |
- pthread_cond_wait(&n_children_cond, &n_children_mutex); |
|
2631 |
- rc = 0; |
|
2632 |
- } else { |
|
2633 |
- timeout.tv_sec = now.tv_sec + child_timeout; |
|
2634 |
- timeout.tv_nsec = 0; |
|
2627 |
+ rc = pthread_cond_timedwait(&n_children_cond, &n_children_mutex, &timeout); |
|
2628 |
+ } |
|
2629 |
+ } while((n_children >= max_children) && (rc != ETIMEDOUT)); |
|
2630 |
+ logg(_("Finished waiting, n_children = %d\n"), n_children); |
|
2631 |
+ } |
|
2632 |
+ n_children++; |
|
2635 | 2633 |
|
2636 |
- rc = pthread_cond_timedwait(&n_children_cond, &n_children_mutex, &timeout); |
|
2637 |
- } |
|
2638 |
- } while((n_children >= max_children) && (rc != ETIMEDOUT)); |
|
2639 |
- logg(_("Finished waiting, n_children = %d\n"), n_children); |
|
2634 |
+ cli_dbgmsg(">n_children = %d\n", n_children); |
|
2635 |
+ pthread_mutex_unlock(&n_children_mutex); |
|
2636 |
+ |
|
2637 |
+ if(child_timeout && (rc == ETIMEDOUT)) |
|
2638 |
+ logg(_("*Timeout waiting for a child to die\n")); |
|
2640 | 2639 |
} |
2641 |
- n_children++; |
|
2642 | 2640 |
|
2643 |
- cli_dbgmsg(">n_children = %d\n", n_children); |
|
2644 |
- pthread_mutex_unlock(&n_children_mutex); |
|
2641 |
+ } else { |
|
2642 |
+ /* More than one message on this connection */ |
|
2643 |
+ char ip[INET_ADDRSTRLEN]; |
|
2645 | 2644 |
|
2646 |
- if(child_timeout && (rc == ETIMEDOUT)) { |
|
2647 |
-#ifdef CL_DEBUG |
|
2648 |
- if(use_syslog) |
|
2649 |
- syslog(LOG_NOTICE, _("Timeout waiting for a child to die")); |
|
2650 |
-#endif |
|
2651 |
- cli_dbgmsg(_("Timeout waiting for a child to die\n")); |
|
2645 |
+ strcpy(ip, privdata->ip); |
|
2646 |
+ if(isBlacklisted(ip)) { |
|
2647 |
+ logg("Rejected email from blacklisted IP %s\n", ip); |
|
2648 |
+ |
|
2649 |
+ /* |
|
2650 |
+ * TODO: Option to greylist rather than blacklist, by sending |
|
2651 |
+ * a try again code |
|
2652 |
+ * TODO: state *which* virus |
|
2653 |
+ */ |
|
2654 |
+ smfi_setreply(ctx, "550", "5.7.1", _("Your IP is blacklisted because your machine is infected with a virus")); |
|
2655 |
+ broadcast(_("Blacklisted IP detected")); |
|
2656 |
+ |
|
2657 |
+ /* |
|
2658 |
+ * Keep them blacklisted |
|
2659 |
+ */ |
|
2660 |
+ pthread_mutex_lock(&blacklist_mutex); |
|
2661 |
+ (void)tableUpdate(blacklist, ip, (int)time((time_t *)0)); |
|
2662 |
+ pthread_mutex_unlock(&blacklist_mutex); |
|
2663 |
+ |
|
2664 |
+ return SMFIS_REJECT; |
|
2652 | 2665 |
} |
2666 |
+ memset(privdata, '\0', sizeof(struct privdata)); |
|
2667 |
+ strcpy(privdata->ip, ip); |
|
2653 | 2668 |
} |
2654 | 2669 |
|
2670 |
+#ifdef SESSION |
|
2671 |
+ privdata->dataSocket = -1; |
|
2672 |
+#else |
|
2673 |
+ privdata->dataSocket = privdata->cmdSocket = -1; |
|
2674 |
+#endif |
|
2675 |
+ |
|
2655 | 2676 |
/* |
2656 | 2677 |
* Rejection is via 550 until DATA is received. We know that |
2657 | 2678 |
* DATA has been sent when either we get a header or the end of |
... | ... |
@@ -3626,7 +3650,7 @@ clamfi_eom(SMFICTX *ctx) |
3626 | 3626 |
} |
3627 | 3627 |
} |
3628 | 3628 |
} |
3629 |
- clamfi_cleanup(ctx); |
|
3629 |
+ /*clamfi_cleanup(ctx);*/ |
|
3630 | 3630 |
|
3631 | 3631 |
return rc; |
3632 | 3632 |
} |