Browse code

Various changes

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

Nigel Horne authored on 2004/04/23 01:50:17
Showing 3 changed files
... ...
@@ -1,3 +1,17 @@
1
+Thu Apr 22 17:48:49 BST 2004 (njh)
2
+----------------------------------
3
+ * clamav-milter: No need to parse the received line if --headers is given
4
+		If -outgoing is given put generated emails in the deferred
5
+			queue to avoid the milter being called twice at the
6
+			same time (one on the incoming one on the outgoing)
7
+		header_list_print, ensure From lines are escaped, may not be
8
+			needed but it is better to be on the safe side
9
+		When loadbalancing, fail to start only if no servers can be
10
+			reached (used to fail if any one server could not be
11
+			reached)
12
+		Not all servers were load balanced
13
+ * docs/man:	Clarified load balancing specification
14
+
1 15
 Wed Apr 21 16:28:49 BST 2004 (njh)
2 16
 ----------------------------------
3 17
  * clamav-milter: If /dev/console fails to open, open /dev/null instead on fds 1
... ...
@@ -120,6 +120,10 @@ in a directory that can be written by everyone. For example ensure that /var/run
120 120
 is owned and writable only by root and add entries for 'User' and
121 121
 'FixStaleSocket' in clamav.conf.
122 122
 
123
+When using UNIX domain sockets via the LocalSocket option of clamav.conf,
124
+we recommend that you use the --quarantine-dir option since that may improve
125
+performance.
126
+
123 127
 CHANGE HISTORY
124 128
 
125 129
 Changes
... ...
@@ -241,7 +245,7 @@ Changes
241 241
 		mail logs. Based on an idea by Jim Allen,
242 242
 		<Jim.Allen@Heartsine.co.uk>
243 243
 0.66l	7/2/04	Updated URL reference
244
- 		Added new config.h mechanism
244
+		Added new config.h mechanism
245 245
 0.66m	9/2/04	Added Hflag from "Leonid Zeitlin" <lz@europe.com>
246 246
 0.66n	13/2/04	Added TCPwrappers support
247 247
 		Removed duplication in version string
... ...
@@ -340,6 +344,16 @@ Changes
340 340
 		TCP_WRAPPERS code now uses inet_ntop()
341 341
 		Simplify virus string
342 342
 		Sort out tabs in the hard coded e-mail message
343
+0.70q	22/4/04	No need to parse the received line if --headers is given
344
+		If -outgoing is given put generated emails in the deferred
345
+			queue to avoid the milter being called twice at the
346
+			same time (one on the incoming one on the outgoing)
347
+		header_list_print, ensure From lines are escaped, may not be
348
+			needed but it is better to be on the safe side
349
+		When loadbalancing, fail to start only if no servers can be
350
+			reached (used to fail if any one server could not be
351
+			reached)
352
+		Not all servers were load balanced
343 353
 
344 354
 BUG REPORTS
345 355
 
... ...
@@ -341,9 +341,25 @@
341 341
  *			TCP_WRAPPERS code now uses inet_ntop()
342 342
  *			Simplify virus string
343 343
  *			Sort out tabs in the hard coded e-mail message
344
+ *	0.70q	22/4/04	No need to parse the received line if --headers is
345
+ *				given
346
+ *			If -outgoing is given put generated emails in the
347
+ *				deferred queue to avoid the milter being called
348
+ *			twice at the same time (one on the incoming one on the
349
+ *				outgoing)
350
+ *			header_list_print, ensure From lines are escaped, may
351
+ * 				not be needed but it is better to be on the
352
+ *				safe side
353
+ *			When loadbalancing, fail to start only if no servers
354
+ *				can be reached (used to fail if any one server
355
+ *				could not be reached)
356
+ *			Not all servers were load balanced
344 357
  *
345 358
  * Change History:
346 359
  * $Log: clamav-milter.c,v $
360
+ * Revision 1.81  2004/04/22 16:47:04  nigelhorne
361
+ * Various changes
362
+ *
347 363
  * Revision 1.80  2004/04/21 15:27:02  nigelhorne
348 364
  * Various changes
349 365
  *
... ...
@@ -569,9 +585,9 @@
569 569
  * Revision 1.6  2003/09/28 16:37:23  nigelhorne
