1. BUILD INSTRUCTIONS A makefile was supplied with this which should have built the program. If it fails please let us know, and here are some hints for building on different platforms. You will need to set --enable-milter when running configure for the automatic build to work. Tested OK on Linux/x86 with gcc3.2. cc -O3 -pedantic -Wuninitialized -Wall -pipe -mcpu=pentium -march=pentium -fomit-frame-pointer -ffast-math -finline-functions -funroll-loops clamav-milter.c -pthread -lmilter ../libclamav/.libs/libclamav.a ../clamd/cfgfile.o ../clamd/others.o Compiles OK on Linux/x86 with tcc 0.9.16, but fails to link errors with 'atexit' tcc -g -b -lmilter -lpthread clamav-milter.c... Fails to compile on Linux/x86 with icc6.0 (complains about stdio.h...) icc -O3 -tpp7 -xiMKW -ipo -parallel -i_dynamic -w2 clamav-milter.c... Fails to build on Linux/x86 with icc7.1 with -ipo (fails on libclamav.a - keeps saying run ranlib). Otherwise it builds and runs OK. icc -O2 -tpp7 -xiMKW -parallel -i_dynamic -w2 -march=pentium4 -mcpu=pentium4 clamav-milter.c... Tested with Electric Fence 2.2.2, and the bounds checking C compiler from http://web.inter.nl.net/hcc/Haj.Ten.Brugge/ Compiles OK on Linux/ppc (YDL2.3) with gcc2.95.4. Needs -lsmutil to link. cc -O3 -pedantic -Wuninitialized -Wall -pipe -fomit-frame-pointer -ffast-math -finline-functions -funroll-loop -pthread -lmilter ../libclamav/.libs/libclamav.a ../clamd/cfgfile.o ../clamd/others.o -lsmutil I haven't tested it further on this platform yet. YDL3.0 should compile out of the box Linux/sparc (Gentoo 2004.2) comes with a sendmail that doesn't support MILTER, so *before* running "configure --enable-milter", download from http://www.sendmail.org/ftp, then: cd .../sendmail-source-directory sh Build make install cd libmilter make install Sendmail on MacOS/X (10.1) is provided without a development package so this can't be run "out of the box" Solaris 8 doesn't have milter support so clamav-milter won't work unless you rebuild sendmail from source. FreeBSD4.7 use /usr/local/bin/gcc30. GCC3.0 is an optional extra on FreeBSD. It comes with getopt.h which is handy. To link you need -lgnugetopt gcc30 -O3 -DCONFDIR=\"/usr/local/etc\" -I. -I.. -I../clamd -I../libclamav -pedantic -Wuninitialized -Wall -pipe -mcpu=pentium -march=pentium -fomit-frame-pointer -ffast-math -finline-functions -funroll-loops clamav-milter.c -pthread -lmilter ../libclamav/.libs/libclamav.a ../clamd/cfgfile.o ../clamd/others.o -lgnugetopt FreeBSD4.8: compiles out of the box with either gcc2.95 or gcc3 NetBSD2.0: compiles out of the box OpenBSD3.4: the supplied sendmail does not come with Milter support. Do this *before* running configure (thanks for Per-Olov Sjöhol for these instructions). echo WANT_LIBMILTER=1 > /etc/mk.conf cd /usr/src/gnu/usr.sbin/sendmail make depend make make install kill -HUP `sed q /var/run/sendmail.pid` Then do this to make the milter headers available to clamav... (the libmilter.a file is already in the right place after the sendmail recompiles above) cd /usr/include ln -s ../src/gnu/usr.sbin/sendmail/include/libmilter libmilter Solaris 9 and FreeBSD5 have milter support in the supplied sendmail, but doesn't include libmilter so you can't develop milter applications on it. Go to sendmail.org, download the latest sendmail, cd to libmilter and "make install" there. Needs -lresolv on Solaris 2. INSTALLATION Install into /usr/local/sbin/clamav-milter. Ensure that your sendmail supports milters by running /usr/lib/sendmail -d0 < /dev/null | fgrep MILTER or /usr/sbin/sendmail -d0 < /dev/null | fgrep MILTER You should see something like: MATCHGECOS MILTER MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETINET6 It doesn't matter exactly what you see, as long as the word MILTER is printed. If you see no output you MUST upgrade your sendmail. See http://www.nmt.edu/~wcolburn/sendmail-8.12.5/libmilter/docs/sample.html 2.1 LINUX (RedHat, Fedora, YellowDog etc) Installations for RedHat Linux and it's derivatives such as YellowDog: Ensure that you have the sendmail-devel RPM installed Add to /etc/mail/sendmail.mc before the MAILER statement: INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl define(`confINPUT_MAIL_FILTERS', `clamav') Note that the INPUT_MAIL_FILTER line must come before the confINPUT_MAIL_FILTERS line. Don't worry that the file /var/run/clamav/clmilter.sock doesn't exist, clamav-milter will create it for you. However you will need to create the directory /var/run/clamav (usually owned by user clamav, mode 700). Check entry in /usr/local/etc/clamd.conf of the form: LocalSocket /var/run/clamav/clamd.sock If you already have a filter (such as spamassassin-milter from http://savannah.nongnu.org/projects/spamass-milt) add it thus: INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m') define(`confINPUT_MAIL_FILTERS', `spamassassin,clamav')dnl mkdir /var/run/clamav chown clamav /var/run/clamav (if you use User clamav in clamd.conf) chmod 700 /var/run/clamav Where /var/run/spamass.sock is the location of the spamass-milt socket file (on some systems it is in /var/run/sendmail/spamass.sock). 2.2 LINUX (Debian) Installations for Debian Linux: As above for RedHat, except that you need the libmilter-dev package: apt-get install libmilter-dev To use TCPwrappers you need to: apt-get install libwrap0-dev 2.3 FreeBSD Installations for FreeBSD5 (may be true for other BSDs) Add to /etc/mail/freebsd.mc: INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl define(`confINPUT_MAIL_FILTERS', `clamav') Check entry in /usr/local/etc/clamd.conf of the form: LocalSocket /var/run/clamav/clamd.sock If you already have a filter (such as spamassassin-milter from http://savannah.nongnu.org/projects/spamass-milt) add it thus: INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m') define(`confINPUT_MAIL_FILTERS', `spamassassin,clamav')dnl mkdir /var/run/clamav chown clamav /var/run/clamav (if you use User clamav in clamd.conf) chmod 700 /var/run/clamav Where /var/run/spamass.sock is the location of the spamass-milt socket file (on some systems it is in /var/run/sendmail/spamass.sock). FreeBSD5.3 sendmail comes without libmilter support. You can upgrade by cd /usr/ports/mail/sendmail make install This may overwrite your existing sendmail configuration, so ensure that you back up first. You should have received a script to install into /etc/rc.d as /etc/rc.d/clamav with this software. Add to /etc/rc.conf: clamd_enable="YES" clamav_milter_enable="YES" clamav_milter_flags="--max-children=2 --dont-wait --timeout=0 -P local:/var/run/clamav/clamav.sock --pidfile=/var/run/clamav/clamav-milter.pid --quarantine-dir=/var/run/clamav/quarantine" 2.4 Solaris 10 Solaris 10 should install out of the box. Edit /etc/mail/cf/cf/main.mc adding the line: INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clmilter.sock, F=, T=S:4m;R:4m')dnl Then: cp /etc/mail/cf/cf/main.cf /etc/mail/main.cf /usr/local/sbin/clamav-milter local:/var/run/clamav/clmilter.sock mkdir /var/run/clamav chown clamav /var/run/clamav (if you use User clamav in clamd.conf) chmod 700 /var/run/clamav You should have received a script to install into /etc/init.d as /etc/init.d/clamav-milter. Then: chmod 755 /etc/init.d/clamav-milter cd /etc ln init.d/clamav-milter rc2.d/S90clamav-milter ln init.d/clamav-milter rc0.d/K90clamav-milter /etc/init.d/clamav-milter start /etc/init.d/sendmail restart 2.6 General Installation Issues You may find INPUT_MAIL_FILTERS is not needed on your machine, however it is recommended by the Sendmail documentation and I recommend going along with that. If you see an unsafe socket error from sendmail, it means that the permissions of the /var/run/clamav directory are too open. Check you have correctly run chown and chmod, it may also mean that clamav-milter hasn't started, run ps and check your logs. The above example shows clamav-milter, clamd and sendmail all on the same machine, however using TCP they may reside on different machines, indeed clamav-milter is capable of talking to multiple clamds for redundancy and load balancing. I suggest putting SpamAssassin first since you're more likely to get spam than a virus/worm sent to you. Add to /etc/sysconfig/clamav-milter CLAMAV_FLAGS="local:/var/run/clamav/clmilter.sock" or if clamd is on a different machine CLAMAV_FLAGS="--server=192.168.1.9 local:/var/run/clamav/clmilter.sock" If you want clamav-milter to listen on TCP for communication with sendmail, for example if they are on different machines use inet:. On machine A (running sendmail) you would have in sendmail.mc: INPUT_MAIL_FILTER(`clamav', `S=inet:3311@machineb, F=T, T=S:4m;R:4m')dnl On machine B (running clamav-milter) you would start up clamav-milter thus: clamav-milter inet:3311 You should have received a script to put into /etc/init.d with this software. You should always start clamd before clamav-milter. You may also think about the F= entry in sendmail.mc, since it tells sendmail what to do with emails if clamav-milter is not running. Setting F=T will tell the remote end to resend later (temporary failure), setting F=R will reject the email (permanent failure) and setting F= will pass the email through as though clamav-milter were not installed, in this case you should warn your users that emails are not being scanned. We recommend setting F=T. You may wish to experiment with the T= entry which governs timeout options. You MUST set some type of timeout or a malicious client could cause a Denial of Service attack by keeping your clamav-milter threads alive. The types of timeout are C (time for clamav-milter to acknowledge to sendmail that it has accepted a new connection), S (timeout for sending information from sendmail to clamav-milter), R (timeout for sendmail reading a reply from clamav-milter when it has been sent some information) and E (timeout for clamav-milter to handle the end-of-message request, this needs to be high enough to scan the largest file that you will receive since it is at this stage that the file is scanned, but short enough to ensure that a DoS can't occur when lots of scans are requested). The important entries for clamav-milter are C and E (both default to 5 minutes). WARNING: When running on internal mode (--external is NOT used), clamav-milter will need to wait for all connections to stop before it can reload the database after running freshclam. It is therefore important that NO timeouts in sendmail.cf are set too high or worse still turned off, otherwise clamav-milter can wait a long time, perhaps indefinately, while waiting for the system to quieten down. The same goes for disabling StreamMaxLength, since receiving a very large email to be scanned may take a long time. We advise setting StreamMaxLength to 1M. Don't forget to rebuild sendmail.cf after modifying sendmail.mc. You will need to restart sendmail after rebuilding sendmail.cf and starting clamd and clamav-milter. As with all software it is wise to ensure that clamav-milter has the least privileges it needs to run. So don't run it as root and don't store the sockets in a directory that can be written by everyone. For example ensure that /var/run is owned and writeable only by root and add entries for 'User' and 'FixStaleSocket' in clamd.conf. When using UNIX domain sockets via the LocalSocket option of clamd.conf, we recommend that you use the --quarantine-dir option since that may improve performance. If you wish to send a warning when a message is blocked, clamav-milter MUST be able to call sendmail, for example on a Fedora Linux system: # ls -lL /usr/lib/sendmail -rwxr-sr-x 1 root smmsp 732356 Sep 1 11:16 /usr/lib/sendmail To test that your clamAV system is now intercepting viruses, visit http://www.testvirus.org If, under heavy strain on Linux, you see the message thread_create() failed: 12, abort appearing in a log file, you will need to increase the number of threads on your system (/proc/sys/kernel/threads-max), or decrease the value of --max-children. 3. CHANGE HISTORY Changes 0.2: 4/3/03 clamfi_abort() now always calls pthread_mutex_unlock 5/3/03 Only send a bounce if -b is set Version now uses -v not -V --config-file couldn't be set by -c 0.3 7/3/03 Enhanced the Solaris compile time comment No need to save the return result of LogSyslog Use LogVerbose 0.4 9/3/03 Initialise dataSocket/cmdSocket correctly 10/3/03 Say why we don't connect() to clamd Enhanced '-l' usage message 0.5 18/3/03 Ported to FreeBSD 4.7 Source no longer in support, so remove one .. from the build instructions Corrected the use of strerror_r 0.51 20/3/03 Mention StreamSaveToDisk in the installation Added -s option which allows clamd to run on a different machine from the milter 0.52 20/3/03 -b flag now only stops the bounce, sends warning to recipient and postmaster 0.53 24/3/03 %d->%u in syslog call 27/3/03 tcpSocket is now of type in_port_t 27/3/03 Use PING/PONG 0.54 23/5/03 Allow a range of IP addresses as outgoing ones that need not be checked 0.55 24/5/03 Use inet_ntop() instead of inet_ntoa() Thanks to Krzysztof Olędzki 0.60 11/7/03 Some TODOs done by Nigel Kukard Should stop a couple of remote chances of crashes 0.60a 22/7/03 Tidied up message when sender is unknown 0.60b 17/8/03 Optionally set postmaster address. Usually one uses /etc/aliases, but not everyone want's to... 0.60c 22/8/03 Another go at Solaris support 0.60d 26/8/03 Removed superfluous buffer and unneeded strerror call ETIMEDOUT isn't an error, but should give a warning 0.60e 09/9/03 Added -P and -q flags by "Nicholas M. Kirsch" 0.60f 17/9/03 Changed fprintf to fputs where possible Redirect stdin from /dev/null, stdout&stderr to /dev/console 0.60g 26/9/03 Handle sendmail calling abort after calling cleanup (Should never happen - but it does) Added -noxheader patch from dirk.meyer@dinoex.sub.org 0.60h 28/9/03 Support MaxThreads option in config file, overriden by --max-children. Patch from "Richard G. Roberto" 0.60i 30/9/03 clamfi_envfrom() now correctly returns SMFIS_TEMPFAIL, in a few circumstances it used to return EX_TEMPFAIL Patch from Matt Sullivan 0.60j 1/10/03 strerror_r doesn't work on Linux, attempting workaround Added support for hard-coded list of email addresses who's e-mail is not scanned 0.60k 5/10/03 Only remove old UNIX domain socket if FixStaleSocket is set 0.60l 11/10/03 port is now unsigned Removed remote possibility of crash if the target e-mail address is very long No longer calls clamdscan to get the version 0.60m 12/10/03 Now does sanity check if using localSocket Gets version info from clamd Only reset fd's 0/1/2 if !ForeGround 0.60n 22/10/03 Call pthread_cont_broadcast more often 0.60o 31/10/03 Optionally accept all mails if scanning procedure fails (Joe Talbott ) 0.60p 5/11/03 Only call mutex_unlock when max_children is set Tidy up the call to pthread_cond_timedwait 0.60q 11/11/03 Fixed handling of % characters in e-mail addresses pointed out by dotslash@snosoft.com 0.65 15/11/03 Upissue of clamav 0.65a 19/11/03 Close cmdSocket earlier Added setpgrp() 0.65b 22/11/03 Ensure milter is not run as root if requested Added quarantine support 0.65c 24/11/03 Support AllowSupplementaryGroups Fix warning about root usage 0.65d 25/11/03 Handle empty hostname or hostaddr Fix based on a submission by Michael Dankov 0.65e 29/11/03 Fix problem of possible confused pointers if large number of recipients given. Fix by Michael Dankov . 0.65f 29/11/03 Added --quarantine-dir Thanks to Michael Dankov . 0.65g 2/12/03 Use setsid if setpgrp is not present. Thanks to Eugene Crosser 0.65h 4/12/03 Added call to umask to ensure that the local socket is not publically writeable. If it is sendmail will (correctly!) refuse to start this program Thanks for Nicklaus Wicker Don't sent From as the first line since that means clamd will think it is an mbox and not handle unescaped From at the start of lines properly Thanks to Michael Dankov 0.65i 9/12/03 Use the location of sendmail discovered by configure 0.65j 10/12/03 Timeout on waiting for data from clamd 0.65k 12/12/03 A couple of calls to clamfi_cleanup were missing before return cl_error 0.66 13/12/03 Upissue 0.66a 22/12/03 Added --sign 0.66b 27/12/03 --sign moved to privdata 0.66c 31/12/03 Included the sendmail queue ID in the log, from an idea by Andy Fiddaman 0.66d 10/1/04 Added OpenBSD instructions Added --signature-file option 0.66e 12/1/04 FixStaleSocket: no longer complain if asked to remove an old socket when there was none to remove 0.66f 24/1/04 -s: Allow clamd server name as well as IPaddress 0.66g 25/1/04 Corrected usage message Started to honour --debug Dump core on LINUX if CL_DEBUG set Support multiple servers separated by colons 0.66h 26/1/04 Corrected endian problem (ntohs instead of htons) 0.66i 28/1/04 Fixed compilation error with --enable-debug 0.66j 29/1/03 Added --noreject flag, based on a patch by "Vijay Sarvepalli" 0.66k 2/2/04 When --postmaster-only is given, include the system ID of the message in the warning e-mail, since that will help the administrator when sifting through the mail logs. Based on an idea by Jim Allen, 0.66l 7/2/04 Updated URL reference Added new config.h mechanism 0.66m 9/2/04 Added Hflag from "Leonid Zeitlin" 0.66n 13/2/04 Added TCPwrappers support Removed duplication in version string Handle machines that don't have in_port_t 0.67 16/2/04 Upissued to 0.67 0.67a 16/2/04 Added clamfi_free 0.67b 17/2/04 Removed compilation warning - now compiles on FreeBSD5.2 Don't allow --force to overwride TCPwrappers 0.67c 18/2/04 Added dont-log-clean flag 0.67d 19/2/04 Reworked TCPwrappers code Thanks to "Hector M. Rulot Segovia" Changed some printf/puts to cli_dbgmsg 0.67e 20/2/04 Moved the definition of the sendmail pipe The recent changes to the configure script changed the order of includes so some prototypes weren't getting in 0.67f 20/2/04 Added checkClamd() - if possible attempts to see if clamd has died 0.67g 21/2/04 Don't run if the quarantine-dir is publically accessable 0.67h 22/2/04 Change the log level TCPwrapper denying Handle ERROR message from clamd Moved smfi_setconn to avoid race condictions when an e-mail is received just as the milter is starting but isn't ready to handle it causing the milter to go to an error state Hardend umask 0.67i 27/2/04 Dropping priv message now same as clamd Only use TCPwrappers when using TCP/IP to establish communications with the milter 0.67j 27/2/04 Call checkClamd() before attempting to connect, it's a way of warning the user if they've started the milter before clamd checkClamd() now stashes pid in syslog Ensure installation instructions tally with man page and put sockets into subdirectory for security clamfi_close debug, change assert to debug message Better way to force TCPwrappers only with TCP/IP 0.67k 7/3/04 Ensure cli_dbgmsg's end with \n Fixed some warning messages with icc Use cli_[cm]alloc Included extra information if --headers is given (based on an idea from "Leonid Zeitlin" 0.67l 10/3/04 Use new HAVE_STRERROR_R rather than TARGET_OS_SOLARIS to determine if strerror_r exists 0.70 17/3/04 Up-issued to 0.70 0.70a 20/3/04 strerror_r is a bit confused on Fedora Linux. The man page says it returns an int, but the prototype in string.h says it returns a char * Say how many bytes can't be written to clamd - it may give a clue what's wrong 0.70b 26/3/04 Display errno information on write failure to clamd Ensure errno is passed to strerror Print fd in clamfi_send debug 0.70c 27/3/04 Timestamp clamfi_send messages Call cli_warnmsg if ERROR received Minor code tidy Delay connection to clamd to handle clamd's appetite for timing out when the remote end (the end talking to sendmail) is slow Prefer cli_dbgmsg/cli_warnmsg over printf 0.70d 29/3/04 Print the sendmail ID with the virus note in syslog config file location has changed 0.70e 1/4/04 Fix a remote possibility of a file descriptor leak in PingServer() if clamd has died Fix by Andrey J. Melnikoff (TEMHOTA) Corrected some debug messages reported by Sergey Y. Afonin 0.70f 1/4/04 Added auto-submitted header to messages generated here Suggested by "Andrey J. Melnikoff (TEMHOTA)" Add advice that --quarantine-dir may improve performance when LocalSocket is used ThreadTimeout seems to have been changed to ReadTimeout 0.70g 3/4/04 Error if ReadTimeout is -ve Honour StreamMaxLength 0.70h 8/4/04 Cleanup StreamMaxLength code 0.70i 9/4/04 Handle clamd giving up on StreamMaxLength before clamav-milter 0.70j 15/4/04 Handle systems without inet_ntop 0.70k 17/4/04 Put the virus message in the 550 rejection 0.70l 19/4/04 Started coding e-mail template support 0.70m 19/4/04 Started code to parse header to find the real infected machine Added the --from flag Return SMFIS_TEMPFAIL when out of memory idea by Joe Maimon Some still to be done Based on an idea by Christian Pelissier . Store different day's quarantines in different directories to make them easier to manage 0.70n 20/4/04 Allow for "i" macro not defined in sendmail.cf clamfi_connect: print better message if hostaddr is null 0.70o 20/4/04 Added X-Virus-Status Always add X-Virus-Scanned If hostaddr is NULL assume it's a local connection. This is probably a safe assumption but it should be verified 0.70p 20/4/04 If /dev/console fails to open, open /dev/null instead on fds 1 and 2 TCP_WRAPPERS code now uses inet_ntop() Simplify virus string Sort out tabs in the hard coded e-mail message 0.70q 22/4/04 No need to parse the received line if --headers is given If -outgoing is given put generated emails in the deferred queue to avoid the milter being called twice at the same time (one on the incoming one on the outgoing) header_list_print, ensure From lines are escaped, may not be needed but it is better to be on the safe side When loadbalancing, fail to start only if no servers can be reached (used to fail if any one server could not be reached) Not all servers were load balanced 0.70r 23/4/04 Ensure only From lines are escaped Also defer generated emails if --force-scan is given Better subject for quarantine e-mails 0.70s 25/4/04 Added --pidfile support 0.70t 28/4/04 Better quarantine message error report when failing to create the temporary file Send 554 after DATA received, not 550 Don't send rejection notices to rejection notices, we just end up playing ping-pong (patch by "Andrey J.Melnikoff (TEMHOTA)" If CL_DEBUG is defined, don't redirect stdout/stderr Don't attempt to return an old signature if no filename has been given. There has never been one to return 0.70u 29/4/04 When changing from realloc to cli_realloc I forgot to keep the assignment of signature 0.70v 6/5/04 clamfi_close now always checks privdata is NULL, not only when debugging Allow transfers of exactly streamMaxLength Warn if a clean file can't be removed from the quarantine When streamMaxLength is exceeded add a header where possible, unless --noxheader is given 0.70x 7/5/04 Only report that we've dropped privilege if the setuid succeeded, fix by Jens Elkner If logVerbose is set state both starting and started messages (based on an idea by "Sergey Y. Afonin" Also added X-Infected-Received-From: header by Sergey Fix from Damian Menscher ensures that when a child dies we continue when max children is hit Report an error if inet_ntop fails in tcp_wrappers 0.71 16/5/04 Up issue 0.71a 21/5/04 --from wasn't always a recognised option Write failure to quarantine file now logs the name of the file Commented out TKs advice about using quarantine when using localSocket, sys admins were confused by it 0.71b 24/5/04 Add which host did the virus scanning 0.71c 25/5/04 X-Virus-Status: Not Scanned - StreamMaxLength exceeded was not always being added Now says host running clamd rather than host running clamav-milter, useful for checking load balancing etc. 0.72 3/6/04 Up-issued 0.72a 8/6/04 --from didn't take an option (fix to 0.71a) 0.73 14/6/04 Up-issued 0.73a 14/6/04 Added support for Windows SFU 3.5 0.73b 15/6/04 Use fully qualified host name for X-Virus-Scanned header when localSocket is set In template files support {sendmail-variable} and support \%v to send the %v string Tidyup handling if the quarantine directory can't be created 0.73c 21/6/04 Call trylock in clamfi_abort before unlock to prevent attempt to unlock not locked mutex since we have no control over when clamfi_abort() is called Remove warning message on FreeBSD5.2 0.73d 28/6/04 Don't error when creating the quarantine directory if it already exists 0.74 29/6/04 Up-issued 0.74a 29/6/04 Allow the child timeout to be configurable 0.74b 8/7/04 Validate the arguments to inet_ntop 0.74c 14/7/04 Added --dont-wait Added --advisory 0.74d 18/7/04 Added sanity check in clamfi_connect 0.74e 21/7/04 Fixed thread unsafe code causing problems with multi-CPU machines running Solaris 0.74f 22/7/04 Use gethostbyname_r() if available 0.75 22/7/04 Up-issue 0.75a 25/7/04 Fixed warning message when building on FreeBSD4.9 Closed (small) memory leak Fix crash when the 1st remote service goes down Only use gethostbyname_r on LINUX for now Load balancing - improved a bit - but still some way to go 0.75b 26/7/04 Template file: %v now prints the virus name without the trailer 0.75c 29/7/04 Better load balancing if max_children = 0 Use HAVE_GETHOSTBYNAME_R_6 0.75d 29/7/04 Don't say "waiting for some to exit" if --dont-wait 0.75e 30/7/04 Handle new clamd message when StreamMaxLength is exceeded 0.75f 02/8/04 Use HAVE_GETHOSTBYNAME_R_5 and HAVE_GETHOSTBYNAME_R_3 Try to ensure that the fully qualified domain name is used idea by christian laubscher Template files can now contain more than one variable Template files sendmail variables handling changed to allow access to variables not in braces. All sendmail variables are now delimeted by dollars, e.g. ${j}$ Better local IP table by Damian Menscher and Andy Fiddaman 0.75g 06/8/04 Handle privdata->from not set when --bounce is set "Denis Ustimenko" Quarantined file's names now contain the name of the virus 0.75h 07/8/04 Some tweaking of the load balancing code 0.75i 11/8/04 Added David Champion isLocalAddr routine 0.75j 11/8/04 Fix --from=EMAIL option which often didn't work reported by "Sergey Y. Afonin" 0.75k 13/8/04 Single thread through tcp_wrappers, reported by David Champion 0.75l 24/8/04 Give hint about what do to if the running as root warning appears Optimise the sending of the To and From headers to clamd Give better SMTP status message when asking for retransmit when --dont-wait is set Quarantine files now handle operating system filename restrictions 0.75m 26/8/04 Generate correct message if there is no response from any clamd server Handle %h (headers) in the template file Fix bug in optimisation when more than one To line is received 0.75n 8/9/04 Better quarantine filename handling on MACOS/X Added i18n support Better error message if the quarantine directory is publically accessable 0.75o 12/9/04 Use .../share/clamav/clamav-milter/locale for the locale information Added first draft of SESSION code. Do NOT use in a production environment. 0.75p 13/9/04 Updated SESSION code. 0.75q 13/9/04 Use pthread_cond_broadcast() instead of pthread_cond_signal() 0.75r 17/9/04 --help didn't include information about --max-children Fix problem in the template file handling where sendmail variables did't work after clamav variables. 0.75s 20/9/04 StreamSaveToDisk is longer used Update references to clamav.conf, should now be clamd.conf 0.80 20/9/04 Up-issued 0.80a 25/9/04 Some Linux's need locale.h as well as libintl.h Honour LogFacility When sanitising the quarantine's filename, don't sanitise the directory name as well 0.80b 27/9/04 Added quit() routine to tidy when shutting down honour HAVE_IN_ADDR_T Added --broadcast option 0.80c 27/9/04 Added iface option to --broadcast 0.80d 28/9/04 Notify clamavmon when a clamd is down, and when clamav-milter stops/starts Error gracefully if the iface option is set to --broadcast on an operating system that doesn't support it 0.80e 30/9/04 If you say --from with no arguments, the from address is now set to the orginator's address 0.80f 2/10/04 Fix crash if %h is used in a template and --headers is not set 0.80g 4/10/04 Enhanced the SMTP reply 0.80h 4/10/04 Fix mails containing viruses being kept twice in quarantine; once as 'msg.xxxxxx' and once as 'msg.xxxxxx.virusname' 0.80i 5/10/04 ScanMail is no longer needed Improved tracing of the infected machine 0.80j 8/10/04 SESSION: reset the session if the PORT command fails Correct --broadcast code if BINDTODEVICE isn't supported 0.80k 24/10/04 Validate the length of the server hostnames Die if the name of the sockets are the same. By dying earlier we can generate a more useful message than libmilter's bind failure message SESSION code now on by default Use cli_strtokbuf() instead of cli_strtok() whereever possible 0.80l 27/10/04 Remove X-VIRUS-STATUS on incoming messages since there's no way to verify it's statement about being clean Plug remote possibility of file descriptor leak Return EX_OSERR if fork fails, not EX_TEMPFAIL If clamav-milter points to more than one server, ensure that the version information for that server is added to the header Update version information in the watchdog. There may therefore be a delay between the server updating and this being reflected in the headers 0.80m 29/10/04 Mark a session as down if the STREAM command timesout, or we can't connect to the returned PORT Fix problem with deleting X-VIRUS-STATUS not setting correct libmilter settings 0.80n 30/10/04 Fix possible crash when one or more servers can't be contacted 0.80o 3/11/04 SESSION: Warn if no clamd servers can be contacted when starting When changing a subject, keep the original subject in X-Original-Subject 0.80p 4/11/04 SESSION: Fix bug causing crash when using LocalSocket mode 0.80q 8/11/04 SESSION: Ensure watchdog only started in TCPSocket mode 0.80r 10/11/04 Define SHUT_* and INET_ADDRSTRLEN if not already defined SCAN in situ rather than passing the file through a socket if localSocket and not quarantine_dir 0.80s 13/11/04 Use SCAN when UNIX socket (localSocket) is used or when the load balancing algorithm favours localhost 0.80t 20/11/04 Use the improved cli_gentemp(NULL) Added more samples to ignoredEmailAddresses list, from "Sergey Y. Afonin" Added validation for the reply from clamd Include the sendmail ID in the quarantine file name, for easier cross matching with the sendmail log file 0.80u 1/12/04 SESSION: Don't hang when streammaxlength is reached - reset the link Not all previous X-Virus-Status headers were removed Added the --internal flag TODO: freshclam notification and version headers 0.80v 2/12/04: --internal now notices when freshclam has been run The default value for --timeout has been changed from 60 seconds to 0 (wait forever) 0.80w 3/12/04: --internal now honours scanning modes and archive limits 0.80x 4/12/04: findServer() could return values out of range 0.80y 5/12/04: --internal: fixed memory leak when a new database is loaded Fixed array overrun on startup that caused problems on some platforms 0.80z 6/12/04: Quarantine files were not being renamed to contain the virus name if --quiet is given Fix compilation error if is SESSION not defined. Quarantine files could lose the date from the path 0.80aa 7/12/04: Daily quarantine directories were not always being created 0.80bb 12/12/04: On Linux store the -ve process group in the pid file to ensure that all threads are sent signals Support the temporary and quarantine directories being on different filesystems 0.80cc 13/12/04: Fix crash on FreeBSD if DNS has been incorrectly set up Mutex the version strings 0.80dd 19/12/04: Tidy up non SESSION code 0.80ee 19/12/04: Error didn't appear in SESSIONS mode if LocalSocket set and neither max-children nor MaxThreads is set. 0.80ff 21/12/04: Fault tolerance - sometimes attempted to get a STREAM from a server that is down 0.80gg 12/1/05: Fixed DNS resolution error messages which could print the incorrect hostname that is not being resolved 0.81 19/1/05: Up issued 0.81a 22/1/05: If forwarding to a quarantine user fails log as LOG_ERR not LOG_DEBUG Try to sanity check that the input socket name is the same as the same given to sendmail Redirect stdout and stderr to LogFile, if that is set --quarantine didn't redirect to the given email address if --internal was used (reported by N Fung ) 0.81b 25/1/05: Disabled SESSION by default (causes problems with clamd on BSD systems when running freshclam) Changed --internal to --external. Internal mode is now the default 0.81c 27/1/05: Don't scan emails intended for the --quarantine address, that stops scanning of emails generated with viruses if --outgoing has been set Downgraded scanmail not defined if --external isn't given from error to warning Added -i flag when calling sendmail, suggested by Michal Jaegermann 0.81d 28/1/05: Some error messages still talked about --internal Scanmail not set warning is now only given if DisableDefaultScanOptions is set 0.81e 30/1/05: Don't check compatibility with sendmail.cf if sendmail is running on a different machine PACKADDR is now uses unsinged to remove warning on Sun's C compiler, patch by "Dugal James P." SESSION is back on by default, to test clamd fix 0.81f 31/1/05: Delete X-Virus-Status in clamfi_eom not in clamfi_header, patch by Jef Poskanzer X-Virus-Status now says that virus that it's infected with, suggestion by "Hank Beatty" 0.81g 2/2/05: Call watchdog if neither --external nor SESSION 0.82 6/2/05: On Solaris, ensure when quarantining a file that the old location is removed Up issue 0.82a 7/2/05: Added --detect-forged-email-address NUL terminate the string read from clamd 0.82b 8/2/05: Don't use clamd's SESSION command 0.82c 8/2/05: Tidy some code and debug statements 0.82d 11/2/05: Added --whitelist-file=file Added --sendmail-cf=file Debug around mkdir/rmdir of tmpdir SESSION mode: not all sessions were closed when quitting 0.83 13/2/05: Up issue 0.83a 23/2/05: Issue a warning if sendmail can't be executed Remove pidfile, suggested by Stephen Gran 0.83b 1/3/05: When not using --external, if a database update is found, stop accepting inputs to quiten the system for the database reload, rather than wait for it to happen by itself 0.84 3/3/05: Up-issue 0.84a 5/3/05: Note that when the connection to sendmail is via TCP/IP rather than a UNIX domain socket, that --local must be given 0.84b 9/3/05: Got rid of that GOTO --detect-forged-local-address no longer gives false positives on emails which have the Sender header set (e.g. mailing lists) Use {mail_addr} if no From field is received 0.84c 18/3/05: Better handling of {mail_addr} / <> 0.84d 6/4/05: Internal mode: print virus and error information on stdout. This goes to LogFile when not in debug mode. Included patch by Andy Feldt for AIX 5.2. I do not have access to such a machine so any feedback would be helpful 0.84e 18/4/05: Fixed a multi-threading problem relating to updating the database when in internal mode Use HAVE_CTIME_R_[23] 0.84f 4/5/05: Better handling of open failures for LogFile Always send 451 when reloading a database, even if dont-wait isn't set 0.84g 9/5/05: Print an error in the log if a segfault is received 0.85 11/5/05: Up-issue 0.85a 12/5/05: Open /dev/console before dropping privilege, reported by David Crow 0.85b 19/5/05: Warn if TCPAddr doesn't allow connection from us Warn if notification email fails Enable some sendmail debug if LogVerbose is set Added sanity checks that the socket can be created 0.85c 24/5/05: Use the program name from argv[0], based on an idea by Joe Maimon When dying use LOG_CRIT rather than LOG_ERR 0.85d 25/5/05: When not in external mode, TEMPFAIL when loading a new database, even when --dont-wait isn't given 0.85e 27/5/05: When loading a new database when not in external mode, keep scanning with the old one rather than hold up incoming mails while waiting for clamav-milter to become idle then reloading the database Backported from CVS: When checking if an email address is in the white-list, check if it is the quarantine email address before checking against the white-list file When starting, check that the white-list file can be opened 4. INTERNATIONALISATION The .po file was created with the command xgettext --msgid-bugs-address=bugs@clamav.net --copyright-holder=njh@bandsman.co.uk -L c -d clamav-milter -k_ clamav-milter.c If you're interested in helping to translate this program please drop the author an e-mail. 5. BUG REPORTS Please send bug reports and/or comments to Nigel Horne or bugs@clamav.net. Various tips will go here, for example define(`confMILTER_LOG_LEVEL',`22') Running in the foreground, valgrind, LogSyslog, LogVerbose, LogFile etc. 6. TODO There are several ideas marked as TODO in the source code. If anyone has any other suggestions please feel free to contact me.