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.  Within filter_end, you can  call  func‐
53       tions that modify the message headers body.
54
55
56       5) After filter_end returns, the function filter_wrapup is called if it
57       has been defined.  It is passed a single  argument  consisting  of  the
58       (possibly  modified) MIME::Entity object representing the message about
59       to be  delivered,  including  any  modifications  made  in  filter_end.
60       Within  filter_wrapup,  you can not call functions that modify the mes‐
61       sage body, but you can still add or modify message headers.
62
63

DISPOSITION

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

CONTROLLING RELAYING

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

FILTERING BY HELO

187       You can define a function called filter_helo in your filter.  This lets
188       you reject connections after the HELO/EHLO SMTP command.  Note that for
189       this function to be called, you must use the -H flag with mimedefang.
190
191
192       filter_helo is passed seven arguments: $ip and $name are the IP address
193       and name of the sending relay, as in filter_relay.  The third argument,
194       $helo, is the argument supplied in the HELO/EHLO command.
195
196
197       The remaining four arguments to filter_helo are $port,  $myip,  $myport
198       and  $qid,  which  contain the client's TCP port, the Sendmail daemon's
199       listening IP address, the Sendmail daemon's  listening  port,  and  the
200       Sendmail Queue-ID, respectively.  Note that the Queue-ID may not yet be
201       available at this stage (for  example,  Postfix  does  not  allocate  a
202       queue-ID this early.)  If the Queue-ID is not available, the string NO‐
203       QUEUE is passed instead.
204
205
206       filter_helo must return  a  two-to-five  element  list:  ($code,  $msg,
207       $smtp_code,  $smtp_dsn, $delay).  $code is a return code, with the same
208       meaning as the $code return from filter_relay.  $msg specifies the text
209       message  to  use  for  the SMTP reply.  If $smtp_code and $smtp_dsn are
210       supplied, they become the SMTP numerical reply code  and  the  enhanced
211       status  delivery  code  (DSN code).  If they are not supplied, sensible
212       defaults are used.  $delay specifies a delay in seconds; the  C  milter
213       code  will sleep for $delay seconds before returning the reply to Send‐
214       mail.  $delay defaults to zero.
215
216       (Note that the delay is implemented in the Milter C code; if you  spec‐
217       ify  a  delay of 30 seconds, that doesn't mean a Perl worker is tied up
218       for the duration of  the  delay.   The  delay  only  costs  one  Milter
219       thread.)
220
221

FILTERING BY SENDER

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

FILTERING BY RECIPIENT

296       You can define a function called filter_recipient in your filter.  This
297       lets you reject messages to certain recipients, rather than waiting un‐
298       til the whole message has been sent.  Note that for this check to  take
299       place, you must use the -t flag with mimedefang.
300
301
302       filter_recipient  is passed nine arguments:  $recipient is the envelope
303       address of the recipient and $sender is the envelope e-mail address  of
304       the  sender  (for  example, "<dfs@roaringpenguin.com>").  The addresses
305       may or may not be surrounded by angle brackets.  $ip and $name are  the
306       IP address and host name of the SMTP relay.  $first is the envelope ad‐
307       dress of the first recipient for this message, and $helo is  the  argu‐
308       ment   to   the   SMTP  "HELO"  command.   The  last  three  arguments,
309       $rcpt_mailer, $rcpt_host and $rcpt_addr are the Sendmail  mailer,  host
310       and  address  triple for the recipient address.  For example, for local
311       recipients, $rcpt_mailer is likely to be "local", while for remote  re‐
312       cipients, it is likely to be "esmtp".
313
314
315       Inside  filter_recipient,  you  can access any ESMTP arguments (such as
316       "NOTIFY=never") in the array @ESMTPArgs.  Each ESMTP argument  occupies
317       one array element.
318
319
320       filter_recipient must return a two-to-five element list whose interpre‐
321       tation is the same as for filter_sender.  Note, however, that  if  fil‐
322       ter_recipient returns 'DISCARD', then the entire message for all recip‐
323       ients is discarded.  (It doesn't really make sense, but that's how Mil‐
324       ter works.)
325
326
327       For  example,  if  you wish to reject messages from spammer@badguy.com,
328       unless they are to postmaster@mydomain.com, you could  use  this  func‐
329       tion:
330
331       sub filter_recipient {
332            my ($recipient, $sender, $ip, $hostname, $first, $helo,
333                   $rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
334            if ($sender =~ /^<?spammer\@badguy\.com>?$/i) {
335                 if ($recipient =~ /^<?postmaster\@mydomain\.com>?$/i) {
336                      return ('CONTINUE', "ok");
337                 }
338                 return ('REJECT', 'Sorry; spammer@badguy.com is blacklisted.');
339            }
340            return ('CONTINUE', "ok");
341       }
342
343

INITIALIZATION AND CLEANUP

345       Just  before  a  worker begins processing messages, mimedefang.pl calls
346       the functions filter_initialize (if it is defined) with  no  arguments.
347       By  the  time filter_initialize is called, all the other initialization
348       (such as setting up syslog facility and priority) has been done.
349
350       If you are not using an embedded Perl interpreter, then  performing  an
351       action  inside  filter_initialize is practically the same as performing
352       it directly in the filter file, outside any function definition.   How‐
353       ever,  if you are using an embedded Perl interpreter, then anything you
354       call directly from outside a function definition is executed once  only
355       in  the parent process.  Anything in filter_initialize is executed once
356       per worker.  If you use any code that opens a descriptor (for  example,
357       a  connection to a database server), you must run that code inside fil‐
358       ter_initialize and not directly from the  filter,  because  the  multi‐
359       plexor  closes  all  open  descriptors  when it activates a new worker.
360       From within filter_initialize a configuration file could be  loaded  by
361       calling read_config.  read_config accepts a configuration file path and
362       it can be used to overwrite global variables.  Configuration file  for‐
363       mat is pure Perl code.
364
365       When  a  worker is about to exit, mimedefang.pl calls the function fil‐
366       ter_cleanup (if it is defined) with no arguments.  This function can do
367       whatever  cleanup you like, such as closing file descriptors and clean‐
368       ing up  long-lived  worker  resources.   The  return  value  from  fil‐
369       ter_cleanup  becomes  the  worker's exit status.  (You should therefore
370       ensure that filter_cleanup returns an integer suitable  for  a  process
371       exit status.)
372
373
374       If  filter_cleanup  takes  longer than 10 seconds to run, the worker is
375       sent a SIGTERM signal.  If that doesn't kill it (because you're  catch‐
376       ing  signals,  perhaps), then a further 10 seconds later, the worker is
377       sent a SIGKILL signal.
378
379

CONTROLLING PARSING

381       If you define a function called filter_create_parser  taking  no  argu‐
382       ments,  then mimedefang.pl will call it to create a MIME::Parser object
383       for parsing mail messages.
384
385       Filter_create_parser is expected to return a MIME::Parser object (or an
386       instance of a class derived from MIME::Parser).
387
388       You  can  use  filter_create_parser  to  change  the  behavior  of  the
389       MIME::Parser used by mimedefang.pl.
390
391       If you do not define a filter_create_parser function, then  a  built-in
392       version equivalent to this is used:
393
394            sub filter_create_parser () {
395                 my $parser = MIME::Parser->new();
396                 $parser->extract_nested_messages(1);
397                 $parser->extract_uuencode(1);
398                 $parser->output_to_core(0);
399                 $parser->tmp_to_core(0);
400                 return $parser;
401            }
402

EXTENDING MIMEDEFANG

404       The  man page for mimedefang-protocol(7) lists commands that are passed
405       to workers in server mode (see "SERVER COMMANDS".)  You  can  define  a
406       function  called  filter_unknown_cmd to extend the set of commands your
407       filter can handle.
408
409       If you define filter_unknown_cmd, it is passed the unknown command as a
410       single  argument.   It  should return a list of values as follows:  The
411       first element of the list must be either "ok"  or  "error:"  (with  the
412       colon.)   The remaining arguments are percent-encoded.  All the result‐
413       ing pieces are joined together with a single space  between  them,  and
414       the resulting string passed back as the reply to the multiplexor.
415
416       For  example,  the  following function will make your filter reply to a
417       "PING" command with "PONG":
418
419       sub filter_unknown_cmd ($) {
420           my($cmd) = @_;
421           if ($cmd eq "PING") {
422               return("ok", "PONG");
423           }
424           return("error:", "Unknown command");
425       }
426
427       You can test this filter by typing the following as root:
428
429       md-mx-ctrl PING
430
431       The response should be:
432
433       ok PONG
434
435       If you extend the set of commands using filter_unknown_cmd, you  should
436       make all your commands start with an upper-case letter to avoid clashes
437       with future built-in commands.
438
439

