Browse code

Some work on maxStreamLength

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@540 77e5149b-7576-45b1-b177-96237e5ba77b

Nigel Horne authored on 2004/05/06 20:25:20
Showing 2 changed files
... ...
@@ -374,6 +374,12 @@ Changes
374 374
 			been given. There has never been one to return
375 375
 0.70u	29/4/04	When changing from realloc to cli_realloc I forgot to keep the
376 376
 		assignment of signature
377
+0.70v	6/5/04	clamfi_close now always checks privdata is NULL, not only when
378
+			debugging
379
+		Allow transfers of exactly streamMaxLength
380
+		Warn if a clean file can't be removed from the quarantine
381
+		When streamMaxLength is exceeded add a header where possible,
382
+			unless --noxheader is given
377 383
 
378 384
 BUG REPORTS
379 385
 
... ...
@@ -376,9 +376,19 @@
376 376
  *				one to return
377 377
  *	0.70u	29/4/04	When changing from realloc to cli_realloc I forgot
378 378
  *			to keep the assignment of signature
379
+ *	0.70v	6/5/04	clamfi_close now always checks privdata is NULL, not
380
+ *				only when debugging
381
+ *			Allow transfers of exactly streamMaxLength
382
+ *			Warn if a clean file can't be removed from the
383
+ *				quarantine
384
+ *			When streamMaxLength is exceeded add a header where
385
+ *				possible, unless --noxheader is given
379 386
  *
380 387
  * Change History:
381 388
  * $Log: clamav-milter.c,v $
389
+ * Revision 1.86  2004/05/06 11:25:20  nigelhorne
390
+ * Some work on maxStreamLength
391
+ *
382 392
  * Revision 1.85  2004/04/29 07:35:27  nigelhorne
383 393
  * Change from realloc to cli_realloc - keep assignment
384 394
  *
... ...
@@ -619,9 +629,9 @@
619 619
  * Revision 1.6  2003/09/28 16:37:23  nigelhorne
620 620
  * Added -f flag use MaxThreads if --max-children not set
621 621
  */
622
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.85 2004/04/29 07:35:27 nigelhorne Exp $";
622
+static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.86 2004/05/06 11:25:20 nigelhorne Exp $";
623 623
 
624
-#define	CM_VERSION	"0.70u"
624
+#define	CM_VERSION	"0.70v"
625 625
 
626 626
 /*#define	CONFDIR	"/usr/local/etc"*/
627 627
 
... ...
@@ -755,7 +765,7 @@ static	sfsistat	clamfi_abort(SMFICTX *ctx);
755 755
 static	sfsistat	clamfi_close(SMFICTX *ctx);
756 756
 static	void		clamfi_cleanup(SMFICTX *ctx);
757 757
 static	void		clamfi_free(struct privdata *privdata);
758
-static	int		clamfi_send(const struct privdata *privdata, size_t len, const char *format, ...);
758
+static	int		clamfi_send(struct privdata *privdata, size_t len, const char *format, ...);
759 759
 static	char		*strrcpy(char *dest, const char *source);
760 760
 static	int		clamd_recv(int sock, char *buf, size_t len);
761 761
 static	off_t		updateSigFile(void);
... ...
@@ -857,8 +867,10 @@ static	const	char	*postmaster = "postmaster";
857 857
 static	const	char	*from = "MAILER-DAEMON";
858 858
 
859 859
 /*
860
- * Whitelist of source e-mail addresses that we do NOT scan
860
+ * NULL terminated whitelist of source e-mail addresses that we do NOT scan
861 861
  * TODO: read in from a file
862
+ * TODO: add white list of target e-mail addresses that we do NOT scan
863
+ * TODO: items in the list should be regular expressions
862 864
  */
