1MIMEDEFANG-FILTER(5)          File Formats Manual         MIMEDEFANG-FILTER(5)
2
3
4

NAME

6       mimedefang-filter - Configuration file for MIMEDefang mail filter.
7
8

DESCRIPTION

10       mimedefang-filter  is  a  Perl fragment that controls how mimedefang.pl
11       disposes of various parts of a MIME message.  In addition, it  contains
12       some  global  variable  settings  that  affect the operation of mimede‐
13       fang.pl.
14
15

CALLING SEQUENCE

17       Incoming messages are scanned as follows:
18
19
20       1) A temporary working directory is created.  It is  made  the  current
21       working  directory  and  the e-mail message is split into parts in this
22       directory.  Each part is  represented  internally  as  an  instance  of
23       MIME::Entity.
24
25
26       2)  If  the file /etc/mail/mimedefang-filter.pl defines a Perl function
27       called filter_begin, it is called with a single argument consisting  of
28       a  MIME::Entity  representing  the  parsed  e-mail message.  Any return
29       value is ignored.
30
31
32       3) For each leaf part of the mail message, filter is called  with  four
33       arguments: entity, a MIME::Entity object; fname, the suggested filename
34       taken from the MIME Content-Disposition header; ext,  the  file  exten‐
35       sion, and type, the MIME Content-Type value.  For each non-leaf part of
36       the mail message, filter_multipart is called with the same  four  argu‐
37       ments  as filter.  A non-leaf part of a message is a part that contains
38       nested parts.  Such a part has no useful body,  but  you  should  still
39       perform filename checks to check for viruses that use malformed MIME to
40       masquerade as non-leaf parts (like message/rfc822).   In  general,  any
41       action  you  perform in filter_multipart applies to the part itself and
42       any contained parts.
43
44
45       Note that both filter and filter_multipart are optional.  If you do not
46       define them, a default function that simply accepts each part is used.
47
48
49       4)  After  all  parts  have  been processed, the function filter_end is
50       called if it has been defined.  It is passed a single argument consist‐
51       ing  of  the  (possibly  modified) MIME::Entity object representing the
52       message about to be delivered.
53
54

DISPOSITION

56       mimedefang.pl examines each part of the MIME message and chooses a dis‐
57       position  for  that part.  (A disposition is selected by calling one of
58       the following functions from filter and  then  immediately  returning.)
59       Available dispositions are:
60
61
62       action_accept
63              The  part  is passed through unchanged.  If no disposition func‐
64              tion is returned, this is the default.
65
66
67       action_accept_with_warning
68              The part is passed through unchanged, but a warning is added  to
69              the mail message.
70
71
72       action_drop
73              The part is deleted without any notification to the recipients.
74
75
76       action_drop_with_warning
77              The part is deleted and a warning is added to the mail message.
78
79
80       action_replace_with_warning
81              The part is deleted and instead replaced with a text message.
82
83
84       action_quarantine
85              The  part is deleted and a warning is added to the mail message.
86              In addition, a copy of the part is saved on the mail  server  in
87              the  directory  /var/spool/MD-Quarantine  and  a notification is
88              sent to the MIMEDefang administrator.
89
90
91       action_bounce
92              The entire e-mail message is rejected and an error  returned  to
93              the  sender.   The  intended  recipients are not notified.  Note
94              that in spite of the name, MIMEDefang does not generate  and  e-
95              mail  a failure notification.  Rather, it causes the SMTP server
96              to return a 5XX SMTP failure code.
97
98
99       action_discard
100              The entire e-mail message is discarded  silently.   Neither  the
101              sender nor the intended recipients are notified.
102
103

CONTROLLING RELAYING

105       You  can  define  a  function called filter_relay in your filter.  This
106       lets you reject SMTP connection attempts early on in the  SMTP  dialog,
107       rather  than  waiting until the whole message has been sent.  Note that
108       for this check to take place, you must use the -r flag with mimedefang.
109
110
111       filter_relay is passed two arguments: $hostip is the IP address of  the
112       relay  host  (for example, "127.0.0.1"), and $hostname is the host name
113       if known (for example, "localhost.localdomain") If the host name  could
114       not  be  determined,  $hostname is $hostip enclosed in square brackets.
115       (That is, ("$hostname" eq "[$hostip]") will be true.)
116
117
118       filter_relay must return a two-element list: ($code, $msg).  $msg spec‐
119       ifies  the text message to use for the SMTP reply, but because of limi‐
120       tations in the Milter API, this message is for  documentation  purposes
121       only---you cannot set the text of the SMTP message returned to the SMTP
122       client from filter_relay.
123
124       $code is a literal string, and can have one of the following values:
125
126
127       'REJECT'
128              if the connection should be rejected.
129
130
131       'CONTINUE'
132              if the connection should be accepted.
133
134
135       'TEMPFAIL'
136              if a temporary failure code should be returned.
137
138
139       'DISCARD'
140              if the message should be accepted and silently discarded.
141
142
143       'ACCEPT_AND_NO_MORE_FILTERING'
144              if the connection should be accepted and  no  further  filtering
145              done.
146
147
148       Earlier versions of MIMEDefang used -1 for TEMPFAIL, 0 for REJECT and 1
149       for CONTINUE.  These values still work, but are deprecated.
150
151
152       In the case of REJECT or TEMPFAIL, $msg specifies the text part of  the
153       SMTP reply.  $msg must not contain newlines.
154
155
156       For example, if you wish to reject connection attempts from any machine
157       in the spammer.com domain, you could use this function:
158
159       sub filter_relay {
160            my ($ip, $name) = @_;
161            if ($name =~ /spammer\.com$/) {
162                 return ('REJECT', "Sorry; spammer.com is blacklisted");
163            }
164            return ('CONTINUE', "ok");
165       }
166
167

FILTERING BY HELO

169       You can define a function called filter_helo in your filter.  This lets
170       you reject connections after the HELO/EHLO SMTP command.  Note that for
171       this function to be called, you must use the -H flag with mimedefang.
172
173
174       filter_helo is passed three arguments: $ip and $name are the IP address
175       and name of the sending relay, as in filter_relay.  The third argument,
176       $helo, is the argument supplied in the HELO/EHLO command.
177
178
179       filter_helo must return  a  two-to-five  element  list:  ($code,  $msg,
180       $smtp_code,  $smtp_dsn, $delay).  $code is a return code, with the same
181       meaning as the $code return from filter_relay.  $msg specifies the text
182       message  to  use  for  the SMTP reply.  If $smtp_code and $smtp_dsn are
183       supplied, they become the SMTP numerical reply code  and  the  enhanced
184       status  delivery  code  (DSN code).  If they are not supplied, sensible
185       defaults are used.  $delay specifies a delay in seconds; the  C  milter
186       code  will sleep for $delay seconds before returning the reply to Send‐
187       mail.  $delay defaults to zero.
188
189       (Note that the delay is implemented in the Milter C code; if you  spec‐
190       ify  a  delay  of 30 seconds, that doesn't mean a Perl slave is tied up
191       for the duration of  the  delay.   The  delay  only  costs  one  Milter
192       thread.)
193
194

FILTERING BY SENDER

196       You  can  define  a function called filter_sender in your filter.  This
197       lets you reject messages from  certain  senders,  rather  than  waiting
198       until  the  whole  message  has been sent.  Note that for this check to
199       take place, you must use the -s flag with mimedefang.
200
201
202       filter_sender is passed four arguments:  $sender is the envelope e-mail
203       address  of  the sender (for example, "<dfs@roaringpenguin.com>").  The
204       address may or may not be surrounded by angle brackets.  $ip and  $name
205       are  the IP address and host name of the SMTP relay.  Finally, $helo is
206       the argument to the SMTP "HELO" command.
207
208
209       Inside filter_sender, you can  access  any  ESMTP  arguments  (such  as
210       "SIZE=12345")  in  the  array @ESMTPArgs.  Each ESMTP argument occupies
211       one array element.
212
213
214       filter_sender must return a two-to-five element  list,  with  the  same
215       meaning as the return value from filter_helo.
216
217
218       For  example,  if  you wish to reject messages from spammer@badguy.com,
219       you could use this function:
220
221       sub filter_sender {
222            my ($sender, $ip, $hostname, $helo) = @_;
223            if ($sender =~ /^<?spammer\@badguy\.com>?$/i) {
224                 return ('REJECT', 'Sorry; spammer@badguy.com is blacklisted.');
225            }
226            return ('CONTINUE', "ok");
227       }
228
229
230       As another example, some spammers identify their own  machine  as  your
231       machine  in  the  SMTP "HELO" command.  This function rejects a machine
232       claiming to be in the "roaringpenguin.com" domain unless it really is a
233       Roaring Penguin machine:
234
235       sub filter_sender {
236         my($sender, $ip, $hostname, $helo) = @_;
237         if ($helo =~ /roaringpenguin.com/i) {
238           if ($ip ne "127.0.0.1" and
239               $ip ne "216.191.236.23" and
240               $ip ne "216.191.236.30") {
241                 return('REJECT', "Go away... $ip is not in roaringpenguin.com");
242           }
243         }
244         return ('CONTINUE', "ok");
245       }
246
247
248       As  a  third  example, you may wish to prevent spoofs by requiring SMTP
249       authentication when email is sent from some email addresses. This func‐
250       tion  rejects  mail from "king@example.com", unless the connecting user
251       properly authenticated as "elvisp". Note that this needs access to  the
252       %SendmailMacros  global,  that  is not available in filter_sender until
253       after a call to read_commands_file.
254
255       sub filter_sender {
256               my($sender, $ip, $hostname, $helo) = @_;
257               read_commands_file();
258               ### notice: This assumes The King uses authentication without realm!
259               if ($sender =~ /^<?king\@example\.com>?$/i and
260                   $SendmailMacros{auth_authen} ne "elvisp") {
261                       return('REJECT', "Faking mail from the king is not allowed.");
262               }
263               return ('CONTINUE', "ok");
264       }
265
266
267

FILTERING BY RECIPIENT