REJECTING UNKNOWN USERS EARLY

441       A very common mail setup is to have a MIMEDefang machine act as an SMTP
442       proxy,  accepting  and  scanning  mail and then relaying it to the real
443       mail server.  Unfortunately, this means  that  the  MIMEDefang  machine
444       cannot  know  if  a local address is valid or not, and will forward all
445       mail for the appropriate domains.  If a mail comes in  for  an  unknown
446       user,  the  MIMEDefang machine will be forced to generate a bounce mes‐
447       sage when it tries to relay the mail.
448
449
450       It's often desirable to have the MIMEDefang host reply with a "User un‐
451       known"  SMTP  response directly.  While this can be done by copying the
452       list of local users to the MIMEDefang machine, MIMEDefang has a  built-
453       in  function  called  md_check_against_smtp_server for querying another
454       relay host:
455
456
457       md_check_against_smtp_server($sender, $recip,  $helo,  $server,  $port)
458       This
459              function  connects  to  the  SMTP server $server and pretends to
460              send mail from $sender to $recip.  The return value is always  a
461              two-element array.  If the RCPT TO: command succeeds, the return
462              value is ("CONTINUE", "OK").  If the RCPT fails with a permanent
463              failure, the return value is ("REJECT", $msg), where $msg is the
464              message from the SMTP server.  Any temporary  failures,  connec‐
465              tion  errors,  etc.  result  in  a  return value of ("TEMPFAIL",
466              $msg).
467
468              The optional argument $port specifies the TCP  port  to  connect
469              to.   If it is not supplied, then the default SMTP port of 25 is
470              used.
471
472              If the server offers STARTTLS support, TLS step-up is attempted.
473              If  TLS  step-up  fails, the check will fall-back to using clear
474              text and log the failure
475
476
477       Suppose the machine filter.domain.tld is filtering  mail  destined  for
478       the  real mail server mail.domain.tld.  You could have a filter_recipi‐
479       ent function like this:
480
481       sub filter_recipient
482       {
483           my($recip, $sender, $ip, $host, $first, $helo,
484              $rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
485           return md_check_against_smtp_server($sender, $recip,
486                                "filter.domain.tld",
487                                "mail.domain.tld");
488       }
489
490       For each RCPT TO: command,  MIMEDefang  opens  an  SMTP  connection  to
491       mail.domain.tld and checks if the command would succeed.
492
493
494       Please  note  that  you should only use md_check_against_smtp_server if
495       your mail server responds with a failure code for nonexistent users  at
496       the  RCPT  TO: level.  Also, this function may impose too much overhead
497       if you receive a lot of e-mail, and it will generate  lots  of  useless
498       log  entries  on  the  real  mail  server  (because of all the RCPT TO:
499       probes.)  It may also significantly increase the load on the real  mail
500       server.
501
502

GLOBAL VARIABLES YOU CAN SET

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

FILTER

651       The heart of mimedefang-filter is the filter procedure.  See the  exam‐
652       ples  that came with MIMEDefang to learn to write a filter.  The filter
653       is called with the following arguments:
654
655
656       $entity
657              The MIME::Entity object.  (See the MIME::tools Perl module docu‐
658              mentation.)
659
660
661       $fname The suggested attachment filename, or "" if none was supplied.
662
663
664       $ext   The  file extension (all characters from the rightmost period to
665              the end of the filename.)
666
667
668       $type  The MIME type (for example, "text/plain".)
669
670
671       The filename is derived as follows:
672
673
674       o      First, if the Content-Disposition header has a "filename" field,
675              it is used.
676
677
678       o      Otherwise,  if the Content-Type header has a "name" field, it is
679              used.
680
681
682       o      Otherwise, the Content-Description header value is used.
683
684
685       Note that the truly paranoid will check all three fields  for  matches.
686       The  functions  re_match  and  re_match_ext  perform regular expression
687       matches on all three of the fields named above, and  return  1  if  any
688       field  matches.   See  the sample filters for details.  The calling se‐
689       quence is:
690
691            re_match($entity, "regexp")
692            re_match_ext($entity, "regexp")
693
694       re_match returns true if any of the fields matches the  regexp  without
695       regard  to  case.   re_match_ext  returns  true if the extension in any
696       field matches.  An extension is defined as the last dot in a  name  and
697       all remaining characters.
698
699
700       A  third function called re_match_in_zip_directory will look inside zip
701       files and return true if any of the file names inside the  zip  archive
702       match the regular expression.  Call it like this:
703
704            my $bh = $entity->bodyhandle();
705            my $path = (defined($bh)) ? $bh->path() : undef;
706            if (defined($path) and re_match_in_zip_directory($path, "regexp")) {
707                # Take action...
708            }
709
710       You  should not call re_match_in_zip_directory unless you know that the
711       entity is a zip file attachment.
712
713
714       Another function called re_match_in_rar_directory will look inside  rar
715       files  and  return true if any of the file names inside the rar archive
716       match  the  regular  expression.   The  function  is  very  similar  to
717       re_match_in_zip_directory  but the unrar binary is required and must be
718       specified in $Features{"unrar"}.
719
720
721       Another function called re_match_in_7z_directory will look inside  7zip
722       files  and return true if any of the file names inside the 7zip archive
723       match  the  regular  expression.   The  function  is  very  similar  to
724       re_match_in_zip_directory  but  the  7z  binary is required and must be
725       specified in $Features{"7zip"}.
726
727

GLOBAL VARIABLES SET BY MIMEDEFANG.PL

729       The following global variables are set by mimedefang.pl and are  avail‐
730       able  for use in your filter.  All of these variables are always avail‐
731       able to filter_begin, filter, filter_multipart and filter_end.  In  ad‐
732       dition,  some  of  them are available in filter_relay, filter_sender or
733       filter_recipient.  If this is the case, it will be noted below.
734
735
736       %Features
737              This hash lets you determine at run-time whether  certain  func‐
738              tionality is available.  This hash is available at all times as‐
739              suming  the  detect_and_load_perl_modules()  function  has  been
740              called.  The defined features are:
741
742              $Features{"SpamAssassin"}  is 1 if SpamAssassin 1.6 or better is
743              installed; 0 otherwise.
744
745              $Features{"HTML::Parser"} is 1 if HTML::Parser is  installed;  0
746              otherwise.
747
748              $Features{"Virus:FPROTD"} is currently always 0.  Set it to 1 in
749              your filter file if you have  F-Risk's  FPROTD  scanner  earlier
750              than version 6.
751
752              $Features{"Virus:FPROTD6"}  is  currently always 0.  Set it to 1
753              in your filter file if you have version  6  of  F-Risk's  FPROTD
754              scanner.
755
756              $Features{"Virus:SymantecCSS"} is currently always 0.  Set it to
757              1 in your filter file  if  you  have  the  Symantec  CarrierScan
758              Server virus scanner.
759
760              $Features{"Virus:NAI"}  is  the full path to NAI uvscan if it is
761              installed; 0 if it is not.
762
763              $Features{"Virus:BDC"} is the full path to Bitdefender bdc if it
764              is installed; 0 if it is not.
765
766              $Features{"Virus:NVCC"} is the full path to Norman Virus Control
767              nvcc if it is installed; 0 if it is not.
768
769              $Features{"Virus:HBEDV"} is the full path to H+BEDV  AntiVir  if
770              it is installed; 0 if it is not.
771
772              $Features{"Virus:VEXIRA"}  is  the  full path to Central Command
773              Vexira if it is installed; 0 if it is not.
774
775              $Features{"Virus:SOPHOS"} is the full path to Sophos sweep if it
776              is installed; 0 if it is not.
777
778              $Features{"Virus:SAVSCAN"} is the full path to Sophos savscan if
779              it is installed; 0 if it is not.
780
781              $Features{"Virus:CLAMAV"} is the full path to Clam  AV  clamscan
782              if it is installed; 0 if it is not.
783
784              $Features{"Virus:AVP"} is the full path to AVP AvpLinux if it is
785              installed; 0 if it is not.
786
787              $Features{"Virus:AVP5"} is the  full  path  to  Kaspersky  "ave‐
788              client" if it is installed; 0 if it is not.
789
790              $Features{"Virus:CSAV"}  is  the full path to Command csav if it
791              is installed; 0 if it is not.
792
793              $Features{"Virus:FSAV"} is the full path to F-Secure fsav if  it
794              is installed; 0 if it is not.
795
796              $Features{"Virus:FPROT"} is the full path to F-Risk f-prot if it
797              is installed; 0 if it is not.
798
799              $Features{"Virus:FPSCAN"} is the full path to F-Risk  fpscan  if
800              it is installed; 0 if it is not.
801
802              $Features{"Virus:SOPHIE"}  is  the  full path to Sophie if it is
803              installed; 0 if it is not.
804
805              $Features{"Virus:CLAMD"} is the full path to clamd if it is  in‐
806              stalled; 0 if it is not.
807
808              $Features{"Virus:CLAMDSCAN"} is the full path to clamdscan if it
809              is installed; 0 if it is not.
810
811              $Features{"Virus:TROPHIE"} is the full path to Trophie if it  is
812              installed; 0 if it is not.
813
814              $Features{"Virus:NOD32"} is the full path to ESET NOD32 nod32cli
815              if it is installed; 0 if it is not.
816
817              $Features{"Path:RSPAMC"} is the full path to rspamc(1) if it  is
818              installed (deprecated); 0 if it is not.
819
820              NOTE: Perl-module based features such as SpamAssassin are deter‐
821              mined at runtime and may change as these are added and  removed.
822              Most  Virus features are predetermined at the time of configura‐
823              tion and do not adapt to runtime availability unless changed  by
824              the filter rules.
825
826
827       $CWD   This  variable  holds the working directory for the current mes‐
828              sage.  During filter processing, mimedefang.pl chdir's into this
829              directory  before  calling  any  of the filter_ functions.  Note
830              that this variable is set correctly in  filter_sender  and  fil‐
831              ter_recipient, but not in filter_relay.
832
833
834       $SuspiciousCharsInHeaders
835              If  this variable is true, then mimedefang has discovered suspi‐
836              cious characters in message headers.  This might be  an  exploit
837              for  bugs  in  MIME-parsing  routines in some badly-written mail
838              user agents (e.g. Microsoft Outlook.)  You  should  always  drop
839              such messages.
840
841
842       $SuspiciousCharsInBody
843              If  this variable is true, then mimedefang has discovered suspi‐
844              cious characters in the message body.  This might be an  exploit
845              for  bugs  in  MIME-parsing  routines in some badly-written mail
846              user agents (e.g. Microsoft Outlook.)  You  should  always  drop
847              such messages.
848
849
850       $RelayHostname
851              The  host  name of the relay.  This is the name of the host that
852              is attempting to send e-mail to your host.  May  be  "undef"  if
853              the  host name could not be determined.  This variable is avail‐
854              able in filter_relay, filter_sender and filter_recipient in  ad‐
855              dition to the body filtering functions.
856
857
858       $RelayAddr
859              The  IP  address of the sending relay (as a string consisting of
860              four dot-separated decimal numbers.)  One potential use of  $Re‐
861              layAddr  is  to  limit mailing to certain lists to people within
862              your organization.  This variable is available in  filter_relay,
863              filter_sender  and filter_recipient in addition to the body fil‐
864              tering functions.
865
866
867       $Helo  The argument given to the SMTP "HELO" command.  This variable is
868              available in filter_sender and filter_recipient, but not in fil‐
869              ter_relay.
870
871
872       $Subject
873              The contents of the "Subject:" header.
874
875
876       $Sender
877              The sender of the e-mail.  This variable is set in filter_sender
878              and  filter_recipient  in  addition  to the body filtering func‐
879              tions.
880
881
882       @Recipients
883              A list of the recipients.  In filter_recipient, it is set to the
884              single  recipient currently under consideration. Or, after call‐
885              ing read_commands_file within filter_recipient, the current  re‐
886              cipient  under consideration is in the final position of the ar‐
887              ray, at $Recipients[-1], while any previous (and  accepted)  re‐
888              cipients are at the beginning of the array, that is, in @Recipi‐
889              ents[0 .. $#Recipients-1].
890
891
892
893       $MessageID
894              The contents of the "Message-ID:"  header  if  one  is  present.
895              Otherwise, contains the string "NOQUEUE".
896
897
898       $QueueID
899              The  Sendmail  queue identifier if it could be determined.  This
900              variable is set correctly  in  filter_relay,  filter_helo,  fil‐
901              ter_sender  and  filter_recipient.   Note, however, that Postfix
902              may not allocate a queue ID until filter_recipient time.   If  a
903              Queue-ID  has  not  yet  been allocated, $QueueID is set to "NO‐
904              QUEUE".
905
906
907       $MsgID Set to $QueueID if the queue ID could be determined;  otherwise,
908              set  to  $MessageID.  This identifier should be used in logging,
909              because it matches the identifier used by Sendmail to  log  mes‐
910              sages.   Note  that  this  variable  is  set  correctly  in fil‐
911              ter_sender and filter_recipient, but it is not available in fil‐
912              ter_relay.
913
914
915       $VirusScannerMessages
916              Each time a virus-scanning function is called, messages (if any)
917              from the virus scanner are accumulated in  this  variable.   You
918              can  use  it  in  filter_end to formulate a notification (if you
919              wish.)
920
921
922       $VirusName
923              If a virus-scanning function found a virus, this  variable  will
924              hold the virus name (if it could be determined.)
925
926
927       $SASpamTester
928              If  defined,  this  is  the configured Mail::SpamAssassin object
929              used for mail tests.  It may  be  initialized  with  a  call  to
930              spam_assassin_init which also returns it.
931
932
933       %SendmailMacros
934              This hash contains the values of some Sendmail macros.  The hash
935              elements exist only for macros defined  by  Sendmail.   See  the
936              Sendmail documentation for the meanings of the macros.
937
938              By  default,  mimedefang  passes  the  values  of  the following
939              macros: ${daemon_name}, ${daemon_port}, ${if_name},  ${if_addr},
940              $j,   $_,   $i,   ${tls_version},   ${cipher},   ${cipher_bits},
941              ${cert_subject}, ${cert_issuer},  ${auth_type},  ${auth_authen},
942              ${auth_ssf},  ${auth_author},  ${mail_mailer},  ${mail_host} and
943              ${mail_addr}.   In  addition,  ${client_port}  is  set  to   the
944              client's TCP port.
945
946              If  any macro is not set or not passed to milter, it will be un‐
947              available.  To access the value of a macro, use:
948
949
950                   $SendmailMacros{"macro_name"}
951
952
953              Do not place curly brackets around the macro name.   This  vari‐
954              able  is available in filter_sender and filter_recipient after a
955              call to read_commands_file.
956
957
958       @SenderESMTPArgs
959              This array contains all the ESMTP arguments supplied in the MAIL
960              FROM: command.  For example:
961
962              sub print_sender_esmtp_args {
963                  foreach (@SenderESMTPArgs) {
964                      print STDERR "Sender ESMTP arg: $_0;
965                  }
966              }
967
968
969       %RecipientESMTPArgs
970              This hash contains all the ESMTP arguments supplied in each RCPT
971              TO: command.  For example:
972
973              sub print_recip_esmtp_args {
974                  foreach my $recip (@Recipients) {
975                      foreach(@{$RecipientESMTPArgs{$recip}}) {
976                          print STDERR "Recip ESMTP arg for $recip: $_0;
977                      }
978                  }
979              }
980
981
982       %RecipientMailers
983              This hash contains the Sendmail "mailer-host-address" triple for
984              each recipient.  Here's an example of how to use it:
985
986              sub print_mailer_info {
987                  my($recip, $mailer, $host, $addr);
988                  foreach $recip (@Recipients) {
989                      $mailer = ${RecipientMailers{$recip}}[0];
990                      $host = ${RecipientMailers{$recip}}[1];
991                      $addr =  ${RecipientMailers{$recip}}[2];
992                      print STDERR "$recip: mailer=$mailer, host=$host, addr=$addr\n";
993                  }
994              }
995
996              In  filter_recipient, this variable by default only contains in‐
997              formation on the recipient currently under investigation. Infor‐
998              mation  on  all  recipients is available after calling read_com‐
999              mands_file.
1000
1001

ACTIONS

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

USEFUL ROUTINES

1345       mimedefang.pl  includes  some  useful  functions you can call from your
1346       filter:
1347
1348
1349       detect_and_load_perl_modules()
1350              Unless you really know what you're doing, this function must  be
1351              called first thing in your filter file.  It causes mimedefang.pl
1352              to detect and load  Perl  modules  such  as  Mail::SpamAssassin,
1353              Net::DNS, etc., and to populate the %Features hash.
1354
1355
1356       send_quarantine_notifications()
1357              This  function  should  be called from filter_end.  If any parts
1358              were quarantined, a  quarantine  notification  is  sent  to  the
1359              MIMEDefang  administrator.   Please note that if you do not call
1360              send_quarantine_notifications, then no quarantine  notifications
1361              are sent.
1362
1363
1364       get_quarantine_dir()
1365              This  function  returns the full path name of the quarantine di‐
1366              rectory.  If you have not yet quarantined any parts of the  mes‐
1367              sage,  a  quarantine  directory  is created and its pathname re‐
1368              turned.
1369
1370
1371       change_sender($sender)
1372              This function changes the envelope sender to  $sender.   It  can
1373              only  be called from filter_begin or any later function.  Please
1374              note that this function is only supported  with  Sendmail/Milter
1375              8.14.0  or newer.  It has no effect if you're running older ver‐
1376              sions.
1377
1378
1379       add_recipient($recip)
1380              This function adds $recip to the list of envelope recipients.  A
1381              copy of the message (after any modifications by MIMEDefang) will
1382              be sent to $recip in addition to the original recipients.   Note
1383              that  add_recipient  does  not  modify the @Recipients array; it
1384              just makes a note to Sendmail to add the recipient.
1385
1386
1387       delete_recipient($recip)
1388              This function deletes $recip from the list of recipients.   That
1389              person  will  not receive a copy of the mail.  $recip should ex‐
1390              actly match an entry in the @Recipients array for delete_recipi‐
1391              ent()  to  work.  Note that delete_recipient does not modify the
1392              @Recipients array; it just makes a note to  Sendmail  to  delete
1393              the recipient.
1394
1395       resend_message($recip1, $recip2, ...)
1396              or
1397
1398       resend_message(@recips)
1399              This  function immediately resends the original, unmodified mail
1400              message to each of the named recipients.  The  sender's  address
1401              is preserved.  Be very careful when using this function, because
1402              it resends the original message, which may contain undesired at‐
1403              tachments.   Also,  you  should not call this function from fil‐
1404              ter(), because it resends the message each time  it  is  called.
1405              This  may  result  in  multiple copies being sent if you are not
1406              careful.  Call from filter_begin() or filter_end() to be safe.
1407
1408              The function returns true on success, or false if it fails.
1409
1410              Note that the resend_message function delivers the mail  in  de‐
1411              ferred  mode  (using  Sendmail's  "-odd"  flag.)  You must run a
1412              client-submission queue processor if you use Sendmail 8.12.   We
1413              recommend executing this command as part of the Sendmail startup
1414              sequence:
1415
1416                   sendmail -Ac -q5m
1417
1418
1419       remove_redundant_html_parts($entity)
1420              This function should only be called from filter_end.  It removes
1421              redundant HTML parts from the message.  It works by deleting any
1422              part of type text/html from the message if (1) it is a  sub-part
1423              of  a  multipart/alternative part, and (2) there is another part
1424              of type text/plain under the multipart/alternative part.
1425
1426
1427       replace_entire_message($entity)
1428              This function can only be called from filter_end.   It  replaces
1429              the  entire message with $entity, a MIME::Entity object that you
1430              have constructed.  You can use any of the MIME::Tools  functions
1431              to construct the entity.
1432
1433
1434       read_commands_file()
1435              This  function should only be called from filter_sender and fil‐
1436              ter_recipient. This will read the COMMANDS file (as described in
1437              mimedefang-protocol(7)),  and  will fill or update the following
1438              global variables: $Sender, @Recipients, %RecipientMailers,  $Re‐
1439              layAddr,   $RealRelayAddr,  $RelayHostname,  $RealRelayHostname,
1440              $QueueID, $Helo, %SendmailMacros.
1441
1442              If you do not call read_commands_file, then the only information
1443              available in filter_sender and filter_recipient is that which is
1444              passed as an argument to the function.
1445
1446
1447       stream_by_domain()
1448              Do not use this function unless you have Sendmail 8.12  and  lo‐
1449              cally- submitted e-mail is submitted using SMTP.
1450
1451              This  function  should  only  be called at the very beginning of
1452              filter_begin(), like this:
1453
1454                   sub filter_begin {
1455                        if (stream_by_domain()) {
1456                             return;
1457                        }
1458                        # Rest of filter_begin
1459                   }
1460
1461              stream_by_domain() looks at all the recipients of  the  message,
1462              and  if  they  belong  to the same domain (e.g., joe@domain.com,
1463              jane@domain.com and sue@domain.com), it returns 0 and  sets  the
1464              global  variable $Domain to the domain (domain.com in this exam‐
1465              ple.)
1466
1467              If users are in different  domains,  stream_by_domain()  resends
1468              the  message (once to each domain) and returns 1 For example, if
1469              the  original  recipients  are  joe@abc.net,  jane@xyz.net   and
1470              sue@abc.net,  the  original message is resent twice: One copy to
1471              joe@abc.net and sue@abc.net, and another copy  to  jane@xyz.net.
1472              Also,  any  subsequent  scanning  is canceled (filter() and fil‐
1473              ter_end() will not be called for the original message)  and  the
1474              message is silently discarded.
1475
1476              If  you  have Sendmail 8.12, then locally-submitted messages are
1477              sent via SMTP, and MIMEDefang will be  called  for  each  resent
1478              message.  It is possible to set up Sendmail 8.12 so locally-sub‐
1479              mitted  messages  are  delivered   directly;   in   this   case,
1480              stream_by_domain will not work.
1481
1482              Using stream_by_domain allows you to customize your filter rules
1483              for each domain.  If you use the function  as  described  above,
1484              you can do this in your filter routine:
1485
1486                   sub filter {
1487                        my($entity, $fname, $ext, $type) = @_;
1488                        if ($Domain eq "abc.com") {
1489                             # Filter actions for abc.com
1490                        } elsif ($Domain eq "xyz.com") {
1491                             # Filter actions for xyz.com
1492                        } else {
1493                             # Default filter actions
1494                        }
1495                   }
1496
1497              You  cannot  rely  on  $Domain  being set unless you have called
1498              stream_by_domain().
1499
1500
1501       stream_by_recipient()
1502              Do not use this function unless you have Sendmail 8.12  and  lo‐
1503              cally- submitted e-mail is submitted using SMTP.
1504
1505              This  function  should  only  be called at the very beginning of
1506              filter_begin(), like this:
1507
1508                   sub filter_begin {
1509                        if (stream_by_recipient()) {
1510                             return;
1511                        }
1512                        # Rest of filter_begin
1513                   }
1514
1515              If there is more than one recipient,  stream_by_recipient()  re‐
1516              sends  the  message  once  to each recipient.  That way, you can
1517              customize your filter rules on a per-recipient basis.  This  may
1518              increase the load on your mail server considerably.
1519
1520              Also,  a  "recipient"  is determined before alias expansion.  So
1521              "all@mydomain.com" is considered a  single  recipient,  even  if
1522              Sendmail delivers to a list.
1523
1524              If  you  have Sendmail 8.12, then locally-submitted messages are
1525              sent via SMTP, and MIMEDefang will be  called  for  each  resent
1526              message.  It is possible to set up Sendmail 8.12 so locally-sub‐
1527              mitted  messages  are  delivered   directly;   in   this   case,
1528              stream_by_recipient() will not work.
1529
1530              stream_by_recipient()  allows you to customize your filter rules
1531              for each recipient in a manner similar to stream_by_domain().
1532
1533

LOGGING

1535       md_graphdefang_log_enable($facility, $enum_recips)
1536              Enables the md_graphdefang_log function (described  next).   The
1537              function  logs  to  syslog using the specified facility.  If you
1538              omit $facility, it defaults to  'mail'.   If  you  do  not  call
1539              md_graphdefang_log_enable  in  your  filter,  then  any calls to
1540              md_graphdefang_log simply do nothing.
1541
1542              If you supply $enum_recips as 1, then a line of logging is  out‐
1543              put  for  each recipient of a mail message.  If it is zero, then
1544              only a single line is output for  each  message.   If  you  omit
1545              $enum_recips, it defaults to 1.
1546
1547
1548       md_graphdefang_log($event, $v1, $v2)
1549              Logs  an  event  with  up to two optional additional parameters.
1550              The log message has a specific format useful for graphing tools;
1551              the message looks like this:
1552
1553                   MDLOG,msgid,event,v1,v2,sender,recipient,subj
1554
1555              "MDLOG"  is literal text.  "msgid" is the Sendmail queue identi‐
1556              fier.  "event" is the event name, and "v1" and "v2" are the  ad‐
1557              ditional  parameters.   "sender" is the sender's e-mail address.
1558              "recipient" is the recipient's e-mail address, and "subj" is the
1559              message  subject.   If  a  message  has more than one recipient,
1560              md_graphdefang_log may log an event message for each  recipient,
1561              depending on how you called md_graphdefang_log_enable.
1562
1563              Note that md_graphdefang_log should not be used in filter_relay,
1564              filter_sender or filter_recipient.  The global variables it  re‐
1565              lies on are not valid in that context.
1566
1567              If  you want to log general text strings, do not use md_graphde‐
1568              fang_log.  Instead, use md_syslog (described next).
1569
1570
1571       md_syslog($level, $msg)
1572              Logs the message $msg to syslog, using level $level.  The  level
1573              is a literal string, and should be one of 'err', 'debug', 'warn‐
1574              ing', ´emerg', 'crit', 'notice' or 'info'.  (See  syslog(3)  for
1575              details.)
1576
1577              Note  that  md_syslog  does not perform %-subsitutions like sys‐
1578              log(3) does.  Depending on  your  Perl  installation,  md_syslog
1579              boils  down  to  a  call  to  Unix::Syslog::syslog  or Sys::Sys‐
1580              log::syslog.  See the Unix::Syslog or Sys::Syslog man pages  for
1581              more details.
1582
1583
1584       md_openlog($tag, $facility)
1585              Sets the tag used in syslog messages to $tag, and sends the logs
1586              to the $facility facility.  If you do not call md_openlog before
1587              you  call  md_syslog, then it is called implicitly with $tag set
1588              to mimedefang.pl and $facility set to mail.
1589
1590

RBL LOOKUP FUNCTIONS

1592       mimedefang.pl includes the following functions for looking  up  IP  ad‐
1593       dresses   in  DNS-based  real-time  blacklists.   Note  that  the  "re‐
1594       lay_is_blacklisted" functions are deprecated and may be  removed  in  a
1595       future  release.  Instead, you should use the module Net::DNSBL::Client
1596       from CPAN.
1597
1598
1599       relay_is_blacklisted($relay, $domain)
1600              This checks a DNS-based real-time spam  blacklist,  and  returns
1601              true  if the relay host is blacklisted, or false otherwise.  (In
1602              fact, the return value is whatever the blacklist  returns  as  a
1603              resolved hostname, such as "127.0.0.4")
1604
1605              Note  that  relay_is_blacklisted uses the built-in gethostbyname
1606              function; this is usually quite inefficient and does not  permit
1607              you to set a timeout on the lookup.  Instead, we recommend using
1608              one of the other DNS lookup function described in this  section.
1609              (Note,  though,  that  the  other  functions  require  the  Perl
1610              Net::DNS module, whereas relay_is_blacklisted does not.)
1611
1612              Here's an example of how to use relay_is_blacklisted:
1613
1614                   if (relay_is_blacklisted($RelayAddr, "rbl.spamhaus.org")) {
1615                        action_add_header("X-Blacklist-Warning",
1616                               "Relay $RelayAddr is blacklisted by Spamhaus");
1617                   }
1618
1619
1620       relay_is_blacklisted_multi($relay,  $timeout,  $answers_wanted,   [$do‐
1621       main1, $domain2, ...], $res)
1622              This function is similar to relay_is_blacklisted, except that it
1623              takes a timeout argument (specified in seconds) and an array  of
1624              domains  to check.  The function checks all domains in parallel,
1625              and is guaranteed to return in $timeout seconds.  (Actually,  it
1626              may take up to one second longer.)
1627
1628              The parameters are:
1629
1630              $relay -- the IP address you want to look up
1631
1632              $timeout -- a timeout in seconds after which the function should
1633              return
1634
1635              $answers_wanted -- the maximum number of  positive  answers  you
1636              care  about.  For example, if you're looking up an address in 10
1637              different RBLs, but are going to bounce it if it is on  four  or
1638              more, you can set $answers_wanted to 4, and the function returns
1639              as soon  as  four  "hits"  are  discovered.   If  you  set  $an‐
1640              swers_wanted to zero, then the function does not return early.
1641
1642              [$domain1, $domain2, ...] -- a reference to an array of strings,
1643              where each string is an RBL domain.
1644
1645              $res -- a Net::DNS::Resolver object.  This argument is optional;
1646              if  you  do  not supply it, then relay_is_blacklisted_multi con‐
1647              structs its own resolver.
1648
1649              The return value is a reference to a hash; the keys of the  hash
1650              are  the  original domains, and the corresponding values are ei‐
1651              ther SERVFAIL, NXDOMAIN, or a list of IP  addresses  in  dotted-
1652              quad notation.
1653
1654              Here's an example:
1655
1656                  $ans = relay_is_blacklisted_multi($RelayAddr, 8, 0,
1657                      ["sbl.spamhaus.org", "relays.ordb.org"]);
1658
1659                  foreach $domain (keys(%$ans)) {
1660                      $r = $ans->{$domain};
1661                      if (ref($r) eq "ARRAY") {
1662                          # It's an array -- it IS listed in RBL
1663                          print STDERR "Lookup in $domain yields [ ";
1664                          foreach $addr (@$r) {
1665                              print STDERR $addr . " ";
1666                          }
1667                          print STDERR "]\n";
1668                      } else {
1669                          # It is NOT listed in RBL
1670                          print STDERR "Lookup in $domain yields "
1671                                       . $ans->{$domain} . "\n";
1672                      }
1673                  }
1674
1675              You  should  compare  each  of $ans->{$domain} to "SERVFAIL" and
1676              "NXDOMAIN" to see if the relay is not listed.  Any other  return
1677              value will be an array of IP addresses indicating that the relay
1678              is listed.
1679
1680              Any lookup that does not succeed within $timeout seconds has the
1681              corresponding return value set to SERVFAIL.
1682
1683
1684       relay_is_blacklisted_multi_list($relay,    $timeout,   $answers_wanted,
1685       [$domain1, $domain2, ...], $res)
1686              This function is similar  to  relay_is_blacklisted_multi  except
1687              that the return value is simply an array of RBL domains in which
1688              the relay was listed.
1689
1690
1691       relay_is_blacklisted_multi_count($relay,   $timeout,   $answers_wanted,
1692       [$domain1, $domain2, ...], $res)
1693              This  function  is  similar to relay_is_blacklisted_multi except
1694              that the return value is an integer specifying the number of do‐
1695              mains on which the relay was blacklisted.
1696
1697
1698       md_get_bogus_mx_hosts($domain)
1699
1700              This  function looks up all the MX records for the specified do‐
1701              main (or A records if there are no MX  records)  and  returns  a
1702              list  of "bogus" IP addresses found amongst the records.  A "bo‐
1703              gus"  IP  address  is  an  IP  address  in  a  private   network
1704              (10.0.0.0/8,  172.16.0.0/12,  192.168.0.0/16), the loopback net‐
1705              work (127.0.0.0/8), local-link for  auto-DHCP  (169.254.0.0/16),
1706              IPv4 multicast (224.0.0.0/4) or reserved (240.0.0.0/4).
1707
1708
1709       Here's how you might use the function in filter_sender:
1710
1711       sub filter_sender {
1712           my ($sender, $ip, $hostname, $helo) = @_;
1713           if ($sender =~ /@([^>]+)/) {
1714               my $domain = $1;
1715               my @bogushosts = md_get_bogus_mx_hosts($domain);
1716               if (scalar(@bogushosts)) {
1717                   return('REJECT', "Domain $domain contains bogus MX record(s) " .
1718                          join(', ', @bogushosts));
1719               }
1720           }
1721           return ('CONTINUE', 'ok');
1722       }
1723
1724

TEST FUNCTIONS

1726       mimedefang.pl includes some "test" functions:
1727
1728
1729       md_version()
1730              returns  the  version  of  MIMEDefang  as a string (for example,
1731              "3.4.1").
1732
1733
1734       message_rejected()
1735              Returns true if any of  action_tempfail,  action_bounce  or  ac‐
1736              tion_discard  have  been  called for this message; returns false
1737              otherwise.
1738
1739
1740       If  you  have  the  Mail::SpamAssassin  Perl  module   installed   (see
1741       https://spamassassin.apache.org)  you  may  call any of the spam_assas‐
1742       sin_* functions.  They should only be called from filter_begin or  fil‐
1743       ter_end because they operate on the entire message at once.  Most func‐
1744       tions use an optionally provided config file.  If  no  config  file  is
1745       provided,  mimedefang.pl will look for one of four default SpamAssassin
1746       preference files.  The first of the following found will be used:
1747
1748
1749       o      /etc/mail/sa-mimedefang.cf
1750
1751       o      /etc/mail/spamassassin/sa-mimedefang.cf
1752
1753       o      /etc/mail/spamassassin/local.cf
1754
1755       o      /etc/mail/spamassassin.cf
1756
1757
1758       Important Note:  MIMEDefang does not permit SpamAssassin to modify mes‐
1759       sages.   If you want to tag spam messages with special headers or alter
1760       the subject line, you must use MIMEDefang functions to do it.   Setting
1761       SpamAssassin configuration options to alter messages will not work.
1762
1763
1764       spam_assassin_is_spam([ $config_file ])
1765              Determine  if  the  current message is SPAM/UCE as determined by
1766              SpamAssassin.  Compares the score of  the  message  against  the
1767              threshold  score  (see  below)  and returns true if it is.  Uses
1768              spam_assassin_check below.
1769
1770
1771       spam_assassin_check([ $config_file ])
1772              This function returns a four-element list of  the  form  ($hits,
1773              $required,  $tests, $report).  $hits is the "score" given to the
1774              message by SpamAssassin (higher score means more  likely  SPAM).
1775              $required  is  the  number  of hits required before SpamAssassin
1776              concludes that the message is SPAM.  $tests is a comma-separated
1777              list  of  SpamAssassin test names, and $report is text detailing
1778              which tests triggered and their point score.  This gives you in‐
1779              sight  into why SpamAssassin concluded that the message is SPAM.
1780              Uses spam_assassin_status below.
1781
1782
1783       spam_assassin_status([ $config_file ])
1784              This function returns a Mail::SpamAssasin::PerMsgStatus  object.
1785              Read  the  SpamAssassin documentation for details about this ob‐
1786              ject.  You are responsible for calling the  finish  method  when
1787              you  are  done with it.  Uses spam_assassin_init and spam_assas‐
1788              sin_mail below.
1789
1790
1791       spam_assassin_init([ $config_file ])
1792              This function returns the new global  Mail::SpamAssassin  object
1793              with  the  specified or default config (outlined above).  If the
1794              global object is already defined, returns it -- does not  change
1795              config  files!   The object can be used to perform other SpamAs‐
1796              sassin related functions.
1797
1798
1799       spam_assassin_mail()
1800              This function returns a  Mail::SpamAssassin::NoMailAudit  object
1801              with  the current email message contained in it.  It may be used
1802              to perform other SpamAssassin related functions.
1803
1804
1805       rspamd_check([ $uri ]) *experimental*
1806              This function returns a six-element list  of  the  form  ($hits,
1807              $required,  $tests,  $report,  $action, $is_spam).  $hits is the
1808              "score" given to the message by Rspamd (higher score means  more
1809              likely  SPAM).  $required  is the number of hits required before
1810              Rspamd concludes that the message is SPAM.  $tests is a list  of
1811              Rspamd  test  names,  and  $report is text detailing which tests
1812              triggered and their point score.  If JSON and  LWP  modules  are
1813              present  $report  will  be  a json string; $action is the action
1814              that rspamd(8) wants to apply and $is_spam is  a  boolean  value
1815              (true/false)  that  determines  if  the  message is spam or not.
1816              This gives you insight into why Rspamd concluded that  the  mes‐
1817              sage is SPAM.
1818
1819
1820       md_copy_orig_msg_to_work_dir()
1821              Normally,  virus-scanners  are passed only the unpacked, decoded
1822              parts of a MIME message.  If you want to pass the original,  un‐
1823              decoded  message  in  as well, call md_copy_orig_msg_to_work_dir
1824              prior to calling message_contains_virus.
1825
1826
1827       md_copy_orig_msg_to_work_dir_as_mbox_file()
1828              Normally, virus-scanners are passed only the  unpacked,  decoded
1829              parts  of a MIME message.  If you want to pass the original, un‐
1830              decoded  message  in  as  a   UNIX-style   "mbox"   file,   call
1831              md_copy_orig_msg_to_work_dir_as_mbox_file  prior to calling mes‐
1832              sage_contains_virus.  The only difference between this  function
1833              and  md_copy_orig_msg_to_work_dir is that this function prepends
1834              a "From_" line to make the message look like a  UNIX-style  mbox
1835              file.   This  is  required for some virus scanners (such as Clam
1836              AntiVirus) to recognize the file as an e-mail message.
1837
1838
1839       message_contains_virus()
1840              This function runs every installed virus-scanner and returns the
1841              scanner results.  The function should be called in list context;
1842              the return value is a three-element list ($code, $category, $ac‐
1843              tion).
1844
1845              $code is the actual return code from the virus scanner.
1846
1847              $category is a string categorizing the return code:
1848
1849              "ok" - no viruses detected.
1850
1851              "not-installed" - indicated virus scanner is not installed.
1852
1853              "cannot-execute" - for some reason, the scanner could not be ex‐
1854              ecuted.
1855
1856              "virus" - a virus was found.
1857
1858              "suspicious" - a "suspicious" file was found.
1859
1860              "interrupted" - scanning was interrupted.
1861
1862              "swerr" - an internal scanner software error occurred.
1863
1864              $action is a string containing the recommended action:
1865
1866              "ok" - allow the message through unmolested.
1867
1868              "quarantine" - a virus was detected; quarantine it.
1869
1870              "tempfail" - something went wrong; tempfail the message.
1871
1872
1873
1874       message_contains_virus_trend()
1875
1876       message_contains_virus_nai()
1877
1878       message_contains_virus_bdc()
1879
1880       message_contains_virus_nvcc()
1881
1882       message_contains_virus_csav()
1883
1884       message_contains_virus_fsav()
1885
1886       message_contains_virus_hbedv()
1887
1888       message_contains_virus_vexira()
1889
1890       message_contains_virus_sophos()
1891
1892       message_contains_virus_clamav()
1893
1894       message_contains_virus_clamdscan()
1895
1896       message_contains_virus_avp()
1897
1898       message_contains_virus_avp5()
1899
1900       message_contains_virus_fprot()
1901
1902       message_contains_virus_fpscan()
1903
1904       message_contains_virus_fprotd()
1905
1906       message_contains_virus_fprotd_v6()
1907
1908       message_contains_virus_nod32()
1909
1910              These functions should be called in list context.  They use  the
1911              indicated  anti-virus  software to scan the message for viruses.
1912              These functions are intended for use in filter_begin()  to  make
1913              an initial scan of the e-mail message.
1914
1915              The supported virus scanners are:
1916
1917       nai    NAI "uvscan" - http://www.nai.com/
1918
1919       Bitdefender "bdc" - http://www.bitdefender.com/
1920
1921       csav   Command Anti-Virus - http://www.commandsoftware.com/
1922
1923       fsav   F-Secure Anti-Virus - http://www.f-secure.com/
1924
1925       hbedv  H+BEDV "AntiVir" - http://www.hbedv.com/
1926
1927       vexira Vexira "Vexira" - http://www.centralcommand.com/
1928
1929       sophos Sophos AntiVirus - http://www.sophos.com/
1930
1931       avp    Kaspersky AVP and aveclient (AVP5) - http://www.avp.ru/
1932
1933       clamav Clam AntiVirus - https://www.clamav.net/
1934
1935       f-prot F-RISK F-PROT - http://www.f-prot.com/
1936
1937       nod32cli
1938              ESET NOD32 - http://www.eset.com/
1939
1940
1941       message_contains_virus_carrier_scan([$host])
1942              Connects  to  the specified host:port:local_or_nonlocal (default
1943              $CSSHost), where the Symantec CarrierScan Server daemon  is  ex‐
1944              pected to be listening.  Return values are the same as the other
1945              message_contains_virus functions.
1946
1947
1948       message_contains_virus_sophie([$sophie_sock])
1949              Connects to the specified socket  (default  $SophieSock),  where
1950              the  Sophie  daemon  is expected to be listening.  Return values
1951              are the same as the other message_contains_virus functions.
1952
1953
1954       message_contains_virus_clamd([$clamd_sock])
1955              Connects to the specified socket (default $ClamdSock), where the
1956              clamd daemon is expected to be listening.  Return values are the
1957              same as the other message_contains_virus functions.
1958
1959
1960       message_contains_virus_trophie([$trophie_sock])
1961              Connects to the specified socket (default  $TrophieSock),  where
1962              the  Trophie  daemon is expected to be listening.  Return values
1963              are the same as the other message_contains_virus functions.
1964
1965
1966       entity_contains_virus($entity)
1967
1968              This function runs the specified MIME::Entity through every  in‐
1969              stalled  virus-scanner and returns the scanner results.  The re‐
1970              turn values are the same as for message_contains_virus().
1971
1972
1973       entity_contains_virus_trend($entity)
1974
1975       entity_contains_virus_nai($entity)
1976
1977       entity_contains_virus_bdc($entity)
1978
1979       entity_contains_virus_nvcc($entity)
1980
1981       entity_contains_virus_csav($entity)
1982
1983       entity_contains_virus_fsav($entity)
1984
1985       entity_contains_virus_hbedv($entity)
1986
1987       entity_contains_virus_sophos($entity)
1988
1989       entity_contains_virus_clamav($entity)
1990
1991       entity_contains_virus_clamdscan($entity)
1992
1993       entity_contains_virus_avp($entity)
1994
1995       entity_contains_virus_avp5($entity)
1996
1997       entity_contains_virus_fprot($entity)
1998
1999       entity_contains_virus_fpscan($entity)
2000
2001       entity_contains_virus_fprotd($entity)
2002
2003       entity_contains_virus_fprotd_v6($entity)
2004
2005       entity_contains_virus_nod32($entity)
2006              These functions, meant to be called from filter(),  are  similar
2007              to  the  message_contains_virus  functions except they scan only
2008              the current part.  They should be called from list context,  and
2009              their  return  values  are  as  described  for  the message_con‐
2010              tains_virus functions.
2011
2012
2013       entity_contains_virus_carrier_scan($entity[, $host])
2014              Connects to the specified  host:port:local_or_nonlocal  (default
2015              $CSSHost),  where  the Symantec CarrierScan Server daemon is ex‐
2016              pected to be listening.  Return values are the same as the other
2017              entity_contains_virus functions.
2018
2019
2020       entity_contains_virus_sophie($entity[, $sophie_sock])
2021              Connects  to  the  specified socket (default $SophieSock), where
2022              the Sophie daemon is expected to be  listening.   Return  values
2023              are the same as the other entity_contains_virus functions.
2024
2025
2026       entity_contains_virus_trophie($entity[, $trophie_sock])
2027              Connects  to  the specified socket (default $TrophieSock), where
2028              the Trophie daemon is expected to be listening.   Return  values
2029              are the same as the other entity_contains_virus functions.
2030
2031
2032       entity_contains_virus_clamd($entity[, $clamd_sock])
2033              Connects to the specified socket (default $ClamdSock), where the
2034              clamd daemon is expected to be listening.  Return values are the
2035              same as the other entity_contains_virus functions.
2036
2037

SMTP FLOW

2039       This section illustrates the flow of messages through MIMEDefang.
2040
2041
2042       1. INITIAL CONNECTION
2043              If  you invoked mimedefang with the -r option and have defined a
2044              filter_relay routine, it is called.
2045
2046
2047       2. SMTP HELO COMMAND
2048              The HELO string is stored internally, but  no  filter  functions
2049              are called.
2050
2051
2052       3. SMTP MAIL FROM: COMMAND
2053              If  you invoked mimedefang with the -s option and have defined a
2054              filter_sender routine, it is called.
2055
2056
2057       4. SMTP RCPT TO: COMMAND
2058              If you invoked mimedefang with the -t option and have defined  a
2059              filter_recipient routine, it is called.
2060
2061
2062       5. END OF SMTP DATA
2063              filter_begin  is  called.  For each MIME part, filter is called.
2064              Then filter_end is called.
2065
2066

PRESERVING RELAY INFORMATION

2068       Most organizations have more than one machine handling internet e-mail.
2069       If  the primary machine is down, mail is routed to a secondary (or ter‐
2070       tiary, etc.) MX server, which stores the mail until the primary MX host
2071       comes back up.  Mail is then relayed to the primary MX host.
2072
2073
2074       Relaying from a secondary to a primary MX host has the unfortunate side
2075       effect of losing the original relay's IP address information.   MIMEDe‐
2076       fang allows you to preserve this information.  One way around the prob‐
2077       lem is to run MIMEDefang on all the secondary MX hosts and use the same
2078       filter.  However, you may not have control over the secondary MX hosts.
2079       If you can persuade the owners of the secondary MX hosts to run MIMEDe‐
2080       fang  with  a  simple  filter that only preserves relay information and
2081       does no other scanning, your primary MX host can obtain relay  informa‐
2082       tion and make decisions using $RelayAddr and $RelayHostname.
2083
2084
2085       When you configure MIMEDefang, supply the "--with-ipheader" argument to
2086       the ./configure script.  When you install  MIMEDefang,  a  file  called
2087       /etc/mail/mimedefang-ip-key  will be created which contains a randomly-
2088       generated header name.  Copy this file to all of your mail relays.   It
2089       is  important  that  all  of  your MX hosts have the same key.  The key
2090       should be kept confidential, but it's not disastrous if it leaks out.
2091
2092
2093       On your secondary MX hosts, add this line to filter_end:
2094
2095            add_ip_validation_header();
2096
2097
2098       Note:  You should only add the validation header to mail  destined  for
2099       one of your other MX hosts!  Otherwise, the validation header will leak
2100       out.
2101
2102
2103       When the secondary MX hosts relay to the primary  MX  host,  $RelayAddr
2104       and  $RelayHostname  will be set based on the IP validation header.  If
2105       MIMEDefang notices this header, it sets the global variable  $WasResent
2106       to  1.   Since  you don't want to trust the header unless it was set by
2107       one of your secondary MX hosts, you should put this code in  filter_be‐
2108       gin:
2109
2110            if ($WasResent) {
2111                 if ($RealRelayAddr ne "ip.of.secondary.mx" and
2112                     $RealRelayAddr ne "ip.of.tertiary.mx") {
2113                      $RelayAddr = $RealRelayAddr;
2114                      $RelayHostname = $RealRelayHostname;
2115                 }
2116            }
2117
2118       This  resets the relay address and hostname to the actual relay address
2119       and hostname, unless the message is coming from one of  your  other  MX
2120       hosts.
2121
2122
2123       On the primary MX host, you should add this in filter_begin:
2124
2125            delete_ip_validation_header();
2126
2127
2128       This prevents the validation header from leaking out to recipients.
2129
2130
2131       Note:  The  IP  validation  header works only in message-oriented func‐
2132       tions.  It (obviously) has no effect on filter_relay, filter_sender and
2133       filter_recipient,  because no header information is available yet.  You
2134       must take this into account when writing your filter;  you  must  defer
2135       relay-based decisions to the message filter for mail arriving from your
2136       other MX hosts.
2137
2138

GLOBAL VARIABLE LIFETIME

2140       The following list describes the lifetime of global  variables  (thanks
2141       to Tony Nugent for providing this documentation.)
2142
2143       If you set a global variable:
2144
2145
2146       Outside a subroutine in your filter file
2147              It is available to all functions, all the time.
2148
2149
2150       In filter_relay, filter_sender or filter_recipient
2151              Not  guaranteed  to be available to any other function, not even
2152              from one filter_recipient call to the  next,  when  receiving  a
2153              multi-recipient email message.
2154
2155
2156       In filter_begin
2157              Available to filter_begin, filter and filter_end
2158
2159
2160       In filter
2161              Available to filter and filter_end
2162
2163
2164       In filter_end
2165              Available within filter_end
2166
2167
2168       The  "built-in"  globals like $Subject, $Sender, etc. are always avail‐
2169       able to filter_begin, filter and filter_end. Some are available to fil‐
2170       ter_relay,  filter_sender or filter_recipient, but you should check the
2171       documentation of the variable above for details.
2172
2173

MAINTAINING STATE

2175       There are four basic groups of filtering functions:
2176
2177
2178       1      filter_relay
2179
2180
2181       2      filter_sender
2182
2183
2184       3      filter_recipient
2185
2186
2187       4      filter_begin, filter, filter_multipart, filter_end
2188
2189
2190       In general, for a given mail message, these groups of functions may  be
2191       called  in  completely different Perl processes.  Thus, there is no way
2192       to maintain state inside Perl between groups of  functions.   That  is,
2193       you cannot set a variable in filter_relay and expect it to be available
2194       in filter_sender, because the filter_sender invocation might take place
2195       in a completely different process.
2196
2197
2198       For a given mail message, it is always the case that filter_begin, fil‐
2199       ter, filter_multipart and  filter_end  are  called  in  the  same  Perl
2200       process.   Therefore, you can use global variables to carry state among
2201       those functions.  You should be very careful to initialize  such  vari‐
2202       ables  in  filter_begin to ensure no data leaks from one message to an‐
2203       other.
2204
2205
2206       Also for a given mail message, the $CWD global variable holds the  mes‐
2207       sage spool directory, and the current working directory is set to $CWD.
2208       Therefore, you can store state in files inside $CWD.  If  filter_sender
2209       stores  data  in a file inside $CWD, then filter_recipient can retrieve
2210       that data.
2211
2212
2213       Since filter_relay is called directly after a mail connection is estab‐
2214       lished,  there  is  no  message  context yet, no per-message mimedefang
2215       spool directory, and the $CWD global is not set. Therefore, it  is  not
2216       possible  to  share  information  from filter_relay to one of the other
2217       filter functions. The only thing that filter_relay has in  common  with
2218       the  other functions are the values in the globals $RelayAddr, and $Re‐
2219       layHostname. These could be used to access per-remote-host  information
2220       in some database.
2221
2222
2223       Inside $CWD, we reserve filenames beginning with upper-case letters for
2224       internal MIMEDefang use.  If you want to create files to  store  state,
2225       name  them beginning with a lower-case letter to avoid clashes with fu‐
2226       ture releases of MIMEDefang.
2227
2228

SOCKET MAPS

2230       If you have Sendmail 8.13 or later, and have compiled it with the SOCK‐
2231       ETMAP  option,  then  you  can use a special map type that communicates
2232       over a socket with another program (rather than looking up a key  in  a
2233       Berkeley database, for example.)
2234
2235
2236       mimedefang-multiplexor  implements  the  Sendmail SOCKETMAP protocol if
2237       you supply the -N option.  In that case,  you  can  define  a  function
2238       called filter_map to implement map lookups.  filter_map takes two argu‐
2239       ments:  $mapname is the name of the Sendmail map (as  given  in  the  K
2240       sendmail configuration directive), and $key is the key to be looked up.
2241
2242
2243       filter_map  must  return a two-element list: ($code, $val) $code can be
2244       one of:
2245
2246
2247       OK     The lookup was successful.  In this case, $val must be  the  re‐
2248              sult of the lookup
2249
2250
2251       NOTFOUND
2252              The  lookup  was unsuccessful -- the key was not found.  In this
2253              case, $val should be the empty string.
2254
2255
2256       TEMP   There was a temporary failure of some kind.  $val can be an  ex‐
2257              planatory error message.
2258
2259
2260       TIMEOUT
2261              There  was  a  timeout of some kind.  $val can be an explanatory
2262              error message.
2263
2264
2265       PERM   There was a permanent failure.  This is not the same as  an  un‐
2266              successful  lookup; it should be used only to indicate a serious
2267              misconfiguration.  As before, $val can be an  explanatory  error
2268              message.
2269
2270
2271       Consider  this small example.  Here is a minimal Sendmail configuration
2272       file:
2273
2274            V10/Berkeley
2275            Kmysock socket unix:/var/spool/MIMEDefang/map.sock
2276            kothersock socket unix:/var/spool/MIMEDefang/map.sock
2277
2278
2279       If  mimedefang-multiplexor   is   invoked   with   the   arguments   -N
2280       unix:/var/spool/MIMEDefang/map.sock,  and the filter defines filter_map
2281       as follows:
2282
2283            sub filter_map ($$) {
2284                my($mapname, $key) = @_;
2285                my $ans;
2286                if($mapname ne "mysock") {
2287                    return("PERM", "Unknown map $mapname");
2288                }
2289                $ans = reverse($key);
2290                return ("OK", $ans);
2291            }
2292
2293       Then in Sendmail's testing mode, we see the following:
2294
2295            > /map mysock testing123
2296            map_lookup: mysock (testing123) returns 321gnitset (0)
2297            > /map othersock foo
2298            map_lookup: othersock (foo) no match (69)
2299
2300
2301       (The return code of 69 means EX_UNAVAILABLE or Service Unavailable)
2302
2303
2304       A real-world example could do map lookups in an LDAP directory  or  SQL
2305       database, or perform other kinds of processing.  You can even implement
2306       standard Sendmail maps like virtusertable, mailertable, access_db, etc.
2307       using SOCKETMAP.
2308
2309

TICK REQUESTS

2311       If  you  supply  the -X option to mimedefang-multiplexor, then every so
2312       often, a "tick" request is sent to a free worker.  If your  filter  de‐
2313       fines  a function called filter_tick, then this function is called with
2314       a single argument: the tick type.  If you run multiple parallel  ticks,
2315       then  each tick has a type ranging from 0 to n-1, where n is the number
2316       of parallel ticks.  If you're only running one tick request,  then  the
2317       argument to filter_tick is always 0.
2318
2319       You can use this facility to run periodic tasks from within MIMEDefang.
2320       Note, however, that you have no control over which worker is picked  to
2321       run  filter_tick.  Also, at most one filter_tick call with a particular
2322       "type" argument will be active at any time, and if there  are  no  free
2323       workers when a tick would occur, the tick is skipped.
2324
2325

SUPPORTED VIRUS SCANNERS

2327       The following virus scanners are supported by MIMEDefang:
2328
2329
2330       o      Symantec    CarrierScan    Server   (http://www.symantec.com/re
2331              gion/can/eng/product/scs/)
2332
2333
2334       o      Trend Micro vscan (http://www.antivirus.com/)
2335
2336
2337       o      Sophos   Sweep   (http://www.sophos.com/products/antivirus/savu
2338              nix.html)
2339
2340
2341       o      H+BEDV AntiVir (http://www.hbedv.com/)
2342
2343
2344       o      Central Command Vexira (http://www.centralcommand.com/)
2345
2346
2347       o      NAI uvscan (http://www.nai.com)
2348
2349
2350       o      Bitdefender bdc (http://www.bitdefender.com)
2351
2352
2353       o      Norman Virus Control (NVCC) (http://www.norman.no/)
2354
2355
2356       o      Command csav (http://www.commandsoftware.com)
2357
2358
2359       o      F-Secure fsav (http://www.f-secure.com)
2360
2361
2362       o      The  clamscan  and clamdscan command-line scanners and the clamd
2363              daemon from Clam AntiVirus (https://www.clamav.net/)
2364
2365
2366       o      Kaspersky Anti-Virus (AVP) (http://www.kaspersky.com/)
2367
2368
2369       o      F-Risk F-Prot (http://www.f-prot.com/)
2370
2371
2372       o      F-Risk F-Prot v6 (http://www.f-prot.com/)
2373
2374
2375
2376       o      F-Risk FPROTD (daemonized version of F-Prot)
2377
2378
2379       o      Symantec    CarrierScan    Server    (http://www.symantec.ca/re
2380              gion/can/eng/product/scs/buymenu.html)
2381
2382
2383       o      Sophie (http://www.vanja.com/tools/sophie/), which uses the lib‐
2384              savi library from Sophos, is supported in daemon-scanning mode.
2385
2386
2387       o      Trophie (http://www.vanja.com/tools/trophie/),  which  uses  the
2388              libvsapi  library from Trend Micro, is supported in daemon-scan‐
2389              ning mode.
2390
2391
2392       o      ESET NOD32 (http://www.eset.com/)
2393
2394

AUTHORS

2396       mimedefang was written by Dianne Skoll  <dfs@roaringpenguin.com>.   The
2397       mimedefang home page is https://www.mimedefang.org/.
2398
2399

SEE ALSO

2401       mimedefang(8), mimedefang.pl(8), Mail::MIMEDefang(3)
2402
2403
2404
2405
2406
2407
24084th Berkeley Distribution       8 February 2005           MIMEDEFANG-FILTER(5)
Impressum