Browse code

Chroot handling no longer marked as experimental

git-svn: trunk@3151

Nigel Horne authored on 2007/07/16 07:07:17
Showing 2 changed files
... ...
@@ -1,3 +1,9 @@
1
+Sun Jul 15 22:12:45 BST 2007 (njh)
2
+----------------------------------
3
+  * clamav-milter:	Chroot handling no longer marked as experimental
4
+			Experimental mode: handle loops in INCLUDE: SPF
5
+				statements
6
+
1 7
 Sun Jul 15 13:27:46 BST 2007 (njh)
2 8
 ----------------------------------
3 9
   * clamav-milter:	Experimental mode: Reduce the number of SPF DNS queries
... ...
@@ -198,7 +198,7 @@ typedef	unsigned int	in_addr_t;
198 198
  * TODO: allow each To: line in the whitelist file to specify a quarantine email
199 199
  *	address
200 200
  * TODO: optionally use zlib to compress data sent to remote hosts
201
- * TODO: Finish IPv6 support (serverIPs array is IPv4 only)
201
+ * TODO: Finish IPv6 support (serverIPs array and SPF are IPv4 only)
202 202
  */
203 203
 
204 204
 struct header_node_t {
... ...
@@ -279,7 +279,7 @@ struct	privdata {
279 279
 				 * looks like the remote end is playing ping
280 280
 				 * pong with us
281 281
 				 */
282
-#ifdef	CL_EXPERIMENTAL
282
+#if	defined(HAVE_RESOLV_H) && defined(CL_EXPERIMENTAL)
283 283
 	unsigned	int	spf_ok:1;
284 284
 #endif
285 285
 	int	statusCount;	/* number of X-Virus-Status headers */
... ...
@@ -490,10 +490,7 @@ static	int	numServers;	/* number of elements in serverIPs array */
490 490
 #define	RETRY_SECS	300	/* How often to retry a server that's down */
491 491
 static	time_t	*last_failed_pings;	/* For servers that are down. NB: not mutexed */
492 492
 #endif
493
-
494
-#ifdef	CL_EXPERIMENTAL
495 493
 static	char	*rootdir;	/* for chroot */
496
-#endif
497 494
 
498 495
 #ifdef	SESSION
499 496
 static	struct	session {
... ...
@@ -567,7 +564,7 @@ static	table_t	*mx(const char *host, table_t *t);
567 567
 #ifdef	HAVE_RESOLV_H
568 568
 static	table_t	*resolve(const char *host, table_t *t);
569 569
 #ifdef	CL_EXPERIMENTAL
570
-static	int	spf(struct privdata *privdata);
570
+static	int	spf(struct privdata *privdata, table_t *prevhosts);
571 571
 static	void	spf_ip(char *ip, int zero, void *v);
572 572
 #endif
573 573
 #endif
... ...
@@ -590,9 +587,7 @@ help(void)
590 590
 	puts(_("\t--bounce\t\t-b\tSend a failure message to the sender."));
591 591
 #endif
592 592
 	puts(_("\t--broadcast\t\t-B [IFACE]\tBroadcast to a network manager when a virus is found."));
593
-#ifdef	CL_EXPERIMENTAL
594 593
 	puts(_("\t--chroot=DIR\t\t-C DIR\tChroot to dir when starting."));
595
-#endif
596 594
 	puts(_("\t--config-file=FILE\t-c FILE\tRead configuration from FILE."));
597 595
 	puts(_("\t--debug\t\t\t-D\tPrint debug messages."));
598 596
 	puts(_("\t--detect-forged-local-address\t-L\tReject mails that claim to be from us."));
... ...
@@ -891,11 +886,9 @@ main(int argc, char **argv)
891 891
 			case 'c':	/* where is clamd.conf? */
892 892
 				cfgfile = optarg;
893 893
 				break;
894
-#ifdef	CL_EXPERIMENTAL
895 894
 			case 'C':	/* chroot */
896 895
 				rootdir = optarg;
897 896
 				break;
898
-#endif
899 897
 			case 'd':	/* don't scan on error */
900 898
 				cl_error = SMFIS_ACCEPT;
901 899
 				break;
... ...
@@ -1059,9 +1052,7 @@ main(int argc, char **argv)
1059 1059
 	}
1060 1060
 	port = argv[optind];
1061 1061
 
1062
-#ifdef	CL_EXPERIMENTAL
1063 1062
 	if(rootdir == NULL)	/* FIXME: Handle CHROOT */
1064
-#endif
1065 1063
 		if(verifyIncomingSocketName(port) < 0) {
1066 1064
 			fprintf(stderr, _("%s: socket-addr (%s) doesn't agree with sendmail.cf\n"), argv[0], port);
1067 1065
 			return EX_CONFIG;
... ...
@@ -1888,7 +1879,6 @@ main(int argc, char **argv)
1888 1888
 
1889 1889
 	broadcast(_("Starting clamav-milter"));
1890 1890
 
1891
-#ifdef	CL_EXPERIMENTAL
1892 1891
 	if(rootdir) {
1893 1892
 		if(getuid() == 0) {
1894 1893
 			if(chdir(rootdir) < 0) {
... ...
@@ -1905,7 +1895,6 @@ main(int argc, char **argv)
1905 1905
 			return EX_CONFIG;
1906 1906
 		}
1907 1907
 	}
1908
-#endif
1909 1908
 
1910 1909
 	if(pidfile) {
1911 1910
 		/* save the PID */
... ...
@@ -1923,9 +1912,7 @@ main(int argc, char **argv)
1923 1923
 		q = strrchr(p, '/');
1924 1924
 		*q = '\0';
1925 1925
 
1926
-#ifdef	CL_EXPERIMENTAL
1927 1926
 		if(rootdir == NULL)
1928
-#endif
1929 1927
 			if(chdir(p) < 0)	/* safety */
1930 1928
 				perror(p);
1931 1929
 
... ...
@@ -1944,14 +1931,10 @@ main(int argc, char **argv)
1944 1944
 		fclose(fd);
1945 1945
 		umask(old_umask);
1946 1946
 	} else if(tmpdir) {
1947
-#ifdef	CL_EXPERIMENTAL
1948 1947
 		if(rootdir == NULL)
1949
-#endif
1950 1948
 			chdir(tmpdir);	/* safety */
1951 1949
 	} else
1952
-#ifdef	CL_EXPERIMENTAL
1953 1950
 		if(rootdir == NULL)
1954
-#endif
1955 1951
 #ifdef	P_tmpdir
1956 1952
 			chdir(P_tmpdir);
1957 1953
 #else
... ...
@@ -3448,12 +3431,16 @@ clamfi_eom(SMFICTX *ctx)
3448 3448
 	 * TODO: it would be useful to add a header if mbox.c/FOLLOWURLS was
3449 3449
 	 * exceeded
3450 3450
 	 */
3451
-#ifdef	CL_EXPERIMENTAL
3452
-	if((strstr(mess, "FOUND") != NULL) && (strstr(mess, "Phishing") != NULL))
3453
-		if(spf(privdata)) {
3451
+#if	defined(HAVE_RESOLV_H) && defined(CL_EXPERIMENTAL)
3452
+	if((strstr(mess, "FOUND") != NULL) && (strstr(mess, "Phishing") != NULL)) {
3453
+		table_t *prevhosts = tableCreate();
3454
+
3455
+		if(spf(privdata, NULL)) {
3454 3456
 			logg(_("%s: Ignoring phish false positive\n"), sendmailId);
3455 3457
 			strcpy(mess, "OK");
3456 3458
 		}
3459
+		tableDestroy(prevhosts);
3460
+	}
3457 3461
 #endif
3458 3462
 	if(strstr(mess, "ERROR") != NULL) {
3459 3463
 		if(strstr(mess, "Size limit reached") != NULL) {
... ...
@@ -6117,18 +6104,23 @@ resolve(const char *host, table_t *t)
6117 6117
 #ifdef	CL_EXPERIMENTAL
6118 6118
 /*
6119 6119
  * Validate SPF records to help to stop Phish false positives
6120
+ * http://www.openspf.org/SPF_Record_Syntax
6121
+ *
6120 6122
  * Currently only handles ip4, a and mx fields in the DNS record
6121 6123
  * Having said that, this is NOT a replacement for spf-milter, it is NOT
6122 6124
  *	an SPF system, we ONLY use SPF records to reduce phish false positives
6123 6125
  * TODO: ptr
6124 6126
  * TODO: IPv6?
6125
- * TODO: cache queries
6127
+ * TODO: cache queries?
6126 6128
  *
6129
+ * INPUT: prevhosts, a list of hosts already searched: stops include loops
6130
+ *	e.g. mercado.com includes medrcadosw.com which includes mercado.com,
6131
+ *	causing a loop
6127 6132
  * Return 1 if SPF says this email is from a legitimate source
6128 6133
  *	0 for fail or unknown
6129 6134
  */
6130 6135
 static int
6131
-spf(struct privdata *privdata)
6136
+spf(struct privdata *privdata, table_t *prevhosts)
6132 6137
 {
6133 6138
 	char *host, *ptr;
6134 6139
 	u_char *p, *end;
... ...
@@ -6140,6 +6132,8 @@ spf(struct privdata *privdata)
6140 6140
 	} q;
6141 6141
 	char buf[BUFSIZ];
6142 6142
 
6143
+	if(privdata->spf_ok)
6144
+		return 1;
6143 6145
 	if(privdata->ip[0] == '\0')
6144 6146
 		return 0;
6145 6147
 	if(strcmp(privdata->ip, "127.0.0.1") == 0) {
... ...
@@ -6305,18 +6299,20 @@ spf(struct privdata *privdata)
6305 6305
 				} else if(strncmp(record, "include:", 8) == 0) {
6306 6306
 					const char *inchost = &record[8];
6307 6307
 
6308
-					if(*inchost && (strcmp(inchost, host) != 0)) {
6309
-						/*
6310
-						 * FIXME: loops: a.com includes
6311
-						 *	b.com which includes
6312
-						 *	a.com
6313
-						 */
6308
+					/*
6309
+					 * Ensure we haven't already looked at
6310
+					 *	the host that's to be included
6311
+					 */
6312
+					if(*inchost &&
6313
+					   (strcmp(inchost, host) != 0) &&
6314
+					   (tableFind(prevhosts, inchost) == -1)) {
6314 6315
 						const char *real_from = privdata->from;
6315 6316
 						privdata->from = cli_malloc(strlen(inchost) + 3);
6316 6317
 						sprintf(privdata->from, "n@%s", inchost);
6317
-						spf(privdata);
6318
+						spf(privdata, prevhosts);
6318 6319
 						free(privdata->from);
6319 6320
 						privdata->from = real_from;
6321
+						tableInsert(prevhosts, inchost, 0);
6320 6322
 					}
6321 6323
 				}
6322 6324
 				free(record);