269       You can define a function called filter_recipient in your filter.  This
270       lets  you  reject  messages  to certain recipients, rather than waiting
271       until the whole message has been sent.  Note that  for  this  check  to
272       take place, you must use the -t flag with mimedefang.
273
274
275       filter_recipient  is passed nine arguments:  $recipient is the envelope
276       address of the recipient and $sender is the envelope e-mail address  of
277       the  sender  (for  example, "<dfs@roaringpenguin.com>").  The addresses
278       may or may not be surrounded by angle brackets.  $ip and $name are  the
279       IP  address  and  host  name of the SMTP relay.  $first is the envelope
280       address of the first recipient for this message, and $helo is the argu‐
281       ment   to   the   SMTP  "HELO"  command.   The  last  three  arguments,
282       $rcpt_mailer, $rcpt_host and $rcpt_addr are the Sendmail  mailer,  host
283       and  address  triple for the recipient address.  For example, for local
284       recipients, $rcpt_mailer is likely to  be  "local",  while  for  remote
285       recipients, it is likely to be "esmtp".
286
287
288       Inside  filter_recipient,  you  can access any ESMTP arguments (such as
289       "NOTIFY=never") in the array @ESMTPArgs.  Each ESMTP argument  occupies
290       one array element.
291
292
293       filter_recipient must return a two-to-five element list whose interpre‐
294       tation is the same as for filter_sender.  Note, however, that  if  fil‐
295       ter_recipient returns 'DISCARD', then the entire message for all recip‐
296       ients is discarded.  (It doesn't really make sense, but that's how Mil‐
297       ter works.)
298
299
300       For  example,  if  you wish to reject messages from spammer@badguy.com,
301       unless they are to postmaster@mydomain.com, you could  use  this  func‐
302       tion:
303
304       sub filter_recipient {
305            my ($recipient, $sender, $ip, $hostname, $first, $helo,
306                   $rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
307            if ($sender =~ /^<?spammer\@badguy\.com>?$/i) {
308                 if ($recipient =~ /^<?postmaster\@mydomain\.com>?$/i) {
309                      return ('CONTINUE', "ok");
310                 }
311                 return ('REJECT', 'Sorry; spammer@badguy.com is blacklisted.');
312            }
313            return ('CONTINUE', "ok");
314       }
315
316

INITIALIZATION AND CLEANUP

318       Just before a slave begins processing messages, mimedefang.pl calls the
319       functions filter_initialize (if it is defined) with no  arguments.   By
320       the  time  filter_initialize  is  called,  all the other initialization
321       (such as setting up syslog facility and priority) has been done.
322
323       If you are not using an embedded Perl interpreter, then  performing  an
324       action  inside  filter_initialize is practically the same as performing
325       it directly in the filter file, outside any function definition.   How‐
326       ever,  if you are using an embedded Perl interpreter, then anything you
327       call directly from outside a function definition is executed once  only
328       in  the parent process.  Anything in filter_initialize is executed once
329       per slave.  If you use any code that opens a descriptor (for example, a
330       connection  to  a  database server), you must run that code inside fil‐
331       ter_initialize and not directly from the  filter,  because  the  multi‐
332       plexor closes all open descriptors when it activates a new slave.
333
334       When  a  slave  is about to exit, mimedefang.pl calls the function fil‐
335       ter_cleanup (if it is defined) with no arguments.  This function can do
336       whatever  cleanup you like, such as closing file descriptors and clean‐
337       ing  up  long-lived  slave  resources.   The  return  value  from  fil‐
338       ter_cleanup becomes the slave's exit status.
339
340
341       If  filter_cleanup  takes  longer  than 10 seconds to run, the slave is
342       sent a SIGTERM signal.  If that doesn't kill it (because you're  catch‐
343       ing  signals,  perhaps),  then a further 10 seconds later, the slave is
344       sent a SIGKILL signal.
345
346

CONTROLLING PARSING

348       If you define a function called filter_create_parser  taking  no  argu‐
349       ments,  then mimedefang.pl will call it to create a MIME::Parser object
350       for parsing mail messages.
351
352       Filter_create_parser is expected to return a MIME::Parser object (or an
353       instance of a class derived from MIME::Parser).
354
355       You  can  use  filter_create_parser  to  change  the  behavior  of  the
356       MIME::Parser used by mimedefang.pl.
357
358       If you do not define a filter_create_parser function, then  a  built-in
359       version equivalent to this is used:
360
361            sub filter_create_parser () {
362                 my $parser = MIME::Parser->new();
363                 $parser->extract_nested_messages(1);
364                 $parser->extract_uuencode(1);
365                 $parser->output_to_core(0);
366                 $parser->tmp_to_core(0);
367                 return $parser;
368            }
369

EXTENDING MIMEDEFANG

371       The  man page for mimedefang-protocol(7) lists commands that are passed
372       to slaves in server mode (see "SERVER COMMANDS".)   You  can  define  a
373       function  called  filter_unknown_cmd to extend the set of commands your
374       filter can handle.
375
376       If you define filter_unknown_cmd, it is passed the unknown command as a
377       single  argument.   It  should return a list of values as follows:  The
378       first element of the list must be either "ok"  or  "error:"  (with  the
379       colon.)   The remaining arguments are percent-encoded.  All the result‐
380       ing pieces are joined together with a single space  between  them,  and
381       the resulting string passed back as the reply to the multiplexor.
382
383       For  example,  the  following function will make your filter reply to a
384       "PING" command with "PONG":
385
386       sub filter_unknown_cmd ($) {
387           my($cmd) = @_;
388           if ($cmd eq "PING") {
389               return("ok", "PONG");
390           }
391           return("error:", "Unknown command");
392       }
393
394       You can test this filter by typing the following as root:
395
396       md-mx-ctrl PING
397
398       The response should be:
399
400       ok PONG
401
402       If you extend the set of commands using filter_unknown_cmd, you  should
403       make all your commands start with an upper-case letter to avoid clashes
404       with future built-in commands.
405
406

REJECTING UNKNOWN USERS EARLY