570 570
  * Added -f flag use MaxThreads if --max-children not set
571 571
  */
572
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.80 2004/04/21 15:27:02 nigelhorne Exp $";
572
+static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.81 2004/04/22 16:47:04 nigelhorne Exp $";
573 573
 
574
-#define	CM_VERSION	"0.70p"
574
+#define	CM_VERSION	"0.70q"
575 575
 
576 576
 /*#define	CONFDIR	"/usr/local/etc"*/
577 577
 
... ...
@@ -1215,7 +1231,7 @@ main(int argc, char **argv)
1215 1215
 		serverIPs = (long *)cli_malloc(sizeof(long));
1216 1216
 		serverIPs[0] = inet_addr("127.0.0.1");
1217 1217
 	} else if((cpt = cfgopt(copt, "TCPSocket")) != NULL) {
1218
-		int i;
1218
+		int i, activeServers;
1219 1219
 
1220 1220
 		/*
1221 1221
 		 * TCPSocket is in fact a port number not a full socket
... ...
@@ -1243,6 +1259,7 @@ main(int argc, char **argv)
1243 1243
 		cli_dbgmsg("numServers: %d\n", numServers);
1244 1244
 
1245 1245
 		serverIPs = (long *)cli_malloc(numServers * sizeof(long));
1246
+		activeServers = 0;
1246 1247
 
1247 1248
 		for(i = 0; i < numServers; i++) {
1248 1249
 			char *hostname;
... ...
@@ -1264,15 +1281,20 @@ main(int argc, char **argv)
1264 1264
 				memcpy((char *)&serverIPs[i], h->h_addr, sizeof(serverIPs[i]));
1265 1265
 			}
1266 1266
 
1267
-			if(!pingServer(i)) {
1268
-				fprintf(stderr, "Can't talk to clamd server %s on port %d\n",
1267
+			if(pingServer(i))
1268
+				activeServers++;
1269
+			else {
1270
+				cli_warnmsg("Warning Can't talk to clamd server %s on port %d\n",
1269 1271
 					hostname, tcpSocket);
1270
-				fprintf(stderr, "Check your entry for TCPSocket in %s\n",
1271
-					cfgfile);
1272
-				return EX_CONFIG;
1273 1272
 			}
1274 1273
 			free(hostname);
1275 1274
 		}
1275
+		if(activeServers == 0) {
1276
+			cli_errmsg("Can't find any clamd servers\n");
1277
+			cli_errmsg("Check your entry for TCPSocket in %s\n",
1278
+				cfgfile);
1279
+			return EX_CONFIG;
1280
+		}
1276 1281
 	} else {
1277 1282
 		fprintf(stderr, "%s: You must select server type (local/TCP) in %s\n",
1278 1283
 			argv[0], cfgfile);
... ...
@@ -1375,7 +1397,7 @@ main(int argc, char **argv)
1375 1375
  * Verify that the server is where we think it is
1376 1376
  * Returns true or false
1377 1377
  *
1378
- * serverNumber counts from 0
1378
+ * serverNumber counts from 0, but is only used for TCPSocket
1379 1379
  */
1380 1380
 static int
1381 1381
 pingServer(int serverNumber)
... ...
@@ -1474,12 +1496,14 @@ pingServer(int serverNumber)
1474 1474
 }
1475 1475
 
1476 1476
 /*
1477
- * Find the best server to connect to. No intelligence to this, if one
1478
- * of the servers goes down it'll be silently ignored, which is probably
1479
- * ok. It is best to weight the order of the servers from most wanted to
1480
- * least wanted
1477
+ * Find the best server to connect to. No intelligence to this.
1478
+ * It is best to weight the order of the servers from most wanted to least
1479
+ * wanted
1481 1480
  *
1482 1481
  * Return value is from 0 - index into serverIPs
1482
+ *
1483
+ * If the load balancing fails return the first server in the list, not
1484
+ * an error, to be on the safe side
1483 1485
  */
1484 1486
 static int
1485 1487
 findServer(void)
... ...
@@ -1522,9 +1546,12 @@ findServer(void)
1522 1522
 