863 865
 static	const	char	*ignoredEmailAddresses[] = {
864 866
 	/*"Mailer-Daemon@bandsman.co.uk",
... ...
@@ -1895,9 +1907,6 @@ clamfi_envfrom(SMFICTX *ctx, char **argv)
1895 1895
 
1896 1896
 	privdata->from = strdup(argv[0]);
1897 1897
 
1898
-	if(streamMaxLength > 0L)
1899
-		privdata->numBytes = (long)(strlen(argv[0]) + 6);
1900
-
1901 1898
 	if(hflag)
1902 1899
 		privdata->headers = header_list_new();
1903 1900
 
... ...
@@ -1932,9 +1941,6 @@ clamfi_envrcpt(SMFICTX *ctx, char **argv)
1932 1932
 	privdata->to[privdata->numTo] = strdup(argv[0]);
1933 1933
 	privdata->to[++privdata->numTo] = NULL;
1934 1934
 
1935
-	if(streamMaxLength > 0L)
1936
-		privdata->numBytes += (long)(strlen(argv[0]) + 4);
1937
-
1938 1935
 	return SMFIS_CONTINUE;
1939 1936
 }
1940 1937
 
... ...
@@ -1966,14 +1972,11 @@ clamfi_header(SMFICTX *ctx, char *headerf, char *headerv)
1966 1966
 			return cl_error;
1967 1967
 		}
1968 1968
 
1969
-	if(clamfi_send(privdata, 0, "%s: %s\n", headerf, headerv) < 0) {
1969
+	if(clamfi_send(privdata, 0, "%s: %s\n", headerf, headerv) <= 0) {
1970 1970
 		clamfi_cleanup(ctx);
1971 1971
 		return cl_error;
1972 1972
 	}
1973 1973
 
1974
-	if(streamMaxLength > 0L)
1975
-		privdata->numBytes += (long)(strlen(headerf) + strlen(headerv) + 3);
1976
-
1977 1974
 	if(hflag)
1978 1975
 		header_list_add(privdata->headers, headerf, headerv);
1979 1976
 	else if((strcasecmp(headerf, "Received") == 0) &&
... ...
@@ -2021,12 +2024,10 @@ clamfi_eoh(SMFICTX *ctx)
2021 2021
 			return cl_error;
2022 2022
 		}
2023 2023
 
2024
-	if(clamfi_send(privdata, 1, "\n") < 0) {
2024
+	if(clamfi_send(privdata, 1, "\n") != 1) {
2025 2025
 		clamfi_cleanup(ctx);
2026 2026
 		return cl_error;
2027 2027
 	}
2028
-	if(streamMaxLength > 0L)
2029
-		privdata->numBytes++;
2030 2028
 
2031 2029
 	/*
2032 2030
 	 * See if the e-mail is only going to members of the list
... ...
@@ -2076,6 +2077,7 @@ static sfsistat
2076 2076
 clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
2077 2077
 {
2078 2078
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
2079
+	int nbytes;
2079 2080
 
2080 2081
 	if(logVerbose)
2081 2082
 		syslog(LOG_DEBUG, "clamfi_envbody: %u bytes", len);
... ...
@@ -2083,8 +2085,8 @@ clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
2083 2083
 	cli_dbgmsg("clamfi_envbody: %u bytes\n", len);
2084 2084
 #endif
2085 2085
 
2086
+	nbytes = clamfi_send(privdata, len, (char *)bodyp);
2086 2087
 	if(streamMaxLength > 0L) {
2087
-		privdata->numBytes += (long)len;
2088 2088
 		if(privdata->numBytes > streamMaxLength) {
2089 2089
 			if(use_syslog) {
2090 2090
 				const char *sendmailId = smfi_getsymval(ctx, "i");
... ...
@@ -2093,11 +2095,13 @@ clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
2093 2093
 				syslog(LOG_NOTICE, "%s: Message more than StreamMaxLength (%ld) bytes - not scanned",
2094 2094
 					sendmailId, streamMaxLength);
2095 2095
 			}
2096
-			clamfi_cleanup(ctx);	/* not needed, but just to be safe */
2097
-			return SMFIS_ACCEPT;
2096
+			if(!nflag)
2097
+				smfi_addheader(ctx, "X-Virus-Status", "Not Scanned - StreamMaxLength exceeded");
2098
+
2099
+			return SMFIS_ACCEPT;	/* clamfi_close will be called */
2098 2100
 		}
2099 2101
 	}
