Browse code

Fix compilation error on FreeBSD

git-svn: trunk@2376

Nigel Horne authored on 2006/10/13 23:44:01
Showing 2 changed files
... ...
@@ -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
 }