git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@931 77e5149b-7576-45b1-b177-96237e5ba77b
Nigel Horne authored on 2004/09/27 21:45:47... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Mon Sep 27 13:44:45 BST 2004 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamav-milter: SESSIONS: try to gracefully close when shutting down |
|
4 |
+ honour HAVE_IN_ADDR_T |
|
5 |
+ Added --broadcast option |
|
6 |
+ |
|
1 | 7 |
Mon Sep 27 04:00:14 CEST 2004 (tk) |
2 | 8 |
---------------------------------- |
3 | 9 |
* libclamav: ignore ndb signatures in cl_scanbuff() |
... | ... |
@@ -501,6 +501,9 @@ Changes |
501 | 501 |
Honour LogFacility |
502 | 502 |
When sanitising the quarantine's filename, don't sanitise |
503 | 503 |
the directory name as well |
504 |
+0.80b 27/9/04 Added quit() routine to tidy when shutting down |
|
505 |
+ honour HAVE_IN_ADDR_T |
|
506 |
+ Added --broadcast option |
|
504 | 507 |
|
505 | 508 |
INTERNATIONALISATION |
506 | 509 |
|
... | ... |
@@ -26,6 +26,9 @@ |
26 | 26 |
* |
27 | 27 |
* Change History: |
28 | 28 |
* $Log: clamav-milter.c,v $ |
29 |
+ * Revision 1.133 2004/09/27 12:43:23 nigelhorne |
|
30 |
+ * Added --broadcast |
|
31 |
+ * |
|
29 | 32 |
* Revision 1.132 2004/09/25 15:47:19 nigelhorne |
30 | 33 |
* Honour LogFacility |
31 | 34 |
* |
... | ... |
@@ -407,9 +410,9 @@ |
407 | 407 |
* Revision 1.6 2003/09/28 16:37:23 nigelhorne |
408 | 408 |
* Added -f flag use MaxThreads if --max-children not set |
409 | 409 |
*/ |
410 |
-static char const rcsid[] = "$Id: clamav-milter.c,v 1.132 2004/09/25 15:47:19 nigelhorne Exp $"; |
|
410 |
+static char const rcsid[] = "$Id: clamav-milter.c,v 1.133 2004/09/27 12:43:23 nigelhorne Exp $"; |
|
411 | 411 |
|
412 |
-#define CM_VERSION "0.80a" |
|
412 |
+#define CM_VERSION "0.80b" |
|
413 | 413 |
|
414 | 414 |
/*#define CONFDIR "/usr/local/etc"*/ |
415 | 415 |
|
... | ... |
@@ -493,6 +496,10 @@ int deny_severity = LOG_NOTICE; |
493 | 493 |
typedef unsigned short in_port_t; |
494 | 494 |
#endif |
495 | 495 |
|
496 |
+#ifndef HAVE_IN_ADDR_T |
|
497 |
+typedef unsigned int in_addr_t; |
|
498 |
+#endif |
|
499 |
+ |
|
496 | 500 |
/* |
497 | 501 |
* Do not define SESSION in a production environment - it has been known to put |
498 | 502 |
* clamd into a loop when clamav-milter is restarted and sending STREAM often |
... | ... |
@@ -622,6 +629,8 @@ static void clamdIsDown(void); |
622 | 622 |
static void *watchdog(void *a); |
623 | 623 |
#endif |
624 | 624 |
static int logg_facility(const char *name); |
625 |
+static void quit(void); |
|
626 |
+static void broadcast(const char *mess); |
|
625 | 627 |
|
626 | 628 |
static char clamav_version[128]; |
627 | 629 |
static int fflag = 0; /* force a scan, whatever */ |
... | ... |
@@ -632,6 +641,10 @@ static int bflag = 0; /* |
632 | 632 |
* sender. This probably isn't a good idea |
633 | 633 |
* since most reply addresses will be fake |
634 | 634 |
*/ |
635 |
+static int Bflag = 0; /* |
|
636 |
+ * Broadcast a message when a virus is found, |
|
637 |
+ * this allows remote network management |
|
638 |
+ */ |
|
635 | 639 |
static int pflag = 0; /* |
636 | 640 |
* Send a warning to the postmaster only, |
637 | 641 |
* this means user's won't be told when someone |
... | ... |
@@ -739,6 +752,7 @@ static pthread_cond_t watchdog_cond = PTHREAD_COND_INITIALIZER; |
739 | 739 |
|
740 | 740 |
static const char *postmaster = "postmaster"; |
741 | 741 |
static const char *from = "MAILER-DAEMON"; |
742 |
+static int quitting; |
|
742 | 743 |
|
743 | 744 |
/* |
744 | 745 |
* NULL terminated whitelist of target ("to") addresses that we do NOT scan |
... | ... |
@@ -760,6 +774,7 @@ help(void) |
760 | 760 |
|
761 | 761 |
puts(_("\t--advisory\t\t-A\tFlag viruses rather than deleting them.")); |
762 | 762 |
puts(_("\t--bounce\t\t-b\tSend a failure message to the sender.")); |
763 |
+ puts(_("\t--broadcast\t\t-B\tBroadcast to a network manager when a virus is found.")); |
|
763 | 764 |
puts(_("\t--config-file=FILE\t-c FILE\tRead configuration from FILE.")); |
764 | 765 |
puts(_("\t--debug\t\t\t-D\tPrint debug messages.")); |
765 | 766 |
puts(_("\t--dont-log-clean\t-C\tDon't add an entry to syslog that a mail is clean.")); |
... | ... |
@@ -845,9 +860,9 @@ main(int argc, char **argv) |
845 | 845 |
for(;;) { |
846 | 846 |
int opt_index = 0; |
847 | 847 |
#ifdef CL_DEBUG |
848 |
- const char *args = "a:Abc:CDfF:lm:nNop:PqQ:dhHs:St:T:U:Vx:"; |
|
848 |
+ const char *args = "a:AbBc:CDfF:lm:nNop:PqQ:dhHs:St:T:U:Vx:"; |
|
849 | 849 |
#else |
850 |
- const char *args = "a:Abc:CDfF:lm:nNop:PqQ:dhHs:St:T:U:V"; |
|
850 |
+ const char *args = "a:AbBc:CDfF:lm:nNop:PqQ:dhHs:St:T:U:V"; |
|
851 | 851 |
#endif |
852 | 852 |
|
853 | 853 |
static struct option long_options[] = { |
... | ... |
@@ -861,6 +876,9 @@ main(int argc, char **argv) |
861 | 861 |
"bounce", 0, NULL, 'b' |
862 | 862 |
}, |
863 | 863 |
{ |
864 |
+ "broadcast", 0, NULL, 'B' |
|
865 |
+ }, |
|
866 |
+ { |
|
864 | 867 |
"config-file", 1, NULL, 'c' |
865 | 868 |
}, |
866 | 869 |
{ |
... | ... |
@@ -963,6 +981,9 @@ main(int argc, char **argv) |
963 | 963 |
case 'b': /* bounce worms/viruses */ |
964 | 964 |
bflag++; |
965 | 965 |
break; |
966 |
+ case 'B': /* broadcast */ |
|
967 |
+ Bflag++; |
|
968 |
+ break; |
|
966 | 969 |
case 'c': /* where is clamd.conf? */ |
967 | 970 |
cfgfile = optarg; |
968 | 971 |
break; |
... | ... |
@@ -1372,6 +1393,8 @@ main(int argc, char **argv) |
1372 | 1372 |
#endif |
1373 | 1373 |
} |
1374 | 1374 |
|
1375 |
+ atexit(quit); |
|
1376 |
+ |
|
1375 | 1377 |
#ifdef SESSION |
1376 | 1378 |
pthread_create(&tid, NULL, watchdog, NULL); |
1377 | 1379 |
#endif |
... | ... |
@@ -1570,6 +1593,7 @@ pingServer(int serverNumber) |
1570 | 1570 |
* Also version command is verbose: says "clamd / ClamAV version" |
1571 | 1571 |
* instead of "clamAV version" |
1572 | 1572 |
*/ |
1573 |
+ cli_dbgmsg("pingServer%d: sending VERSION\n", serverNumber); |
|
1573 | 1574 |
if(send(sock, "VERSION\n", 8, 0) < 8) { |
1574 | 1575 |
perror("send"); |
1575 | 1576 |
close(sock); |
... | ... |
@@ -1799,6 +1823,9 @@ clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) |
1799 | 1799 |
#endif |
1800 | 1800 |
const char *remoteIP; |
1801 | 1801 |
|
1802 |
+ if(quitting) |
|
1803 |
+ return cl_error; |
|
1804 |
+ |
|
1802 | 1805 |
if(ctx == NULL) { |
1803 | 1806 |
if(use_syslog) |
1804 | 1807 |
syslog(LOG_ERR, _("clamfi_connect: ctx is null")); |
... | ... |
@@ -2680,6 +2707,8 @@ clamfi_eom(SMFICTX *ctx) |
2680 | 2680 |
|
2681 | 2681 |
snprintf(reject, sizeof(reject) - 1, _("%s detected by ClamAV - http://www.clamav.net"), virusname); |
2682 | 2682 |
smfi_setreply(ctx, (char *)privdata->rejectCode, "5.7.1", reject); |
2683 |
+ if(Bflag) |
|
2684 |
+ broadcast(mess); |
|
2683 | 2685 |
} |
2684 | 2686 |
clamfi_cleanup(ctx); |
2685 | 2687 |
|
... | ... |
@@ -3759,7 +3788,7 @@ watchdog(void *a) |
3759 | 3759 |
|
3760 | 3760 |
assert(cmdSockets != NULL); |
3761 | 3761 |
|
3762 |
- for(;;) { |
|
3762 |
+ while(!quitting) { |
|
3763 | 3763 |
int i; |
3764 | 3764 |
struct timespec ts; |
3765 | 3765 |
struct timeval tp; |
... | ... |
@@ -3936,3 +3965,80 @@ logg_facility(const char *name) |
3936 | 3936 |
|
3937 | 3937 |
return -1; |
3938 | 3938 |
} |
3939 |
+ |
|
3940 |
+static void |
|
3941 |
+quit(void) |
|
3942 |
+{ |
|
3943 |
+#ifdef SESSION |
|
3944 |
+ int i; |
|
3945 |
+ |
|
3946 |
+ quitting++; |
|
3947 |
+ |
|
3948 |
+ if(use_syslog) |
|
3949 |
+ syslog(LOG_INFO, _("Stopping: %s"), clamav_version); |
|
3950 |
+ |
|
3951 |
+ pthread_mutex_lock(&sstatus_mutex); |
|
3952 |
+ for(i = 0; i < max_children; i++) { |
|
3953 |
+ const int sock = cmdSockets[i]; |
|
3954 |
+ |
|
3955 |
+ /* |
|
3956 |
+ * Check all free sessions are still usable |
|
3957 |
+ * This could take some time with many free |
|
3958 |
+ * sessions to slow remote servers, so only do this |
|
3959 |
+ * when the system is quiet (not 100% accurate when |
|
3960 |
+ * determining this since n_children isn't locked but |
|
3961 |
+ * that doesn't really matter) |
|
3962 |
+ */ |
|
3963 |
+ cli_dbgmsg("quit: close server %d\n", i); |
|
3964 |
+ if(cmdSocketsStatus[i] == CMDSOCKET_FREE) { |
|
3965 |
+ send(sock, "END\n", 4, 0); |
|
3966 |
+ shutdown(sock, SHUT_WR); |
|
3967 |
+ cmdSocketsStatus[i] = CMDSOCKET_DOWN; |
|
3968 |
+ pthread_mutex_unlock(&sstatus_mutex); |
|
3969 |
+ close(sock); |
|
3970 |
+ pthread_mutex_lock(&sstatus_mutex); |
|
3971 |
+ } |
|
3972 |
+ } |
|
3973 |
+ pthread_mutex_unlock(&sstatus_mutex); |
|
3974 |
+#else |
|
3975 |
+ quitting++; |
|
3976 |
+ |
|
3977 |
+ if(use_syslog) |
|
3978 |
+ syslog(LOG_INFO, _("Stopping: %s"), clamav_version); |
|
3979 |
+#endif |
|
3980 |
+} |
|
3981 |
+ |
|
3982 |
+static void |
|
3983 |
+broadcast(const char *mess) |
|
3984 |
+{ |
|
3985 |
+ int on; |
|
3986 |
+ struct sockaddr_in s; |
|
3987 |
+ const sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
|
3988 |
+ |
|
3989 |
+ if(sock < 0) { |
|
3990 |
+ perror("socket"); |
|
3991 |
+ return; |
|
3992 |
+ } |
|
3993 |
+ |
|
3994 |
+ /* |
|
3995 |
+ * SO_BROADCAST doesn't sent to all NICs on Linux, it only broadcasts |
|
3996 |
+ * on eth0. You can use SO_BINDTODEVICE to get around that, but you |
|
3997 |
+ * need to have uid == 0 for that |
|
3998 |
+ */ |
|
3999 |
+ on = 1; |
|
4000 |
+ if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (int *)&on, sizeof(on)) < 0) { |
|
4001 |
+ perror("setsockopt"); |
|
4002 |
+ close(sock); |
|
4003 |
+ return; |
|
4004 |
+ } |
|
4005 |
+ |
|
4006 |
+ memset(&s, '\0', sizeof(struct sockaddr_in)); |
|
4007 |
+ s.sin_family = AF_INET; |
|
4008 |
+ s.sin_port = (in_port_t)htons(tcpSocket); |
|
4009 |
+ s.sin_addr.s_addr = htonl(INADDR_BROADCAST); |
|
4010 |
+ |
|
4011 |
+ if(sendto(sock, mess, strlen(mess), 0, (struct sockaddr *)&s, sizeof(struct sockaddr_in)) < 0) |
|
4012 |
+ perror("sendto"); |
|
4013 |
+ |
|
4014 |
+ close(sock); |
|
4015 |
+} |
... | ... |
@@ -63,6 +63,12 @@ Send a failure message to the sender, and to the postmaster. |
63 | 63 |
fake their source address, so this option is not recommended ]. |
64 | 64 |
See also \-\-noreject. |
65 | 65 |
.TP |
66 |
+\fB\-B, \-\-broadcast\fR |
|
67 |
+When a virus is intercepted, broadcast a UDP message to the TCPSocket port set |
|
68 |
+in \fBclamd.conf\fR. |
|
69 |
+A future network management program (yet to be written) will intercept these |
|
70 |
+broadcasts to raise a warning on the operator's desk. |
|
71 |
+.TP |
|
66 | 72 |
\fB-C, \-\-dont-log-clean\fR |
67 | 73 |
Messages without viruses are usually logged if SysLog is set in |
68 | 74 |
\fBclamd.conf\fR since it gives a feel-good factor. |
... | ... |
@@ -185,7 +191,7 @@ There is no support for IPv6. |
185 | 185 |
clamav\-milter \-ol local:/var/run/clamav/clmilter.sock |
186 | 186 |
.SH "AUTHOR" |
187 | 187 |
.LP |
188 |
-Nigel Horne <njh@clamav.net> |
|
188 |
+Nigel Horne <njh@bandsman.co.uk> |
|
189 | 189 |
.SH "SEE ALSO" |
190 | 190 |
.LP |
191 | 191 |
clamd(8), clamscan(1), freshclam(1), sigtool(1), clamd.conf(5), hosts_access(5) |