2100
-	if(clamfi_send(privdata, len, (char *)bodyp) < 0) {
2102
+	if(nbytes < len) {
2101 2103
 		clamfi_cleanup(ctx);	/* not needed, but just to be safe */
2102 2104
 		return cl_error;
2103 2105
 	}
... ...
@@ -2206,9 +2210,6 @@ clamfi_eom(SMFICTX *ctx)
2206 2206
 		smfi_addheader(ctx, "X-Virus-Scanned", clamav_version);
2207 2207
 
2208 2208
 	if(strstr(mess, "ERROR") != NULL) {
2209
-		if(!nflag)
2210
-			smfi_addheader(ctx, "X-Virus-Status", "Not Scanned");
2211
-
2212 2209
 		if(strstr(mess, "Size exceeded") != NULL) {
2213 2210
 			/*
2214 2211
 			 * Clamd has stopped on StreamMaxLength before us
... ...
@@ -2217,8 +2218,12 @@ clamfi_eom(SMFICTX *ctx)
2217 2217
 				syslog(LOG_NOTICE, "%s: Message more than StreamMaxLength (%ld) bytes - not scanned",
2218 2218
 					sendmailId, streamMaxLength);
2219 2219
 			clamfi_cleanup(ctx);	/* not needed, but just to be safe */
2220
+			if(!nflag)
2221
+				smfi_addheader(ctx, "X-Virus-Status", "Not Scanned - StreamMaxLength exceeded");
2220 2222
 			return SMFIS_ACCEPT;
2221 2223
 		}
2224
+		if(!nflag)
2225
+			smfi_addheader(ctx, "X-Virus-Status", "Not Scanned");
2222 2226
 
2223 2227
 		cli_warnmsg("%s: %s\n", sendmailId, mess);
2224 2228
 		if(use_syslog)
... ...
@@ -2430,7 +2435,9 @@ clamfi_eom(SMFICTX *ctx)
2430 2430
 			if(use_syslog)
2431 2431
 				syslog(LOG_NOTICE, "Quarantined infected mail as %s", privdata->filename);
2432 2432
 			/*
2433
-			 * Cleanup filename here! Default procedure would delete quarantine file
2433
+			 * Cleanup filename here otherwise clamfi_free() will
2434
+			 * delete the file that we wish to keep because it
2435
+			 * is infected
2434 2436
 			 */
2435 2437
 			free(privdata->filename);
2436 2438
 			privdata->filename = NULL;
... ...
@@ -2504,17 +2511,11 @@ clamfi_abort(SMFICTX *ctx)
2504 2504
 static sfsistat
2505 2505
 clamfi_close(SMFICTX *ctx)
2506 2506
 {
2507
-#ifdef	CL_DEBUG
2508 2507
 	struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
2509 2508
 
2510 2509
 	cli_dbgmsg("clamfi_close\n");
2511
-	if(privdata != NULL) {
2512
-		if(use_syslog)
2513
-			syslog(LOG_DEBUG, "clamfi_close, privdata != NULL");
2514
-		else
2515
-			cli_warnmsg("clamfi_close, privdata != NULL");
2516
-	}
2517
-#endif
2510
+	if(privdata != NULL)
2511
+		clamfi_cleanup(ctx);
2518 2512
 
2519 2513
 	if(logVerbose)
2520 2514
 		syslog(LOG_DEBUG, "clamfi_close");
... ...
@@ -2546,8 +2547,13 @@ clamfi_free(struct privdata *privdata)
2546 2546
 		}
2547 2547
 
2548 2548
 		if(privdata->filename != NULL) {
2549
-			if(unlink(privdata->filename) < 0)
2549
+			if(unlink(privdata->filename) < 0) {
2550 2550
 				perror(privdata->filename);
2551
+				if(use_syslog)
2552
+					syslog(LOG_ERR,
2553
+						"Can't remove clean file %s",
2554
+						privdata->filename);
2555
+			}
2551 2556
 			free(privdata->filename);
2552 2557
 			privdata->filename = NULL;
2553 2558
 		}
... ...
@@ -2621,13 +2627,14 @@ clamfi_free(struct privdata *privdata)
2621 2621
 }
2622 2622
 
2623 2623
 /*
2624
- * Returns < 0 for failure
2624
+ * Returns < 0 for failure, otherwise the number of bytes sent
2625 2625
  */
2626 2626
 static int
2627
-clamfi_send(const struct privdata *privdata, size_t len, const char *format, ...)
2627
+clamfi_send(struct privdata *privdata, size_t len, const char *format, ...)
2628 2628
 {
2629 2629
 	char output[BUFSIZ];
2630 2630
 	const char *ptr;
2631
+	int ret = 0;
2631 2632
 
2632 2633
 	assert(format != NULL);
2633 2634
 
... ...
@@ -2687,10 +2694,17 @@ clamfi_send(const struct privdata *privdata, size_t len, const char *format, ...
2687 2687
 
2688 2688
 			return -1;
2689 2689
 		}
2690
+		ret += nbytes;
2690 2691
 		len -= nbytes;
2691 2692
 		ptr = &ptr[nbytes];
2693
+
2694
+		if(streamMaxLength > 0L) {
2695
+			privdata->numBytes += nbytes;
2696
+			if(privdata->numBytes >= streamMaxLength)
2697
+				break;
2698
+		}
2692 2699
 	}
2693
-	return 0;
2700
+	return ret;
2694 2701
 }
2695 2702
 
2696 2703
 /*
... ...
@@ -3057,7 +3071,7 @@ connect2clamd(struct privdata *privdata)
3057 3057
 		privdata->from);
3058 3058
 
3059 3059
 	for(to = privdata->to; *to; to++)
3060
-		if(clamfi_send(privdata, 0, "To: %s\n", *to) < 0)
3060
+		if(clamfi_send(privdata, 0, "To: %s\n", *to) <= 0)
3061 3061
 			return 0;
3062 3062
 
3063 3063
 	cli_dbgmsg("connect2clamd OK\n");