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... | ... |
@@ -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 |
|