1523 1523
 		if((connect(sock, (struct sockaddr *)server, sizeof(struct sockaddr)) < 0) ||
1524 1524
 		   (send(sock, "PING\n", 5, 0) < 5)) {
1525
-			cli_errmsg("findServer: Check server %d - it may be down\n", i);
1525
+			const char *hostname = cli_strtok(serverHostNames, i, ":");
1526
+			cli_warnmsg("findServer: Check clamd server %s - it may be down\n", hostname);
1526 1527
 			if(use_syslog)
1527
-				syslog(LOG_WARNING, "findServer: Check server %d - it may be down", i);
1528
+				syslog(LOG_WARNING,
1529
+					"findServer: Check clamd server %s - it may be down",
1530
+					hostname);
1528 1531
 			socks[i] = -1;
1529 1532
 			close(sock);
1530 1533
 			continue;
... ...
@@ -1542,7 +1569,7 @@ findServer(void)
1542 1542
 	tv.tv_sec = readTimeout;
1543 1543
 	tv.tv_usec = 0;
1544 1544
 
1545
-	retval = select(maxsock, &rfds, NULL, NULL, &tv);
1545
+	retval = select(maxsock + 1, &rfds, NULL, NULL, &tv);
1546 1546
 	if(retval < 0)
1547 1547
 		perror("select");
1548 1548
 
... ...
@@ -1870,10 +1897,9 @@ clamfi_header(SMFICTX *ctx, char *headerf, char *headerv)
1870 1870
 
1871 1871
 	if(hflag)
1872 1872
 		header_list_add(privdata->headers, headerf, headerv);
1873
-
1874
-	if((strcasecmp(headerf, "Received") == 0) &&
1873
+	else if((strcasecmp(headerf, "Received") == 0) &&
1875 1874
 	   (strncasecmp(headerv, "from ", 5) == 0)) {
1876
-	   	if(privdata->received)
1875
+		if(privdata->received)
1877 1876
 			free(privdata->received);
1878 1877
 		privdata->received = strdup(headerv);
1879 1878
 	}
... ...
@@ -2140,10 +2166,16 @@ clamfi_eom(SMFICTX *ctx)
2140 2140
 		}
2141 2141
 	} else {
2142 2142
 		char reject[1024];
2143
-		char **to;
2143
+		char **to, *virusname;
2144 2144
 
2145 2145
 		*ptr = '\0';	/* Remove the "FOUND" word */
2146 2146
 
2147
+		/* skip over 'stream/filename: ' at the start */
2148
+		if((virusname = strchr(mess, ':')) != NULL)
2149
+			virusname = &virusname[2];
2150
+		else
2151
+			virusname = mess;
2152
+
2147 2153
 		if(!nflag)
2148 2154
 			smfi_addheader(ctx, "X-Virus-Status", "Infected");
2149 2155
 
... ...
@@ -2185,7 +2217,7 @@ clamfi_eom(SMFICTX *ctx)
2185 2185
 			(void)strcpy(ptr, "\n");
2186 2186
 
2187 2187
 			/* Include the sendmail queue ID in the log */
2188
-			syslog(LOG_NOTICE, "%s: %s %s", sendmailId, mess, err);
2188
+			syslog(LOG_NOTICE, "%s: %s%s", sendmailId, mess, err);
2189 2189
 #ifdef	CL_DEBUG
2190 2190
 			cli_dbgmsg("%s\n", err);
2191 2191
 #endif
... ...
@@ -2196,7 +2228,16 @@ clamfi_eom(SMFICTX *ctx)
2196 2196
 			char cmd[128];
2197 2197
 			FILE *sendmail;
2198 2198
 
2199
-			snprintf(cmd, sizeof(cmd), "%s -t", SENDMAIL_BIN);
2199
+			/*
2200
+			 * If the oflag is given this sendmail command
2201
+			 * will cause the mail being generated here to be
2202
+			 * scanned. So if oflag is given we just put the
2203
+			 * item in the queue so there's no scanning of two
2204
+			 * messages at once. It'll still be scanned, but
2205
+			 * not at the same time as the incoming message
2206
+			 */
2207
+			snprintf(cmd, sizeof(cmd) - 1,
2208
+				(oflag) ? "%s -t -odq" : "%s -t", SENDMAIL_BIN);
2200 2209
 
2201 2210
 			sendmail = popen(cmd, "w");
2202 2211
 
... ...
@@ -2254,13 +2295,18 @@ clamfi_eom(SMFICTX *ctx)
2254 2254
 
2255 2255
 					for(to = privdata->to; *to; to++)
2256 2256
 						fprintf(sendmail, "\t%s\n", *to);
2257
-					/* skip over 'stream: ' at the start */
2258
-					fprintf(sendmail, "contained %sand has not been delivered.\n", &mess[8]);
2257
+					fprintf(sendmail, "contained %sand has not been delivered.\n", virusname);
2259 2258
 
2260 2259
 					if(privdata->filename != NULL)
2261 2260
 						fprintf(sendmail, "\nThe message in question has been quarantined as %s\n", privdata->filename);
2262 2261
 
2263
-					if(privdata->received)
2262
+					if(hflag) {
2263
+						fprintf(sendmail, "\nThe message was received by %s from %s via %s\n\n",
2264
+							smfi_getsymval(ctx, "j"), from,
2265
+							smfi_getsymval(ctx, "_"));
2266
+						fputs("For your information, the original message headers were:\n\n", sendmail);
2267
+						header_list_print(privdata->headers, sendmail);
2268
+					} else if(privdata->received)
2264 2269
 						/*
2265 2270
 						 * TODO: parse this to find
2266 2271
 						 * real infected machine.
... ...
@@ -2274,13 +2320,6 @@ clamfi_eom(SMFICTX *ctx)
2274 2274
 						fprintf(sendmail, "\nThe infected machine is likely to be here:\n%s\t\n",
2275 2275
 							privdata->received);
2276 2276
 
2277
-					if(hflag) {
2278
-						fprintf(sendmail, "\nThe message was received by %s from %s via %s\n\n",
2279
-							smfi_getsymval(ctx, "j"), from,
2280
-							smfi_getsymval(ctx, "_"));
2281
-						fputs("For your information, the original message headers were:\n\n", sendmail);
2282
-						header_list_print(privdata->headers, sendmail);
2283
-					}
2284 2277
 				}
2285 2278
 
2286 2279
 				pclose(sendmail);
... ...
@@ -2322,8 +2361,7 @@ clamfi_eom(SMFICTX *ctx)
2322 2322
 		else
2323 2323
 			rc = SMFIS_DISCARD;
2324 2324
 
2325
-		/* skip over 'stream: ' at the start */
2326
-		snprintf(reject, sizeof(reject) - 1, "%sdetected by ClamAV - http://www.clamav.net", &mess[8]);
2325
+		snprintf(reject, sizeof(reject) - 1, "%sdetected by ClamAV - http://www.clamav.net", virusname);
2327 2326
 		smfi_setreply(ctx, "550", "5.7.1", reject);
2328 2327
 	}