408       A very common mail setup is to have a MIMEDefang machine act as an SMTP
409       proxy,  accepting  and  scanning  mail and then relaying it to the real
410       mail server.  Unfortunately, this means  that  the  MIMEDefang  machine
411       cannot  know  if  a local address is valid or not, and will forward all
412       mail for the appropriate domains.  If a mail comes in  for  an  unknown
413       user,  the  MIMEDefang machine will be forced to generate a bounce mes‐
414       sage when it tries to relay the mail.
415
416
417       It's often desirable to have the MIMEDefang host  reply  with  a  "User
418       unknown" SMTP response directly.  While this can be done by copying the
419       list of local users to the MIMEDefang machine, MIMEDefang has a  built-
420       in  function  called  md_check_against_smtp_server for querying another
421       relay host:
422
423
424       md_check_against_smtp_server($sender, $recip,  $helo,  $server,  $port)
425       This
426              function  connects  to  the  SMTP server $server and pretends to
427              send mail from $sender to $recip.  The return value is always  a
428              two-element array.  If the RCPT TO: command succeeds, the return
429              value is ("CONTINUE", "OK").  If the RCPT fails with a permanent
430              failure, the return value is ("REJECT", $msg), where $msg is the
431              message from the SMTP server.  Any temporary  failures,  connec‐
432              tion  errors,  etc.  result  in  a  return value of ("TEMPFAIL",
433              $msg).
434
435              The optional argument $port specifies the TCP  port  to  connect
436              to.   If it is not supplied, then the default SMTP port of 25 is
437              used.
438
439
440       Suppose the machine filter.domain.tld is filtering  mail  destined  for
441       the  real mail server mail.domain.tld.  You could have a filter_recipi‐
442       ent function like this:
443
444       sub filter_recipient
445       {
446           my($recip, $sender, $ip, $host, $first, $helo,
447              $rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
448           return md_check_against_smtp_server($sender, $recip,
449                                "filter.domain.tld",
450                                "mail.domain.tld");
451       }
452
453       For each RCPT TO: command,  MIMEDefang  opens  an  SMTP  connection  to
454       mail.domain.tld and checks if the command would succeed.
455
456
457       Please  note  that  you should only use md_check_against_smtp_server if
458       your mail server responds with a failure code for nonexistent users  at
459       the  RCPT  TO: level.  Also, this function may impose too much overhead
460       if you receive a lot of e-mail, and it will generate  lots  of  useless
461       log  entries  on  the  real  mail  server  (because of all the RCPT TO:
462       probes.)  It may also significantly increase the load on the real  mail
463       server.
464
465

GLOBAL VARIABLES YOU CAN SET

467       The following Perl global variables should be set in mimedefang-filter:
468
469
470       $AdminAddress
471              The e-mail address of the MIMEDefang administrator.
472
473
474       $DaemonAddress
475              The  e-mail  address  from which MIMEDefang-originated notifica‐
476              tions come.
477
478
479       $AddWarningsInline
480              If this variable is set to 0, then all MIMEDefang warnings (such
481              as created by action_quarantine or action_drop_with_warning) are
482              collected together and added in  a  separate  MIME  part  called
483              WARNING.TXT.  If the variable is set to 1, then the warnings are
484              added directly in the first text/plain and  text/html  parts  of
485              the  message.  If the message does not contain any text/plain or
486              text/html parts, then  a  WARNING.TXT  MIME  part  is  added  as
487              before.
488
489
490       $MaxMIMEParts
491              A  message  containing  many MIME parts can cause MIME::Tools to
492              consume large amounts of memory and bring  your  system  to  its
493              knees.  If you set $MaxMIMEParts to a positive number, then MIME
494              parsing is terminated for messages  with  more  than  that  many
495              parts,  and  the message is bounced.  In this case, none of your
496              filter functions is called.
497
498              By default, $MaxMIMEParts is set to  -1,  meaning  there  is  no
499              limit  on  the number of parts in a message.  Note that in order
500              to use this variable,  you  must  install  the  Roaring  Penguin
501              patched  version of MIME::Tools, version 5.411a-RP-Patched-02 or
502              newer.
503
504
505       $Stupidity{"NoMultipleInlines"}
506              Set this to 1 if your e-mail is too stupid to  display  multiple
507              MIME parts in-line.  In this case, a nasty hack causes the first
508              part of the original message to appear as an attachment if warn‐
509              ing  are issued.  Mail clients that are not this stupid are Net‐
510              scape Communicator and  Pine.   On  the  other  hand,  Microsoft
511              Exchange  and Microsoft Outlook are indeed this stupid.  Perhaps
512              users of those clients should switch.
513
514              The following global variables may optionally be set.   If  they
515              are not set, sensible defaults are used:
516
517
518       $AddApparentlyToForSpamAssassin
519              By default, MIMEDefang tries to pass SpamAssassin a message that
520              looks exactly like one it  would  receive  via  procmail.   This
521              means  adding  a Received: header, adding a Message-ID header if
522              necessary, and adding a Return-Path: header.  If you set $AddAp‐
523              parentlyToForSpamAssassin  to  1,  then  MIMEDefang also adds an
524              Apparently-To: header with all the  envelope  recipients  before
525              passing  the  message  to  SpamAssassin.  This lets SpamAssassin
526              detect possibly whitelisted recipient addresses.
527
528              The default value for $AddApparentlyToForSpamAssassin is 0.
529
530
531       $SyslogFacility
532              This specifies the logging facility used by  mimedefang.pl.   By
533              default, it is set to "mail", but you can set it to other possi‐
534              bilites.  See the openlog(3) man page for details.   You  should
535              name  facilities  as  all-lowercase  without the leading "LOG_".
536              That is, use "local3", not "LOG_LOCAL3".
537
538
539       $WarningLocation (default 0)
540              If set to 0 (the default), non-inline warnings are placed first.
541              If  you  want  the  warning at the end of the e-mail, set $Warn‐
542              ingLocation to -1.
543
544
545       $DaemonName (default "MIMEDefang")
546              The full name used when MIMEDefang sends out notifications.
547
548
549       $AdminName (default "MIMEDefang Administrator")
550              The full name of the MIMEDefang administrator.
551
552
553       $SALocalTestsOnly (default 1)
554              If set to 1, SpamAssassin calls will use only local tests.  This
555              is the default and recommended setting.  This disables Received,
556              RBL and Razor tests in an all or nothing fashion.  To use  Razor
557              this  MUST be set to 0.  You can add 'skip_rbl_checks 1' to your
558              SpamAssassin config file if you need to.
559
560
561       $NotifySenderSubject (default "MIMEDefang Notification")
562              The   subject   used   when    e-mail    is    sent    out    by
563              action_notify_sender().  If you set this, you should set it each
564              time you call action_notify_sender() to ensure consistency.
565
566       $NotifyAdministratorSubject (default "MIMEDefang Notification")
567              The subject used when e-mail is sent out by action_notify_admin‐
568              istrator().   If  you  set this, you should set it each time you
569              call action_notify_administrator() to ensure consistency.
570
571
572       $QuarantineSubject (default "MIMEDefang Quarantine Report")
573              The subject used when a quarantine notice is sent to the  admin‐
574              istrator.  If you set this, you should set it each time you call
575              action_quarantine() or action_quarantine_entire_message().
576
577
578       $NotifyNoPreamble (default 0)
579              Normally, notifications sent by  action_notify_sender()  have  a
580              preamble  warning  about  message  modifications.  If you do not
581              want this, set $NotifyNoPreamble to 1.
582
583
584       $CSSHost (default 127.0.0.1:7777:local)
585              Host and port for the Symantec CarrierScan Server virus scanner.
586              This takes the form ip_addr:port:local_or_nonlocal.  The ip_addr
587              and port are the host and port on which  CarrierScan  Server  is
588              listening.   If  you  want to scan local files, append :local to
589              force the use of the AVSCANLOCAL command.   If  the  CarrierScan
590              Server  is  on  another host, append :nonlocal to force the file
591              contents to be sent to the scanner over the socket.
592
593
594       $SophieSock (default /var/spool/MIMEDefang/sophie)
595              Socket  used  for  Sophie  daemon  calls   within   message_con‐
596              tains_virus_sophie  and  entity_contains_virus_sophie  unless  a
597              socket is provided by the calling routine.
598
599
600       $ClamdSock (default /var/spool/MIMEDefang/clamd.sock)
601              Socket  used  for  clamd  daemon   calls   within   message_con‐
602              tains_virus_clamd   and   entity_contains_virus_clamd  unless  a
603              socket is provided by the calling routine.
604
605
606       $TrophieSock (default /var/spool/MIMEDefang/trophie)
607              Socket  used  for  Trophie  daemon  calls  within   message_con‐
608              tains_virus_trophie  and  entity_contains_virus_trophie unless a
609              socket is provided by the calling routine.
610
611
612

FILTER

614       The heart of mimedefang-filter is the filter procedure.  See the  exam‐
615       ples  that came with MIMEDefang to learn to write a filter.  The filter
616       is called with the following arguments:
617
618
619       $entity
620              The MIME::Entity object.  (See the MIME::tools Perl module docu‐
621              mentation.)
622
623
624       $fname The suggested attachment filename, or "" if none was supplied.
625
626
627       $ext   The  file extension (all characters from the rightmost period to
628              the end of the filename.)
629
630
631       $type  The MIME type (for example, "text/plain".)
632
633
634       The filename is derived as follows:
635
636
637       o      First, if the Content-Disposition header has a "filename" field,
638              it is used.
639
640
641       o      Otherwise,  if the Content-Type header has a "name" field, it is
642              used.
643
644
645       o      Otherwise, the Content-Description header value is used.
646
647
648       Note that the truly paranoid will check all three fields  for  matches.
649       The  functions  re_match  and  re_match_ext  perform regular expression
650       matches on all three of the fields named above, and  return  1  if  any
651       field  matches.   See  the  sample  filters  for  details.  The calling
652       sequence is:
653
654            re_match($entity, "regexp")
655            re_match_ext($entity, "regexp")
656
657       re_match returns true if any of the fields matches the  regexp  without
658       regard  to  case.   re_match_ext  returns  true if the extension in any
659       field matches.  An extension is defined as the last dot in a  name  and
660       all remaining characters.
661
662
663       A  third function called re_match_in_zip_directory will look inside zip
664       files and return true if any of the file names inside the  zip  archive
665       match the regular expression.  Call it like this:
666
667            my $bh = $entity->bodyhandle();
668            my $path = (defined($bh)) ? $bh->path() : undef;
669            if (defined($path) and re_match_in_zip_directory($path, "regexp")) {
670                # Take action...
671            }
672
673       You  should not call re_match_in_zip_directory unless you know that the
674       entity is a zip file attachment.
675
676

GLOBAL VARIABLES SET BY MIMEDEFANG.PL

678       The following global variables are set by mimedefang.pl and are  avail‐
679       able  for use in your filter.  All of these variables are always avail‐
680       able to filter_begin,  filter,  filter_multipart  and  filter_end.   In
681       addition,  some of them are available in filter_relay, filter_sender or
682       filter_recipient.  If this is the case, it will be noted below.
683
684
685       %Features
686              This hash lets you determine at run-time whether  certain  func‐
687              tionality  is  available.   This  hash is available at all times
688              assuming the detect_and_load_perl_modules()  function  has  been
689              called.  The defined features are:
690
691              $Features{"SpamAssassin"}  is 1 if SpamAssassin 1.6 or better is
692              installed; 0 otherwise.
693
694              $Features{"HTMLCleaner"}   is   1   if   Anomy::HTMLCleaner   is
695              installed; 0 otherwise.
696
697              $Features{"HTML::Parser"}  is  1 if HTML::Parser is installed; 0
698              otherwise.
699
700              $Features{"Virus:FPROTD"} is currently always 0.  Set it to 1 in
701              your filter file if you have F-Risk's FPROTD scanner.
702
703              $Features{"Virus:SymantecCSS"} is currently always 0.  Set it to
704              1 in your filter file  if  you  have  the  Symantec  CarrierScan
705              Server virus scanner.
706
707              $Features{"Virus:NAI"}  is  the full path to NAI uvscan if it is
708              installed; 0 if it is not.
709
710              $Features{"Virus:BDC"} is the full path to Bitdefender bdc if it
711              is installed; 0 if it is not.
712
713              $Features{"Virus:NVCC"} is the full path to Norman Virus Control
714              nvcc if it is installed; 0 if it is not.
715
716              $Features{"Virus:HBEDV"} is the full path to H+BEDV  AntiVir  if
717              it is installed; 0 if it is not.
718
719              $Features{"Virus:VEXIRA"}  is  the  full path to Central Command
720              Vexira if it is installed; 0 if it is not.
721
722              $Features{"Virus:SOPHOS"} is the full path to Sophos sweep if it
723              is installed; 0 if it is not.
724
725              $Features{"Virus:SAVSCAN"} is the full path to Sophos savscan if
726              it is installed; 0 if it is not.
727
728              $Features{"Virus:CLAMAV"} is the full path to Clam  AV  clamscan
729              if it is installed; 0 if it is not.
730
731              $Features{"Virus:AVP"} is the full path to AVP AvpLinux if it is
732              installed; 0 if it is not.
733
734              $Features{"Virus:AVP5"} is the  full  path  to  Kaspersky  "ave‐
735              client" if it is installed; 0 if it is not.
736
737              $Features{"Virus:CSAV"}  is  the full path to Command csav if it
738              is installed; 0 if it is not.
739
740              $Features{"Virus:FSAV"} is the full path to F-Secure fsav if  it
741              is installed; 0 if it is not.
742
743              $Features{"Virus:FPROT"} is the full path to F-Risk f-prot if it
744              is installed; 0 if it is not.
745
746              $Features{"Virus:SOPHIE"} is the full path to Sophie  if  it  is
747              installed; 0 if it is not.
748
749              $Features{"Virus:CLAMD"}  is  the  full  path  to clamd if it is
750              installed; 0 if it is not.
751
752              $Features{"Virus:TROPHIE"} is the full path to Trophie if it  is
753              installed; 0 if it is not.
754
755              $Features{"Virus:NOD32"} is the full path to ESET NOD32 nod32cli
756              if it is installed; 0 if it is not.
757
758              NOTE: Perl-module based features (SpamAssassin and  HTMLCleaner)
759              are  determined at runtime and may change as these are added and
760              removed.  Most Virus features are predetermined at the  time  of
761              configuration  and  do  not adapt to runtime availability unless
762              changed by the filter rules.
763
764
765       $CWD   This variable holds the working directory for the  current  mes‐
766              sage.  During filter processing, mimedefang.pl chdir's into this
767              directory before calling any of  the  filter_  functions.   Note
768              that  this  variable  is set correctly in filter_sender and fil‐
769              ter_recipient, but not in filter_relay.
770
771
772       $SuspiciousCharsInHeaders
773              If this variable is true, then mimedefang has discovered  suspi‐
774              cious  characters  in message headers.  This might be an exploit
775              for bugs in MIME-parsing routines  in  some  badly-written  mail
776              user  agents  (e.g.  Microsoft Outlook.)  You should always drop
777              such messages.
778
779
780       $SuspiciousCharsInBody
781              If this variable is true, then mimedefang has discovered  suspi‐
782              cious  characters in the message body.  This might be an exploit
783              for bugs in MIME-parsing routines  in  some  badly-written  mail
784              user  agents  (e.g.  Microsoft Outlook.)  You should always drop
785              such messages.
786
787
788       $RelayHostname
789              The host name of the relay.  This is the name of the  host  that
790              is  attempting  to  send e-mail to your host.  May be "undef" if
791              the host name could not be determined.  This variable is  avail‐
792              able in filter_relay, filter_sender and filter_recipient.
793
794
795       $RelayAddr
796              The  IP  address of the sending relay (as a string consisting of
797              four dot-separated  decimal  numbers.)   One  potential  use  of
798              $RelayAddr is to limit mailing to certain lists to people within
799              your organization.  This variable is available in  filter_relay,
800              filter_sender and filter_recipient.
801
802
803       $Helo  The argument given to the SMTP "HELO" command.  This variable is
804              available in filter_sender and filter_recipient, but not in fil‐
805              ter_relay.
806
807
808       $Subject
809              The contents of the "Subject:" header.
810
811
812       $Sender
813              The sender of the e-mail.  This variable is set in filter_sender
814              and filter_recipient.
815
816
817       @Recipients
818              A list of the recipients.  In filter_recipient, it is set to the
819              single  recipient currently under consideration. Or, after call‐
820              ing  read_commands_file  within  filter_recipient,  the  current
821              recipient  under  consideration  is in the final position of the
822              array, at $Recipients[-1], while  any  previous  (and  accepted)
823              recipients  are  at  the  beginning  of  the  array, that is, in
824              @Recipients[0 .. $#Recipients-1].
825
826
827
828       $MessageID
829              The contents of the "Message-ID:"  header  if  one  is  present.
830              Otherwise, contains the string "NOQUEUE".
831
832
833       $QueueID
834              The Sendmail queue identifier if it could be determined.  Other‐
835              wise, contains the string "NOQUEUE". This variable is  set  cor‐
836              rectly  in  filter_sender  and  filter_recipient,  but it is not
837              available in filter_relay.
838
839
840       $MsgID Set to $QueueID if the queue ID could be determined;  otherwise,
841              set  to  $MessageID.  This identifier should be used in logging,
842              because it matches the identifier used by Sendmail to  log  mes‐
843              sages.   Note  that  this  variable  is  set  correctly  in fil‐
844              ter_sender and filter_recipient, but it is not available in fil‐
845              ter_relay.
846
847
848       $VirusScannerMessages
849              Each time a virus-scanning function is called, messages (if any)
850              from the virus scanner are accumulated in  this  variable.   You
851              can  use  it  in  filter_end to formulate a notification (if you
852              wish.)
853
854
855       $VirusName
856              If a virus-scanning function found a virus, this  variable  will
857              hold the virus name (if it could be determined.)
858
859
860       $SASpamTester
861              If  defined,  this  is  the configured Mail::SpamAssassin object
862              used for mail tests.  It may  be  initialized  with  a  call  to
863              spam_assassin_init which also returns it.
864
865
866       %SendmailMacros
867              This hash contains the values of some Sendmail macros.  The hash
868              elements exist only for macros defined  by  Sendmail.   See  the
869              Sendmail documentation for the meanings of the macros.
870
871              By  default,  mimedefang  passes  the  values  of  the following
872              macros: ${daemon_name},  ${if_name},  ${if_addr},  $j,  $_,  $i,
873              ${tls_version},   ${cipher},   ${cipher_bits},  ${cert_subject},
874              ${cert_issuer},   ${auth_type},   ${auth_authen},   ${auth_ssf},
875              ${auth_author}, ${mail_mailer}, ${mail_host} and ${mail_addr}.
876
877              If  any  macro  is  not  set or not passed to milter, it will be
878              unavailable.  To access the value of a macro, use:
879
880
881                   $SendmailMacros{"macro_name"}
882
883
884              Do not place curly brackets around the macro name.   This  vari‐
885              able  is available in filter_sender and filter_recipient after a
886              call to read_commands_file.
887
888
889       @SenderESMTPArgs
890              This array contains all the ESMTP arguments supplied in the MAIL
891              FROM: command.  For example:
892
893              sub print_sender_esmtp_args {
894                  foreach (@SenderESMTPArgs) {
895                      print STDERR "Sender ESMTP arg: $_0;
896                  }
897              }
898
899
900       %RecipientESMTPArgs
901              This hash contains all the ESMTP arguments supplied in each RCPT
902              TO: command.  For example:
903
904              sub print_recip_esmtp_args {
905                  foreach my $recip (@Recipients) {
906                      foreach(@{$RecipientESMTPArgs{$recip}}) {
907                          print STDERR "Recip ESMTP arg for $recip: $_0;
908                      }
909                  }
910              }
911
912
913       %RecipientMailers
914              This hash contains the Sendmail "mailer-host-address" triple for
915              each recipient.  Here's an example of how to use it:
916
917              sub print_mailer_info {
918                  my($recip, $mailer, $host, $addr);
919                  foreach $recip (@Recipients) {
920                      $mailer = ${RecipientMailers{$recip}}[0];
921                      $host = ${RecipientMailers{$recip}}[1];
922                      $addr =  ${RecipientMailers{$recip}}[2];
923                      print STDERR "$recip: mailer=$mailer, host=$host, addr=$addr\n";
924                  }
925              }
926
927              In  filter_recipient,  this  variable  by  default only contains
928              information on  the  recipient  currently  under  investigation.
929              Information   on  all  recipients  is  available  after  calling
930              read_commands_file.
931
932

ACTIONS

934       When the filter procedure decides how to dispose of a part,  it  should
935       call one or more action_ subroutines.  The action subroutines are:
936
937
938       action_accept()
939              Accept the part.
940
941
942       action_rebuild()
943              Rebuild the mail body, even if mimedefang thinks no changes were
944              made.  Normally, mimedefang does  not  alter  a  message  if  no
945              changes  were  made.   action_rebuild  may  be  used if you make
946              changes to entities directly (by  manipulating  the  MIME::Head,
947              for  example.)   Unless you call action_rebuild, mimedefang will
948              be unaware of the changes.  Note that all the built-in action...
949              routines that change a message implicitly call action_rebuild.
950
951
952       action_add_header($hdr, $val)
953              Add  a  header to the message.  This can be used in filter_begin
954              or filter_end.  The $hdr component is the  header  name  without
955              the  colon,  and  the $val is the header value.  For example, to
956              add the header:
957
958                   X-MyHeader: A nice piece of text
959
960              use:
961
962                   action_add_header("X-MyHeader", "A nice piece of text");
963
964
965       action_change_header($hdr, $val, $index)
966              Changes an existing header in the message. This can be  used  in
967              filter_begin  or  filter_end.   The $hdr parameter is the header
968              name without the colon, and $val is the header  value.   If  the
969              header  does  not  exist,  then a header with the given name and
970              value is added.
971
972              The $index parameter is optional; it defaults to 1.  If you sup‐
973              ply  it, then the $index'th occurrence of the header is changed,
974              if there is more than one header with the same name.   (This  is
975              common with the Received: header, for example.)
976
977
978       action_insert_header($hdr, $val, $index)
979              Add  a  header to the message int the specified position $index.
980              A position of 0 specifies that the header  should  be  prepended
981              before  existing  headers.   This can be used in filter_begin or
982              filter_end.  The $hdr component is the header name  without  the
983              colon, and the $val is the header value.
984
985
986       action_delete_header($hdr, $index)
987              Deletes  an  existing header in the message. This can be used in
988              filter_begin or filter_end.  The $hdr parameter  is  the  header
989              name without the colon.
990
991              The $index parameter is optional; it defaults to 1.  If you sup‐
992              ply it, then the $index'th occurrence of the header is  deleted,
993              if there is more than one header with the same name.
994
995
996       action_delete_all_headers($hdr)
997              Deletes  all  headers with the specified name.  This can be used
998              in filter_begin or filter_end.  The $hdr parameter is the header
999              name without the colon.
1000
1001
1002       action_drop()
1003              Drop  the part.  If called from filter_multipart, drops all con‐
1004              tained parts also.
1005
1006
1007       action_drop_with_warning($msg)
1008              Drop the part, but add the warning $msg to the  e-mail  message.
1009              If called from filter_multipart, drops all contained parts also.
1010
1011
1012       action_accept_with_warning($msg)
1013              Accept the part, but add the warning $msg to the e-mail message.
1014
1015
1016       action_replace_with_warning($msg)
1017              Drop  the  part and replace it with a text part $msg.  If called
1018              from filter_multipart, drops all contained parts also.
1019
1020
1021       action_replace_with_url($entity, $doc_root, $base_url, $msg, [$cd_data,
1022       $salt])
1023              Drop the part, but save it in a unique location under $doc_root.
1024              The part is replaced with the text  message  $msg.   The  string
1025              "_URL_"  in  $msg is replaced with $base_url/something, that can
1026              be used to retrieve the message.
1027
1028              You should not use this function in filter_multipart.
1029
1030              This action is intended for stripping large  parts  out  of  the
1031              message  and  replacing  them to a link on a Web server.  Here's
1032              how you would use it in filter():
1033
1034              $size = (stat($entity->bodyhandle->path))[7];
1035              if ($size > 1000000) {
1036                   return action_replace_with_url($entity,
1037                        "/home/httpd/html/mail_parts",
1038                        "http://mailserver.company.com/mail_parts",
1039                        "The attachment was larger than 1,000,000 bytes.\n" .
1040                        "It was removed, but may be accessed at this URL:\n\n" .
1041                        "\t_URL_\n");
1042              }
1043
1044              This example moves attachments greater than 1,000,000 bytes into
1045              /home/httpd/html/mail_parts  and replaces them with a link.  The
1046              directory  should  be   accessible   via   a   Web   server   at
1047              http://mailserver.company.com/mail_parts.
1048
1049              The  generated  name is created by performing a SHA1 hash of the
1050              part and adding the extension to the ASCII-HEX representation of
1051              the  hash.   If  many  different  e-mails are sent containing an
1052              identical large part, only one  copy  of  the  part  is  stored,
1053              regardless of the number of senders or recipients.
1054
1055              For  privacy  reasons,  you must turn off Web server indexing in
1056              the directory in which you place mail parts, or anyone  will  be
1057              able  to  read them.  If indexing is disabled, an attacker would
1058              have to guess the SHA1 hash of a part in order to read it.
1059
1060              Optionally, a fifth argument can supply data to be saved into  a
1061              hidden  dot filename based on the generated name.  This data can
1062              then be read in on the fly by a CGI script  or  mod_perl  module
1063              before  serving the file to a web client, and used to add infor‐
1064              mation to the response, such as Content-Disposition data.
1065
1066              A sixth optional argument, $salt, is mixed in to the SHA1  hash.
1067              This  salt  can  be  any string and should be kept confidential.
1068              The salt is designed to prevent people from guessing whether  or
1069              not  a particular attachment has been received on your server by
1070              altering the SHA1 hash calculation.
1071
1072
1073       action_defang($entity, $name, $fname, $type)
1074              Accept the part, but change its name  to  $name,  its  suggested
1075              filename  to  $fname  and  its  MIME type to $type.  If $name or
1076              $fname are "", then mimedefang.pl generates generic  names.   Do
1077              not use this action in filter_multipart.
1078
1079              If  you  use  action_defang, you must define a subroutine called
1080              defang_warning in your filter.  This  routine  takes  two  argu‐
1081              ments: $oldfname (the original name of an attachment) and $fname
1082              (the defanged version.)  It should return a message telling  the
1083              user what happened.  For example:
1084
1085              sub defang_warning {
1086                  my($oldfname, $fname) = @_;
1087                  return "The attachment '$oldfname' was renamed to '$fname'\n";
1088              }
1089
1090
1091
1092       action_external_filter($entity, $cmd)
1093              Run  an  external UNIX command $cmd.  This command must read the
1094              part from the file ./FILTERINPUT and leave the result in  ./FIL‐
1095              TEROUTPUT.   If  the  command  executes successfully, returns 1,
1096              otherwise 0.  You can test the return  value  and  call  another
1097              action_  if  the  filter failed.  Do not use this action in fil‐
1098              ter_multipart.
1099
1100
1101       action_quarantine($entity, $msg)
1102              Drop and quarantine the part, but add the warning $msg to the e-
1103              mail message.
1104
1105
1106       action_quarantine_entire_message($msg)
1107              Quarantines  the entire message in a quarantine directory on the
1108              mail server, but does not otherwise affect  disposition  of  the
1109              message.  If "$msg" is non-empty, it is included in any adminis‐
1110              trator notification.
1111
1112
1113       action_sm_quarantine($reason)
1114              Quarantines a message in the Sendmail mail queue using  the  new
1115              QUARANTINE facility of Sendmail 8.13.  Consult the Sendmail doc‐
1116              umentation  for  details  about  this  facility.   If  you   use
1117              action_sm_quarantine  with  a version of Sendmail that lacks the
1118              QUARANTINE facility, mimedefang will log an  error  message  and
1119              not quarantine the message.
1120
1121
1122       action_bounce($reply, $code, $dsn)
1123              Reject  the entire e-mail message with an SMTP failure code, and
1124              the one-line error message $reply.  If the  optional  $code  and
1125              $dsn  arguments  are  supplied,  they specify the numerical SMTP
1126              reply code and the extended status  code  (DSN  code).   If  the
1127              codes  you  supply  do  not  make  sense  for a bounce, they are
1128              replaced with "554" and "5.7.1" respectively.
1129
1130              action_bounce merely makes a note that  the  message  is  to  be
1131              bounced;  remaining parts are still processed.  If action_bounce
1132              is called for more than one part, the mail is bounced  with  the
1133              message  in the final call to action_bounce.  You can profitably
1134              call action_quarantine followed by action_bounce if you want  to
1135              keep a copy of the offending part.  Note that the message is not
1136              bounced immediately; rather, remaining parts are  processed  and
1137              the message is bounced after all parts have been processed.
1138
1139              Note  that  despite  its name, action_bounce does not generate a
1140              "bounce message".  It merely rejects the message  with  an  SMTP
1141              failure code.
1142
1143              WARNING: action_bounce() may cause the sending relay to generate
1144              spurious bounce messages if the sender address is  faked.   This
1145              is  a particular problem with viruses.  However, we believe that
1146              on balance, it's better to bounce a virus than to silently  dis‐
1147              card it.  It's almost never a good idea to hide a problem.
1148
1149
1150       action_tempfail($msg, $code, $dsn)
1151              Cause  an  SMTP  "temporary failure" code to be returned, so the
1152              sending mail relay requeues the message and tries  again  later.
1153              The  message  $msg  is included with the temporary failure code.
1154              If the optional $code and  $dsn  arguments  are  supplied,  they
1155              specify  the  numerical  SMTP reply code and the extended status
1156              code (DSN code).  If the codes you supply do not make sense  for
1157              a  temporary  failure,  they are replaced with "450" and "4.7.1"
1158              respectively.
1159
1160
1161       action_discard()
1162              Silently discard the message, notifying nobody.  You  can  prof‐
1163              itably  call action_quarantine followed by action_discard if you
1164              want to keep a copy of the offending part.  Note that  the  mes‐
1165              sage  is  not discarded immediately; rather, remaining parts are
1166              processed and the message is discarded after all parts have been
1167              processed.
1168
1169
1170       action_notify_sender($message)
1171              This action sends an e-mail back to the original sender with the
1172              indicated message.  You may call another action after this  one.
1173              If  action_notify_sender  is called more than once, the messages
1174              are accumulated into a single e-mail  message  --  at  most  one
1175              notification  message is sent per incoming message.  The message
1176              should be terminated with a newline.
1177
1178              The notification is delivered in deferred mode; you should run a
1179              client-queue runner if you are using Sendmail 8.12.
1180
1181              NOTE:  Viruses  often fake the sender address.  For that reason,
1182              if a virus-scanner has detected a virus, action_notify_sender is
1183              disabled  and will simply log an error message if you try to use
1184              it.
1185
1186
1187       action_notify_administrator($message)
1188              This action e-mails the MIMEDefang  administrator  the  supplied
1189              message.    You   may   call  another  action  after  this  one;
1190              action_notify_administrator does not affect mail processing.  If
1191              action_notify_administrator  is  called more than once, the mes‐
1192              sages are accumulated into a single e-mail message  --  at  most
1193              one notification message is sent per incoming message.  The mes‐
1194              sage should be terminated with a newline.
1195
1196              The notification is delivered in deferred mode; you should run a
1197              client-queue runner if you are using Sendmail 8.12.
1198
1199
1200       anomy_clean_html($entity, {"name" => val , ...})
1201              If   you  have  the  Anomy  mail  cleaning  tools  (http://mail
1202              tools.anomy.net) and have installed the Anomy modules in a stan‐
1203              dard  Perl include directory, this function uses an Anomy::HTML‐
1204              Cleaner object to sanitize  the  HTML  code  in  $entity,  which
1205              assumed  to  be  of type text/html.  The configuration arguments
1206              are optional; possible values are documented in comments in  the
1207              Anomy/HTMLCleaner.pm Perl module.
1208
1209
1210       append_text_boilerplate($entity, $boilerplate, $all)
1211              This  action  should only be called from filter_end.  It appends
1212              the text "\n$boilerplate\n" to the  first  text/plain  part  (if
1213              $all is 0) or to all text/plain parts (if $all is 1).
1214
1215
1216       append_html_boilerplate($entity, $boilerplate, $all)
1217              This  action should only be called from filter_end.  It adds the
1218              text "\n$boilerplate\n" to the first text/html part (if $all  is
1219              0)  or  to  all  text/html  parts (if $all is 1).  This function
1220              tries to be smart  about  inserting  the  boilerplate;  it  uses
1221              HTML::Parser  to detect closing tags and inserts the boilerplate
1222              before the </body> tag if there is one, or  before  the  </html>
1223              tag  if  there is no </body>.  If there is no </body> or </html>
1224              tag, it appends the boilerplate to the end of the part.
1225
1226              Do not use append_html_boilerplate unless you have installed the
1227              HTML::Parser Perl module.
1228
1229              Here is an example illustrating how to use the boilerplate func‐
1230              tions:
1231
1232                   sub filter_end {
1233                        my($entity) = @_;
1234                        append_text_boilerplate($entity,
1235                             "Lame text disclaimer", 0);
1236                        append_html_boilerplate($entity,
1237                             "<em>Lame</em> HTML disclaimer", 0);
1238                   }
1239
1240
1241       action_add_part($entity, $type, $encoding, $data, $fname,  $disposition
1242       [, $offset])
1243              This  action  should only be called from the filter_end routine.
1244              It adds a new part to the message, converting the original  mes‐
1245              sage to mutipart if necessary.  The function returns the part so
1246              that additional mime attributes may be set  on  it.   Here's  an
1247              example:
1248
1249                   sub filter_end {
1250                        my($entity) = @_;
1251
1252                        action_add_part($entity, "text/plain", "-suggest",
1253                                  "This e-mail does not represent" .
1254                                  "the official policy of FuBar, Inc.\n",
1255                                  "disclaimer.txt", "inline");
1256                      }
1257
1258              The  $entity  parameter  must  be the argument passed in to fil‐
1259              ter_end.  The $offset parameter  is  optional;  if  omitted,  it
1260              defaults  to  -1,  which  adds the new part at the end.  See the
1261              MIME::Entity man page and the add_part member function  for  the
1262              meaning of $offset.
1263
1264              Note that action_add_part tries to be more intelligent than sim‐
1265              ply calling $entity->add_part.  The decision process is as  fol‐
1266              lows:
1267
1268
1269       o      If  the  top-level  entity  is multipart/mixed, then the part is
1270              simply added.
1271
1272
1273       o      Otherwise, a new top-level multipart/mixed container  is  gener‐
1274              ated,  and  the original top-level entity is made the first part
1275              of the multipart/mixed container.  The new part is then added to
1276              the multipart/mixed container.
1277
1278

USEFUL ROUTINES

1280       mimedefang.pl  includes  some  useful  functions you can call from your
1281       filter:
1282
1283
1284       detect_and_load_perl_modules()
1285              Unless you really know what you're doing, this function must  be
1286              called first thing in your filter file.  It causes mimedefang.pl
1287              to detect and load  Perl  modules  such  as  Mail::SpamAssassin,
1288              Net::DNS, etc., and to populate the %Features hash.
1289
1290
1291       send_quarantine_notifications()
1292              This  function  should  be called from filter_end.  If any parts
1293              were quarantined, a  quarantine  notification  is  sent  to  the
1294              MIMEDefang  administrator.   Please note that if you do not call
1295              send_quarantine_notifications, then no quarantine  notifications
1296              are sent.
1297
1298
1299       get_quarantine_dir()
1300              This  function  returns  the  full  path  name of the quarantine
1301              directory.  If you have not yet quarantined  any  parts  of  the
1302              message,  a  quarantine  directory  is  created and its pathname
1303              returned.
1304
1305
1306       change_sender($sender)
1307              This function changes the envelope sender to  $sender.   It  can
1308              only  be called from filter_begin or any later function.  Please
1309              note that this function is only supported  with  Sendmail/Milter
1310              8.14.0  or newer.  It has no effect if you're running older ver‐
1311              sions.
1312
1313
1314       add_recipient($recip)
1315              This function adds $recip to the list of envelope recipients.  A
1316              copy of the message (after any modifications by MIMEDefang) will
1317              be sent to $recip in addition to the original recipients.   Note
1318              that  add_recipient  does  not  modify the @Recipients array; it
1319              just makes a note to Sendmail to add the recipient.
1320
1321
1322       delete_recipient($recip)
1323              This function deletes $recip from the list of recipients.   That
1324              person  will  not  receive  a  copy  of the mail.  $recip should
1325              exactly  match  an  entry   in   the   @Recipients   array   for
1326              delete_recipient() to work.  Note that delete_recipient does not
1327              modify the @Recipients array; it just makes a note  to  Sendmail
1328              to delete the recipient.
1329
1330       resend_message($recip1, $recip2, ...)
1331              or
1332
1333       resend_message(@recips)
1334              This  function immediately resends the original, unmodified mail
1335              message to each of the named recipients.  The  sender's  address
1336              is preserved.  Be very careful when using this function, because
1337              it resends the original message,  which  may  contain  undesired
1338              attachments.   Also, you should not call this function from fil‐
1339              ter(), because it resends the message each time  it  is  called.
1340              This  may  result  in  multiple copies being sent if you are not
1341              careful.  Call from filter_begin() or filter_end() to be safe.
1342
1343              The function returns true on success, or false if it fails.
1344
1345              Note that the  resend_message  function  delivers  the  mail  in
1346              deferred  mode  (using  Sendmail's "-odd" flag.)  You must run a
1347              client-submission queue processor if you use Sendmail 8.12.   We
1348              recommend executing this command as part of the Sendmail startup
1349              sequence:
1350
1351                   sendmail -Ac -q5m
1352
1353
1354       remove_redundant_html_parts($entity)
1355              This function should only be called from filter_end.  It removes
1356              redundant HTML parts from the message.  It works by deleting any
1357              part of type text/html from the message if (1) it is a  sub-part
1358              of  a  multipart/alternative part, and (2) there is another part
1359              of type text/plain under the multipart/alternative part.
1360
1361
1362       replace_entire_message($entity)
1363              This function can only be called from filter_end.   It  replaces
1364              the  entire message with $entity, a MIME::Entity object that you
1365              have constructed.  You can use any of the MIME::Tools  functions
1366              to construct the entity.
1367
1368
1369       read_commands_file()
1370              This  function should only be called from filter_sender and fil‐
1371              ter_recipient. This will read the COMMANDS file (as described in
1372              mimedefang-protocol(7)),  and  will fill or update the following
1373              global  variables:  $Sender,   @Recipients,   %RecipientMailers,
1374              $RelayAddr,  $RealRelayAddr, $RelayHostname, $RealRelayHostname,
1375              $QueueID, $Helo, %SendmailMacros.
1376
1377              If you do not call read_commands_file, then the only information
1378              available in filter_sender and filter_recipient is that which is
1379              passed as an argument to the function.
1380
1381
1382       stream_by_domain()
1383              Do not use this function  unless  you  have  Sendmail  8.12  and
1384              locally- submitted e-mail is submitted using SMTP.
1385
1386              This  function  should  only  be called at the very beginning of
1387              filter_begin(), like this:
1388
1389                   sub filter_begin {
1390                        if (stream_by_domain()) {
1391                             return;
1392                        }
1393                        # Rest of filter_begin
1394                   }
1395
1396              stream_by_domain() looks at all the recipients of  the  message,
1397              and  if  they  belong  to the same domain (e.g., joe@domain.com,
1398              jane@domain.com and sue@domain.com), it returns 0 and  sets  the
1399              global  variable $Domain to the domain (domain.com in this exam‐
1400              ple.)
1401
1402              If users are in different  domains,  stream_by_domain()  resends
1403              the  message (once to each domain) and returns 1 For example, if
1404              the  original  recipients  are  joe@abc.net,  jane@xyz.net   and
1405              sue@abc.net,  the  original message is resent twice: One copy to
1406              joe@abc.net and sue@abc.net, and another copy  to  jane@xyz.net.
1407              Also,  any  subsequent  scanning  is canceled (filter() and fil‐
1408              ter_end() will not be called for the original message)  and  the
1409              message is silently discarded.
1410
1411              If  you  have Sendmail 8.12, then locally-submitted messages are
1412              sent via SMTP, and MIMEDefang will be  called  for  each  resent
1413              message.  It is possible to set up Sendmail 8.12 so locally-sub‐
1414              mitted  messages  are  delivered   directly;   in   this   case,
1415              stream_by_domain will not work.
1416
1417              Using stream_by_domain allows you to customize your filter rules
1418              for each domain.  If you use the function  as  described  above,
1419              you can do this in your filter routine:
1420
1421                   sub filter {
1422                        my($entity, $fname, $ext, $type) = @_;
1423                        if ($Domain eq "abc.com") {
1424                             # Filter actions for abc.com
1425                        } elsif ($Domain eq "xyz.com") {
1426                             # Filter actions for xyz.com
1427                        } else {
1428                             # Default filter actions
1429                        }
1430                   }
1431
1432              You  cannot  rely  on  $Domain  being set unless you have called
1433              stream_by_domain().
1434
1435
1436       stream_by_recipient()
1437              Do not use this function  unless  you  have  Sendmail  8.12  and
1438              locally- submitted e-mail is submitted using SMTP.
1439
1440              This  function  should  only  be called at the very beginning of
1441              filter_begin(), like this:
1442
1443                   sub filter_begin {
1444                        if (stream_by_recipient()) {
1445                             return;
1446                        }
1447                        # Rest of filter_begin
1448                   }
1449
1450              If there  is  more  than  one  recipient,  stream_by_recipient()
1451              resends  the  message once to each recipient.  That way, you can
1452              customize your filter rules on a per-recipient basis.  This  may
1453              increase the load on your mail server considerably.
1454
1455              Also,  a  "recipient"  is determined before alias expansion.  So
1456              "all@mydomain.com" is considered a  single  recipient,  even  if
1457              Sendmail delivers to a list.
1458
1459              If  you  have Sendmail 8.12, then locally-submitted messages are
1460              sent via SMTP, and MIMEDefang will be  called  for  each  resent
1461              message.  It is possible to set up Sendmail 8.12 so locally-sub‐
1462              mitted  messages  are  delivered   directly;   in   this   case,
1463              stream_by_recipient() will not work.
1464
1465              stream_by_recipient()  allows you to customize your filter rules
1466              for each recipient in a manner similar to stream_by_domain().
1467
1468

LOGGING

1470       md_graphdefang_log_enable($facility, $enum_recips)
1471              Enables the md_graphdefang_log function (described  next).   The
1472              function  logs  to  syslog using the specified facility.  If you
1473              omit $facility, it defaults to  'mail'.   If  you  do  not  call
1474              md_graphdefang_log_enable  in  your  filter,  then  any calls to
1475              md_graphdefang_log simply do nothing.
1476
1477              If you supply $enum_recips as 1, then a line of logging is  out‐
1478              put  for  each recipient of a mail message.  If it is zero, then
1479              only a single line is output for  each  message.   If  you  omit
1480              $enum_recips, it defaults to 1.
1481
1482
1483       md_graphdefang_log($event, $v1, $v2)
1484              Logs  an  event  with  up to two optional additional parameters.
1485              The log message has a specific format useful for graphing tools;
1486              the message looks like this:
1487
1488                   MDLOG,msgid,event,v1,v2,sender,recipient,subj
1489
1490              "MDLOG"  is literal text.  "msgid" is the Sendmail queue identi‐
1491              fier.  "event" is the event name, and  "v1"  and  "v2"  are  the
1492              additional parameters.  "sender" is the sender's e-mail address.
1493              "recipient" is the recipient's e-mail address, and "subj" is the
1494              message  subject.   If  a  message  has more than one recipient,
1495              md_graphdefang_log may log an event message for each  recipient,
1496              depending on how you called md_graphdefang_log_enable.
1497
1498              Note that md_graphdefang_log should not be used in filter_relay,
1499              filter_sender or  filter_recipient.   The  global  variables  it
1500              relies on are not valid in that context.
1501
1502              If  you want to log general text strings, do not use md_graphde‐
1503              fang_log.  Instead, use md_syslog (described next).
1504
1505
1506       md_syslog($level, $msg)
1507              Logs the message $msg to syslog, using level $level.  The  level
1508              is a literal string, and should be one of 'err', 'debug', 'warn‐
1509              ing', ´emerg', 'crit', 'notice' or 'info'.  (See  syslog(3)  for
1510              details.)
1511
1512              Note  that  md_syslog  does not perform %-subsitutions like sys‐
1513              log(3) does.  Depending on  your  Perl  installation,  md_syslog
1514              boils  down  to  a  call  to  Unix::Syslog::syslog  or Sys::Sys‐
1515              log::syslog.  See the Unix::Syslog or Sys::Syslog man pages  for
1516              more details.
1517
1518
1519       md_openlog($tag, $facility)
1520              Sets the tag used in syslog messages to $tag, and sends the logs
1521              to the $facility facility.  If you do not call md_openlog before
1522              you  call  md_syslog, then it is called implicitly with $tag set
1523              to mimedefang.pl and $facility set to mail.
1524
1525

RBL LOOKUP FUNCTIONS

1527       mimedefang.pl includes  the  following  functions  for  looking  up  IP
1528       addresses in DNS-based real-time blacklists.
1529
1530
1531       relay_is_blacklisted($relay, $domain)
1532              This  checks  a  DNS-based real-time spam blacklist, and returns
1533              true if the relay host is blacklisted, or false otherwise.   (In
1534              fact,  the  return  value is whatever the blacklist returns as a
1535              resolved hostname, such as "127.0.0.4")
1536
1537              Note that relay_is_blacklisted uses the  built-in  gethostbyname
1538              function;  this is usually quite inefficient and does not permit
1539              you to set a timeout on the lookup.  Instead, we recommend using
1540              one  of the other DNS lookup function described in this section.
1541              (Note,  though,  that  the  other  functions  require  the  Perl
1542              Net::DNS module, whereas relay_is_blacklisted does not.)
1543
1544              Here's an example of how to use relay_is_blacklisted:
1545
1546                   if (relay_is_blacklisted($RelayAddr, "rbl.spamhaus.org")) {
1547                        action_add_header("X-Blacklist-Warning",
1548                               "Relay $RelayAddr is blacklisted by Spamhaus");
1549                   }
1550
1551
1552       relay_is_blacklisted_multi($relay,      $timeout,      $answers_wanted,
1553       [$domain1, $domain2, ...], $res)
1554              This function is similar to relay_is_blacklisted, except that it
1555              takes  a timeout argument (specified in seconds) and an array of
1556              domains to check.  The function checks all domains in  parallel,
1557              and  is guaranteed to return in $timeout seconds.  (Actually, it
1558              may take up to one second longer.)
1559
1560              The parameters are:
1561
1562              $relay -- the IP address you want to look up
1563
1564              $timeout -- a timeout in seconds after which the function should
1565              return
1566
1567              $answers_wanted  --  the  maximum number of positive answers you
1568              care about.  For example, if you're looking up an address in  10
1569              different  RBLs,  but are going to bounce it if it is on four or
1570              more, you can set $answers_wanted to 4, and the function returns
1571              as   soon   as   four   "hits"   are  discovered.   If  you  set
1572              $answers_wanted to zero,  then  the  function  does  not  return
1573              early.
1574
1575              [$domain1, $domain2, ...] -- a reference to an array of strings,
1576              where each string is an RBL domain.
1577
1578              $res -- a Net::DNS::Resolver object.  This argument is optional;
1579              if  you  do  not supply it, then relay_is_blacklisted_multi con‐
1580              structs its own resolver.
1581
1582              The return value is a reference to a hash; the keys of the  hash
1583              are  the  original  domains,  and  the  corresponding values are
1584              either SERVFAIL, NXDOMAIN, or a list of IP addresses in  dotted-
1585              quad notation.
1586
1587              Here's an example:
1588
1589                  $ans = relay_is_blacklisted_multi($RelayAddr, 8, 0,
1590                      ["sbl.spamhaus.org", "relays.ordb.org"]);
1591
1592                  foreach $domain (keys(%$ans)) {
1593                      $r = $ans->{$domain};
1594                      if (ref($r) eq "ARRAY") {
1595                          # It's an array -- it IS listed in RBL
1596                          print STDERR "Lookup in $domain yields [ ";
1597                          foreach $addr (@$r) {
1598                              print STDERR $addr . " ";
1599                          }
1600                          print STDERR "]\n";
1601                      } else {
1602                          # It is NOT listed in RBL
1603                          print STDERR "Lookup in $domain yields "
1604                                       . $ans->{$domain} . "\n";
1605                      }
1606                  }
1607
1608              You  should  compare  each  of $ans->{$domain} to "SERVFAIL" and
1609              "NXDOMAIN" to see if the relay is not listed.  Any other  return
1610              value will be an array of IP addresses indicating that the relay
1611              is listed.
1612
1613              Any lookup that does not succeed within $timeout seconds has the
1614              corresponding return value set to SERVFAIL.
1615
1616
1617       relay_is_blacklisted_multi_list($relay,    $timeout,   $answers_wanted,
1618       [$domain1, $domain2, ...], $res)
1619              This function is similar  to  relay_is_blacklisted_multi  except
1620              that the return value is simply an array of RBL domains in which
1621              the relay was listed.
1622
1623
1624       relay_is_blacklisted_multi_count($relay,   $timeout,   $answers_wanted,
1625       [$domain1, $domain2, ...], $res)
1626              This  function  is  similar to relay_is_blacklisted_multi except
1627              that the return value is an integer  specifying  the  number  of
1628              domains on which the relay was blacklisted.
1629
1630
1631       md_get_bogus_mx_hosts($domain)
1632              This function is not really an RBL lookup.  What it does is look
1633              up all the MX records for the specified  domain,  and  return  a
1634              list  of  "bogus"  IP addresses found amongst the MX records.  A
1635              "bogus" IP address  is  an  IP  address  in  a  private  network
1636              (10.0.0.0/8,  172.16.0.0/12,  192.168.0.0/16), the loopback net‐
1637              work (127.0.0.0/8), local-link for  auto-DHCP  (169.254.0.0/16),
1638              IPv4 multicast (224.0.0.0/4) or reserved (240.0.0.0/4).
1639
1640
1641       Here's how you might use the function in filter_sender:
1642
1643       sub filter_sender {
1644           my ($sender, $ip, $hostname, $helo) = @_;
1645           if ($sender =~ /@([^>]+)/) {
1646               my $domain = $1;
1647               my @bogushosts = md_get_bogus_mx_hosts($domain);
1648               if (scalar(@bogushosts)) {
1649                   return('REJECT', "Domain $domain contains bogus MX record(s) " .
1650                          join(', ', @bogushosts));
1651               }
1652           }
1653           return ('CONTINUE', 'ok');
1654       }
1655
1656

TEST FUNCTIONS

1658       mimedefang.pl includes some "test" functions:
1659
1660
1661       md_version()
1662              returns  the  version  of  MIMEDefang  as a string (for example,
1663              "2.64").
1664
1665
1666       message_rejected()
1667              Returns  true  if  any  of  action_tempfail,  action_bounce   or
1668              action_discard  have been called for this message; returns false
1669              otherwise.
1670
1671
1672       If  you  have  the  Mail::SpamAssassin  Perl  module   installed   (see
1673       http://www.spamassassin.org)  you  may  call any of the spam_assassin_*
1674       functions.  They should only be called from filter_begin or  filter_end
1675       because they operate on the entire message at once.  Most functions use
1676       an optionally provided config file.  If no  config  file  is  provided,
1677       mimedefang.pl will look for one of four default SpamAssassin preference
1678       files.  The first of the following found will be used:
1679
1680
1681       o      /etc/mail/sa-mimedefang.cf
1682
1683       o      /etc/mail/spamassassin/sa-mimedefang.cf
1684
1685       o      /etc/mail/spamassassin/local.cf
1686
1687       o      /etc/mail/spamassassin.cf
1688
1689
1690       Important Note:  MIMEDefang does not permit SpamAssassin to modify mes‐
1691       sages.   If you want to tag spam messages with special headers or alter
1692       the subject line, you must use MIMEDefang functions to do it.   Setting
1693       SpamAssassin configuration options to alter messages will not work.
1694
1695
1696       spam_assassin_is_spam([ $config_file ])
1697              Determine  if  the  current message is SPAM/UCE as determined by
1698              SpamAssassin.  Compares the score of  the  message  against  the
1699              threshold  score  (see  below)  and returns true if it is.  Uses
1700              spam_assassin_check below.
1701
1702
1703       spam_assassin_check([ $config_file ])
1704              This function returns a four-element list of  the  form  ($hits,
1705              $required,  $tests, $report).  $hits is the "score" given to the
1706              message by SpamAssassin (higher score means more  likely  SPAM).
1707              $required  is  the  number  of hits required before SpamAssassin
1708              concludes that the message is SPAM.  $tests is a comma-separated
1709              list  of  SpamAssassin test names, and $report is text detailing
1710              which tests triggered and their point  score.   This  gives  you
1711              insight  into  why  SpamAssassin  concluded  that the message is
1712              SPAM.  Uses spam_assassin_status below.
1713
1714
1715       spam_assassin_status([ $config_file ])
1716              This function returns a Mail::SpamAssasin::PerMsgStatus  object.
1717              Read  the  SpamAssassin  documentation  for  details  about this
1718              object.  You are responsible for calling the finish method  when
1719              you  are  done with it.  Uses spam_assassin_init and spam_assas‐
1720              sin_mail below.
1721
1722
1723       spam_assassin_init([ $config_file ])
1724              This function returns the new global  Mail::SpamAssassin  object
1725              with  the  specified or default config (outlined above).  If the
1726              global object is already defined, returns it -- does not  change
1727              config  files!   The object can be used to perform other SpamAs‐
1728              sassin related functions.
1729
1730
1731       spam_assassin_mail()
1732              This function returns a  Mail::SpamAssassin::NoMailAudit  object
1733              with  the current email message contained in it.  It may be used
1734              to perform other SpamAssassin related functions.
1735
1736
1737       md_copy_orig_msg_to_work_dir()
1738              Normally, virus-scanners are passed only the  unpacked,  decoded
1739              parts  of  a  MIME  message.   If you want to pass the original,
1740              undecoded message in as well, call  md_copy_orig_msg_to_work_dir
1741              prior to calling message_contains_virus.
1742
1743
1744       md_copy_orig_msg_to_work_dir_as_mbox_file()
1745              Normally,  virus-scanners  are passed only the unpacked, decoded
1746              parts of a MIME message.  If you  want  to  pass  the  original,
1747              undecoded   message   in  as  a  UNIX-style  "mbox"  file,  call
1748              md_copy_orig_msg_to_work_dir_as_mbox_file prior to calling  mes‐
1749              sage_contains_virus.   The only difference between this function
1750              and md_copy_orig_msg_to_work_dir is that this function  prepends
1751              a  "From_"  line to make the message look like a UNIX-style mbox
1752              file.  This is required for some virus scanners  (such  as  Clam
1753              AntiVirus) to recognize the file as an e-mail message.
1754
1755
1756       message_contains_virus()
1757              This function runs every installed virus-scanner and returns the
1758              scanner results.  The function should be called in list context;
1759              the  return  value  is  a  three-element list ($code, $category,
1760              $action).
1761
1762              $code is the actual return code from the virus scanner.
1763
1764              $category is a string categorizing the return code:
1765
1766              "ok" - no viruses detected.
1767
1768              "not-installed" - indicated virus scanner is not installed.
1769
1770              "cannot-execute" - for some reason, the  scanner  could  not  be
1771              executed.
1772
1773              "virus" - a virus was found.
1774
1775              "suspicious" - a "suspicious" file was found.
1776
1777              "interrupted" - scanning was interrupted.
1778
1779              "swerr" - an internal scanner software error occurred.
1780
1781              $action is a string containing the recommended action:
1782
1783              "ok" - allow the message through unmolested.
1784
1785              "quarantine" - a virus was detected; quarantine it.
1786
1787              "tempfail" - something went wrong; tempfail the message.
1788
1789
1790
1791       message_contains_virus_trend()
1792
1793       message_contains_virus_nai()
1794
1795       message_contains_virus_bdc()
1796
1797       message_contains_virus_nvcc()
1798
1799       message_contains_virus_csav()
1800
1801       message_contains_virus_fsav()
1802
1803       message_contains_virus_hbedv()
1804
1805       message_contains_virus_vexira()
1806
1807       message_contains_virus_sophos()
1808
1809       message_contains_virus_clamav()
1810
1811       message_contains_virus_avp()
1812
1813       message_contains_virus_avp5()
1814
1815       message_contains_virus_fprot()
1816
1817       message_contains_virus_fprotd()
1818
1819       message_contains_virus_nod32()
1820
1821              These  functions should be called in list context.  They use the
1822              indicated anti-virus software to scan the message  for  viruses.
1823              These  functions  are intended for use in filter_begin() to make
1824              an initial scan of the e-mail message.
1825
1826              The supported virus scanners are:
1827
1828       nai    NAI "uvscan" - http://www.nai.com/
1829
1830       Bitdefender "bdc" - http://www.bitdefender.com/
1831
1832       csav   Command Anti-Virus - http://www.commandsoftware.com/
1833
1834       fsav   F-Secure Anti-Virus - http://www.f-secure.com/
1835
1836       hbedv  H+BEDV "AntiVir" - http://www.hbedv.com/
1837
1838       vexira Vexira "Vexira" - http://www.centralcommand.com/
1839
1840       sophos Sophos AntiVirus - http://www.sophos.com/
1841
1842       avp    Kaspersky AVP and aveclient (AVP5) - http://www.avp.ru/
1843
1844       clamav Clam AntiVirus - http://www.clamav.net/
1845
1846       f-prot F-RISK F-PROT - http://www.f-prot.com/
1847
1848       nod32cli
1849              ESET NOD32 - http://www.eset.com/
1850
1851
1852       message_contains_virus_carrier_scan([$host])
1853              Connects to the specified  host:port:local_or_nonlocal  (default
1854              $CSSHost),  where  the  Symantec  CarrierScan  Server  daemon is
1855              expected to be listening.  Return values are  the  same  as  the
1856              other message_contains_virus functions.
1857
1858
1859       message_contains_virus_sophie([$sophie_sock])
1860              Connects  to  the  specified socket (default $SophieSock), where
1861              the Sophie daemon is expected to be  listening.   Return  values
1862              are the same as the other message_contains_virus functions.
1863
1864
1865       message_contains_virus_clamd([$clamd_sock])
1866              Connects to the specified socket (default $ClamdSock), where the
1867              clamd daemon is expected to be listening.  Return values are the
1868              same as the other message_contains_virus functions.
1869
1870
1871       message_contains_virus_trophie([$trophie_sock])
1872              Connects  to  the specified socket (default $TrophieSock), where
1873              the Trophie daemon is expected to be listening.   Return  values
1874              are the same as the other message_contains_virus functions.
1875
1876
1877       entity_contains_virus($entity)
1878
1879              This  function  runs  the  specified  MIME::Entity through every
1880              installed virus-scanner and returns the  scanner  results.   The
1881              return values are the same as for message_contains_virus().
1882
1883
1884       entity_contains_virus_trend($entity)
1885
1886       entity_contains_virus_nai($entity)
1887
1888       entity_contains_virus_bdc($entity)
1889
1890       entity_contains_virus_nvcc($entity)
1891
1892       entity_contains_virus_csav($entity)
1893
1894       entity_contains_virus_fsav($entity)
1895
1896       entity_contains_virus_hbedv($entity)
1897
1898       entity_contains_virus_sophos($entity)
1899
1900       entity_contains_virus_clamav($entity)
1901
1902       entity_contains_virus_avp($entity)
1903
1904       entity_contains_virus_avp5($entity)
1905
1906       entity_contains_virus_fprot($entity)
1907
1908       entity_contains_virus_fprotd($entity)
1909
1910       entity_contains_virus_nod32($entity)
1911              These  functions,  meant to be called from filter(), are similar
1912              to the message_contains_virus functions except  they  scan  only
1913              the  current part.  They should be called from list context, and
1914              their return  values  are  as  described  for  the  message_con‐
1915              tains_virus functions.
1916
1917
1918       entity_contains_virus_carrier_scan($entity[, $host])
1919              Connects  to  the specified host:port:local_or_nonlocal (default
1920              $CSSHost), where  the  Symantec  CarrierScan  Server  daemon  is
1921              expected  to  be  listening.   Return values are the same as the
1922              other entity_contains_virus functions.
1923
1924
1925       entity_contains_virus_sophie($entity[, $sophie_sock])
1926              Connects to the specified socket  (default  $SophieSock),  where
1927              the  Sophie  daemon  is expected to be listening.  Return values
1928              are the same as the other entity_contains_virus functions.
1929
1930
1931       entity_contains_virus_trophie($entity[, $trophie_sock])
1932              Connects to the specified socket (default  $TrophieSock),  where
1933              the  Trophie  daemon is expected to be listening.  Return values
1934              are the same as the other entity_contains_virus functions.
1935
1936
1937       entity_contains_virus_clamd($entity[, $clamd_sock])
1938              Connects to the specified socket (default $ClamdSock), where the
1939              clamd daemon is expected to be listening.  Return values are the
1940              same as the other entity_contains_virus functions.
1941
1942

SMTP FLOW

1944       This section illustrates the flow of messages through MIMEDefang.
1945
1946
1947       1. INITIAL CONNECTION
1948              If you invoked mimedefang with the -r option and have defined  a
1949              filter_relay routine, it is called.
1950
1951
1952       2. SMTP HELO COMMAND
1953              The  HELO  string  is stored internally, but no filter functions
1954              are called.
1955
1956
1957       3. SMTP MAIL FROM: COMMAND
1958              If you invoked mimedefang with the -s option and have defined  a
1959              filter_sender routine, it is called.
1960
1961
1962       4. SMTP RCPT TO: COMMAND
1963              If  you invoked mimedefang with the -t option and have defined a
1964              filter_recipient routine, it is called.
1965
1966
1967       5. END OF SMTP DATA
1968              filter_begin is called.  For each MIME part, filter  is  called.
1969              Then filter_end is called.
1970
1971

PRESERVING RELAY INFORMATION

1973       Most organizations have more than one machine handling internet e-mail.
1974       If the primary machine is down, mail is routed to a secondary (or  ter‐
1975       tiary, etc.) MX server, which stores the mail until the primary MX host
1976       comes back up.  Mail is then relayed to the primary MX host.
1977
1978
1979       Relaying from a secondary to a primary MX host has the unfortunate side
1980       effect  of losing the original relay's IP address information.  MIMEDe‐
1981       fang allows you to preserve this information.  One way around the prob‐
1982       lem is to run MIMEDefang on all the secondary MX hosts and use the same
1983       filter.  However, you may not have control over the secondary MX hosts.
1984       If you can persuade the owners of the secondary MX hosts to run MIMEDe‐
1985       fang with a simple filter that only  preserves  relay  information  and
1986       does  no other scanning, your primary MX host can obtain relay informa‐
1987       tion and make decisions using $RelayAddr and $RelayHostname.
1988
1989
1990       When you configure MIMEDefang, supply the "--with-ipheader" argument to
1991       the  ./configure  script.   When  you install MIMEDefang, a file called
1992       /etc/mail/mimedefang-ip-key will be created which contains a  randomly-
1993       generated  header name.  Copy this file to all of your mail relays.  It
1994       is important that all of your MX hosts have  the  same  key.   The  key
1995       should be kept confidential, but it's not disastrous if it leaks out.
1996
1997
1998       On your secondary MX hosts, add this line to filter_end:
1999
2000            add_ip_validation_header();
2001
2002
2003       Note:   You  should only add the validation header to mail destined for
2004       one of your other MX hosts!  Otherwise, the validation header will leak
2005       out.
2006
2007
2008       When  the  secondary  MX hosts relay to the primary MX host, $RelayAddr
2009       and $RelayHostname will be set based on the IP validation  header.   If
2010       MIMEDefang  notices this header, it sets the global variable $WasResent
2011       to 1.  Since you don't want to trust the header unless it  was  set  by
2012       one  of  your  secondary  MX  hosts,  you  should put this code in fil‐
2013       ter_begin:
2014
2015            if ($WasResent) {
2016                 if ($RealRelayAddr ne "ip.of.secondary.mx" and
2017                     $RealRelayAddr ne "ip.of.tertiary.mx") {
2018                      $RelayAddr = $RealRelayAddr;
2019                      $RelayHostname = $RealRelayHostname;
2020                 }
2021            }
2022
2023       This resets the relay address and hostname to the actual relay  address
2024       and  hostname,  unless  the message is coming from one of your other MX
2025       hosts.
2026
2027
2028       On the primary MX host, you should add this in filter_begin:
2029
2030            delete_ip_validation_header();
2031
2032
2033       This prevents the validation header from leaking out to recipients.
2034
2035
2036       Note: The IP validation header works  only  in  message-oriented  func‐
2037       tions.  It (obviously) has no effect on filter_relay, filter_sender and
2038       filter_recipient, because no header information is available yet.   You
2039       must  take  this  into account when writing your filter; you must defer
2040       relay-based decisions to the message filter for mail arriving from your
2041       other MX hosts.
2042
2043

GLOBAL VARIABLE LIFETIME

2045       The  following  list describes the lifetime of global variables (thanks
2046       to Tony Nugent for providing this documentation.)
2047
2048       If you set a global variable:
2049
2050
2051       Outside a subroutine in your filter file
2052              It is available to all functions, all the time.
2053
2054
2055       In filter_relay, filter_sender or filter_recipient
2056              Not guaranteed to be available to any other function,  not  even
2057              from  one  filter_recipient  call  to the next, when receiving a
2058              multi-recipient email message.
2059
2060
2061       In filter_begin
2062              Available to filter_begin, filter and filter_end
2063
2064
2065       In filter
2066              Available to filter and filter_end
2067
2068
2069       In filter_end
2070              Available within filter_end
2071
2072
2073       The "built-in" globals like $Subject, $Sender, etc. are  always  avail‐
2074       able to filter_begin, filter and filter_end. Some are available to fil‐
2075       ter_relay, filter_sender or filter_recipient, but you should check  the
2076       documentation of the variable above for details.
2077
2078

MAINTAINING STATE

2080       There are four basic groups of filtering functions:
2081
2082
2083       1      filter_relay
2084
2085
2086       2      filter_sender
2087
2088
2089       3      filter_recipient
2090
2091
2092       4      filter_begin, filter, filter_multipart, filter_end
2093
2094
2095       In  general, for a given mail message, these groups of functions may be
2096       called in completely different Perl processes.  Thus, there is  no  way
2097       to  maintain  state  inside Perl between groups of functions.  That is,
2098       you cannot set a variable in filter_relay and expect it to be available
2099       in filter_sender, because the filter_sender invocation might take place
2100       in a completely different process.
2101
2102
2103       However, for a given mail message, the $CWD global variable  holds  the
2104       message  spool  directory,  and the current working directory is set to
2105       $CWD.  Therefore, you can store state in files inside  $CWD.   If  fil‐
2106       ter_sender stores data in a file inside $CWD, then filter_recipient can
2107       retrieve that data.
2108
2109
2110       Since filter_relay is called directly after a mail connection is estab‐
2111       lished,  there  is  no  message  context yet, no per-message mimedefang
2112       spool directory, and the $CWD global is not set. Therefore, it  is  not
2113       possible  to  share  information  from filter_relay to one of the other
2114       filter functions. The only thing that filter_relay has in  common  with
2115       the  other  functions  are  the  values  in  the globals $RelayAddr and
2116       $RelayHostname. These could be used to access per-remote-host  informa‐
2117       tion in some database.
2118
2119
2120       Inside $CWD, we reserve filenames beginning with upper-case letters for
2121       internal MIMEDefang use.  If you want to create files to  store  state,
2122       name  them  beginning  with  a  lower-case letter to avoid clashes with
2123       future releases of MIMEDefang.
2124
2125

SOCKET MAPS

2127       If you have Sendmail 8.13 or later, and have compiled it with the SOCK‐
2128       ETMAP  option,  then  you  can use a special map type that communicates
2129       over a socket with another program (rather than looking up a key  in  a
2130       Berkeley database, for example.)
2131
2132
2133       mimedefang-multiplexor  implements  the  Sendmail SOCKETMAP protocol if
2134       you supply the -N option.  In that case,  you  can  define  a  function
2135       called filter_map to implement map lookups.  filter_map takes two argu‐
2136       ments:  $mapname is the name of the Sendmail map (as  given  in  the  K
2137       sendmail configuration directive), and $key is the key to be looked up.
2138
2139
2140       filter_map  must  return a two-element list: ($code, $val) $code can be
2141       one of:
2142
2143
2144       OK     The lookup was successful.  In  this  case,  $val  must  be  the
2145              result of the lookup
2146
2147
2148       NOTFOUND
2149              The  lookup  was unsuccessful -- the key was not found.  In this
2150              case, $val should be the empty string.
2151
2152
2153       TEMP   There was a temporary failure of some  kind.   $val  can  be  an
2154              explanatory error message.
2155
2156
2157       TIMEOUT
2158              There  was  a  timeout of some kind.  $val can be an explanatory
2159              error message.
2160
2161
2162       PERM   There was a permanent failure.  This  is  not  the  same  as  an
2163              unsuccessful  lookup; it should be used only to indicate a seri‐
2164              ous misconfiguration.  As before, $val  can  be  an  explanatory
2165              error message.
2166
2167
2168       Consider  this small example.  Here is a minimal Sendmail configuration
2169       file:
2170
2171            V10/Berkeley
2172            Kmysock socket unix:/var/spool/MIMEDefang/map.sock
2173            kothersock socket unix:/var/spool/MIMEDefang/map.sock
2174
2175
2176       If  mimedefang-multiplexor   is   invoked   with   the   arguments   -N
2177       unix:/var/spool/MIMEDefang/map.sock,  and the filter defines filter_map
2178       as follows:
2179
2180            sub filter_map ($$) {
2181                my($mapname, $key) = @_;
2182                my $ans;
2183                if($mapname ne "mysock") {
2184                    return("PERM", "Unknown map $mapname");
2185                }
2186                $ans = reverse($key);
2187                return ("OK", $ans);
2188            }
2189
2190       Then in Sendmail's testing mode, we see the following:
2191
2192            > /map mysock testing123
2193            map_lookup: mysock (testing123) returns 321gnitset (0)
2194            > /map othersock foo
2195            map_lookup: othersock (foo) no match (69)
2196
2197
2198       (The return code of 69 means EX_UNAVAILABLE or Service Unavailable)
2199
2200
2201       A real-world example could do map lookups in an LDAP directory  or  SQL
2202       database, or perform other kinds of processing.  You can even implement
2203       standard Sendmail maps like virtusertable, mailertable, access_db, etc.
2204       using SOCKETMAP.
2205
2206

TICK REQUESTS

2208       If  you  supply  the -X option to mimedefang-multiplexor, then every so
2209       often, a "tick" request is sent  to  a  free  slave.   If  your  filter
2210       defines  a  function  called  filter_tick, then this function is called
2211       with a single argument: the tick type.  If you  run  multiple  parallel
2212       ticks,  then each tick has a type ranging from 0 to n-1, where n is the
2213       number of parallel ticks.  If you're only  running  one  tick  request,
2214       then the argument to filter_tick is always 0.
2215
2216       You can use this facility to run periodic tasks from within MIMEDefang.
2217       Note, however, that you have no control over which slave is  picked  to
2218       run  filter_tick.  Also, at most one filter_tick call with a particular
2219       "type" argument will be active at any time, and if there  are  no  free
2220       slaves when a tick would occur, the tick is skipped.
2221
2222

SUPPORTED VIRUS SCANNERS

2224       The following virus scanners are supported by MIMEDefang:
2225
2226
2227       o      Symantec       CarrierScan       Server       (http://www.syman
2228              tec.com/region/can/eng/product/scs/)
2229
2230
2231       o      Trend Micro vscan (http://www.antivirus.com/)
2232
2233
2234       o      Sophos   Sweep   (http://www.sophos.com/products/antivirus/savu
2235              nix.html)
2236
2237
2238       o      H+BEDV AntiVir (http://www.hbedv.com/)
2239
2240
2241       o      Central Command Vexira (http://www.centralcommand.com/)
2242
2243
2244       o      NAI uvscan (http://www.nai.com)
2245
2246
2247       o      Bitdefender bdc (http://www.bitdefender.com)
2248
2249
2250       o      Norman Virus Control (NVCC) (http://www.norman.no/)
2251
2252
2253       o      Command csav (http://www.commandsoftware.com)
2254
2255
2256       o      F-Secure fsav (http://www.f-secure.com)
2257
2258
2259       o      The clamscan command-line scanner and the clamd daemon from Clam
2260              AntiVirus (http://www.clamav.net/)
2261
2262
2263       o      Kaspersky Anti-Virus (AVP) (http://www.kaspersky.com/)
2264
2265
2266       o      F-Risk F-Prot (http://www.f-prot.com/)
2267
2268
2269       o      F-Risk FPROTD (daemonized version of F-Prot)
2270
2271
2272       o      Symantec       CarrierScan       Server       (http://www.syman
2273              tec.ca/region/can/eng/product/scs/buymenu.html)
2274
2275
2276       o      Sophie (http://www.vanja.com/tools/sophie/), which uses the lib‐
2277              savi library from Sophos, is supported in daemon-scanning mode.
2278
2279
2280       o      Trophie (http://www.vanja.com/tools/trophie/),  which  uses  the
2281              libvsapi  library from Trend Micro, is supported in daemon-scan‐
2282              ning mode.
2283
2284
2285       o      ESET NOD32 (http://www.eset.com/)
2286
2287

AUTHORS

2289       mimedefang was written by David F. Skoll <dfs@roaringpenguin.com>.  The
2290       mimedefang home page is http://www.mimedefang.org/.
2291
2292

SEE ALSO

2294       mimedefang(8), mimedefang.pl(8)
2295
2296
2297
2298
2299
2300
23014th Berkeley Distribution       8 February 2005           MIMEDEFANG-FILTER(5)
Impressum