MailCorral is invoked by the milter interface of sendmail, upon startup. It registers callback routines for the various message processing actions, as defined by the milter interface. Upon return to sendmail, the callbacks are called by sendmail whenever it has messages to deliver. The callbacks filter the messages for noxious entities (e.g. viruses) and warn the user of their presence by inserting warnings into the body text of the message. In some cases (e.g. attachments), the offending entities are altered or deleted to render them harmless.
Checking for spam can be done using the built-in whitelist and statistical spam checkers or by informing MailCorral about a spam arbitration daemon (arbitron) such as SpamAssassin. The statistical spam counts are gathered on-the-fly as the message is scanned for other things. White and blacklist checking is done before any call is made to the spam arbitron.
If a spam arbitron is being used, a request for spam determination is sent to the arbitron, via a pipe, which includes the headers and text of the message (non-text attachments are omitted, thereby speeding up the process).
If either the internal spam checks or the arbitron determine that the message is spam, it is disposed of according to the disposition options chosen. Three choices are available: deliver the spam, suitably tagged as such; uncerimoniously place the spam in the trash can; divert the spam to a corral where it can be remailed to the recipient at a later date.
The first two disposition options are self-explanatory. The third option causes the spam not to be sent directly to the recipient but instead written to a corral directory. The corralled message is given all of the usual filtering, before it is corralled, hence it is ready for immediate remailing, should the recipient so decide (see SpamCorral).
MailCorral comes with basic, rules-based virus checking built in. This works by checking attachments and inline MIME entities against a table of well-known problem file and MIME types. If a bad type is found, the attachment or inline MIME entity can be deleted or have its name mangled so that it cannot be accidentally opened by some well-meaning application that doesn't know better.
Signature-based virus checking can be carried out in conjunction with a virus arbitration daemon (arbitron), for instance ClamAV. If such a virus arbitron is being used, a request for virus detection is sent to the arbitron, via a pipe, which includes all of the components of the message that could harbor a virus (text attachments, the text body of the message and the headers are omitted, thereby speeding up the process, because they cannot contain a virus).
Archiving is a fairly straightforward affair. If a third-party archiver is being used, a second copy of the message is simply sent to the archiver. However, there is one wrinkle. This message must itself pass through sendmail and MailCorral as it is delivered. Hence, MailCorral applies special checks against messages being delivered to the archiver and bypasses much of its filtering if one is found. Thus, the second copy of the message can pass through the filter untouched on its way to the archiver.
If archiving is being done directly to a local archive directory, a file name is made up, the file opened and all of the message components (most of which are likely to be cached) written to it. If indexing is also being done, a connection to the MySQL database is opened and the index entries written to it.
To do all of the above, this program must be used in conjunction with a version of sendmail that has milter support and must be set up in the sendmail config file to be called by milter. In addition, spam recognition requires the use of a spam arbitration daemon (unless you wish to insert your own code into the filter) to decide which messages are, indeed, spam, and virus detection, likewise, needs a virus arbitration daemon to identify the viruses, unless you, again, use your own, custom code.
Incidentally, custom filtering code can be inserted into the filter. To ease the burden on the programmer, a Perl shim is invoked by the filter that sets up all of the message components so that the custom code can get at them. The shim then invokes the custom code, which is also written in Perl. The answer is returned to the shim and it does the rest of the work involved with telling the filter how to dispose of each of the components.