##################################################################### WHAT IS IT: modularized contentfilter for Zmailer COPYRIGHT: (c) 2003 Eugene G. Crosser LICENSE: The same set as apply to Zmailer code NOTE: distribution contains third party source code with possibly different copyright: - strlcpy implementation from OpenBSD - lhash implementation from SSLeay/OpenSSL - getopt implementation from FSF ##################################################################### The goal of this project is to get a reasonable tradeoff between speed and features. It sould be easy to add or exclude modules, to write new modules and distribute them independently from the core package. The program makes use of the `new' (as of this writing) contentfilter interface of Zmailer (http://www.zmailer.org/) where communication takes place over unix domain socket. When it gets a path to Zmailer message file, the program starts a thread or forks, the thread/child mmaps the (readonly) (or pulls into memory if you don't have mmap()), and invokes plugins that claimed the initial `stage' (by default, "zmsg"). Each plugin may fill in the `ans' buffer and must return either ZMSCAN_CONTINUE or ZMSCAN_STOP. In the latter case, no further plugins are called and the `ans' buffer is passed over to smtpserver. Each plugin can also invoke other `stages' or even the same `stage', in which case it will be called resursively. It should check the return code of stage invocation and return immediately if it gets anything other than ZMSCAN_CONTINUE. Plugin scanning function must me thread-safe and reentrant. Initialization function does not need to be. Plugin functions may be compiled in or dynamically loadable (if your OS supports dynamic objects). To compile in a plugin, put the source into `plugins' subdirectory and run ./configure --with-plugins="blank separated list"; include the name of your source file (without ".c" suffix). Dynamically loadbale plugins may be built independantly; but they need access to "zmscanner.h" and "libzmscanner.a"; these are normally installed at default locations, /usr/local/include and /usr/local/lib. Plugin source must include a ZMS_MODULE() macro which specifies what `stage' to claim, internal name of the module, and three functions - plugin initialization (may do configuration parsing etc.), plugin termination, and data scanning. See the source for examples. The daemon itself is designed in such a way that when you kill the parent process with SIGUSR1, it forks and execs its own binary (which could have been upgraded in the meanwhile) without closing the control socket. When the child initializes and is ready to process requests, it signals the parent with SIGUSR2 which causes graceful shudown of the process after all active processing threads terminate. There are several useful external plugins available, e.g. zms_clamav that doe virus scanning on non-text body parts, zms_dehtml that strips HTML tags off text/html parts, and zms_pcre that scans text body parts for regular expresstions using pcre library (http://www.pcre.org/). ##################################################################### Appendix: building from CVS $ cvs -d :pserver:cvs@cvs.average.org:/roots/ZMSCANNER login CVS password: [hit Enter here] $ cvs -d :pserver:cvs.average.org:/roots/ZMSCANNER co zmscanner $ cd zmscanner $ aclocal -I m4 $ autoheader $ libtoolize $ automake -a $ autoconf $ ./configure --various-options ##################################################################### $Id: README,v 1.5 2004/06/04 16:56:46 crosser Exp $ $Log: README,v $ Revision 1.5 2004/06/04 16:56:46 crosser in README ask to run aclocal -I m4 bump version make man pages distributable fix bug in zmsctl make FreeBSD compatibility hack in setting SIGCHLD handler Revision 1.4 2003/09/14 10:34:22 crosser 3d party source notice Revision 1.3 2003/09/09 22:15:50 crosser more doc; typo in plugin Revision 1.2 2003/09/09 21:58:27 crosser write some doc Revision 1.1 2003/08/21 16:32:20 crosser README, ansi2knr, stdio