2329 2328
 	clamfi_cleanup(ctx);
... ...
@@ -2449,7 +2487,7 @@ clamfi_free(struct privdata *privdata)
2449 2449
 		if(debug_level >= 9)
2450 2450
 			cli_dbgmsg("Free privdata\n");
2451 2451
 #endif
2452
-	   	if(privdata->received)
2452
+		if(privdata->received)
2453 2453
 			free(privdata->received);
2454 2454
 		free(privdata);
2455 2455
 	}
... ...
@@ -2694,8 +2732,11 @@ header_list_print(header_list_t list, FILE *fp)
2694 2694
 {
2695 2695
 	const struct header_node_t *iter;
2696 2696
 
2697
-	for(iter = list->first; iter; iter = iter->next)
2697
+	for(iter = list->first; iter; iter = iter->next) {
2698
+		if(strncmp(iter->header, "From", 4) == 0)
2699
+			putc('>', fp);
2698 2700
 		fprintf(fp, "%s\n", iter->header);
2701
+	}
2699 2702
 }
2700 2703
 
2701 2704
 /*
... ...
@@ -2742,7 +2783,7 @@ connect2clamd(struct privdata *privdata)
2742 2742
 		privdata->filename = (char *)cli_malloc(strlen(quarantine_dir) + 19);
2743 2743
 
2744 2744
 		sprintf(privdata->filename, "%s/%02d%02d%02d", quarantine_dir,
2745
-			YY, MM, DD); 
2745
+			YY, MM, DD);
2746 2746
 
2747 2747
 		(void)mkdir(privdata->filename, 0700);
2748 2748