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.
718
719

GLOBAL VARIABLES SET BY MIMEDEFANG.PL

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

ACTIONS

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

USEFUL ROUTINES

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

LOGGING

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

RBL LOOKUP FUNCTIONS

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

TEST FUNCTIONS

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

SMTP FLOW

2028       This section illustrates the flow of messages through MIMEDefang.
2029
2030
2031       1. INITIAL CONNECTION
2032              If you invoked mimedefang with the -r option and have defined  a
2033              filter_relay routine, it is called.
2034
2035
2036       2. SMTP HELO COMMAND
2037              The  HELO  string  is stored internally, but no filter functions
2038              are called.
2039
2040
2041       3. SMTP MAIL FROM: COMMAND
2042              If you invoked mimedefang with the -s option and have defined  a
2043              filter_sender routine, it is called.
2044
2045
2046       4. SMTP RCPT TO: COMMAND
2047              If  you invoked mimedefang with the -t option and have defined a
2048              filter_recipient routine, it is called.
2049
2050
2051       5. END OF SMTP DATA
2052              filter_begin is called.  For each MIME part, filter  is  called.
2053              Then filter_end is called.
2054
2055

PRESERVING RELAY INFORMATION

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

GLOBAL VARIABLE LIFETIME

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

MAINTAINING STATE

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

SOCKET MAPS

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

TICK REQUESTS

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

SUPPORTED VIRUS SCANNERS

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

AUTHORS

2385       mimedefang  was  written by Dianne Skoll <dfs@roaringpenguin.com>.  The
2386       mimedefang home page is http://www.mimedefang.org/.
2387
2388

SEE ALSO

2390       mimedefang(8), mimedefang.pl(8)
2391
2392
2393
2394
2395
2396
23974th Berkeley Distribution       8 February 2005           MIMEDEFANG-FILTER(5)
Impressum