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 (deprecated); 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.86").
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([ $uri ]) *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.  If JSON and LWP modules are
1804              present $report will be a json string;  $action  is  the  action
1805              that  rspamd(8)  wants  to apply and $is_spam is a boolean value
1806              (true/false) that determines if the  message  is  spam  or  not.
1807              This  gives  you insight into why Rspamd concluded that the mes‐
1808              sage is SPAM.
1809
1810
1811       md_copy_orig_msg_to_work_dir()
1812              Normally, virus-scanners are passed only the  unpacked,  decoded
1813              parts  of a MIME message.  If you want to pass the original, un‐
1814              decoded message in as  well,  call  md_copy_orig_msg_to_work_dir
1815              prior to calling message_contains_virus.
1816
1817
1818       md_copy_orig_msg_to_work_dir_as_mbox_file()
1819              Normally,  virus-scanners  are passed only the unpacked, decoded
1820              parts of a MIME message.  If you want to pass the original,  un‐
1821              decoded   message   in   as   a  UNIX-style  "mbox"  file,  call
1822              md_copy_orig_msg_to_work_dir_as_mbox_file prior to calling  mes‐
1823              sage_contains_virus.   The only difference between this function
1824              and md_copy_orig_msg_to_work_dir is that this function  prepends
1825              a  "From_"  line to make the message look like a UNIX-style mbox
1826              file.  This is required for some virus scanners  (such  as  Clam
1827              AntiVirus) to recognize the file as an e-mail message.
1828
1829
1830       message_contains_virus()
1831              This function runs every installed virus-scanner and returns the
1832              scanner results.  The function should be called in list context;
1833              the return value is a three-element list ($code, $category, $ac‐
1834              tion).
1835
1836              $code is the actual return code from the virus scanner.
1837
1838              $category is a string categorizing the return code:
1839
1840              "ok" - no viruses detected.
1841
1842              "not-installed" - indicated virus scanner is not installed.
1843
1844              "cannot-execute" - for some reason, the scanner could not be ex‐
1845              ecuted.
1846
1847              "virus" - a virus was found.
1848
1849              "suspicious" - a "suspicious" file was found.
1850
1851              "interrupted" - scanning was interrupted.
1852
1853              "swerr" - an internal scanner software error occurred.
1854
1855              $action is a string containing the recommended action:
1856
1857              "ok" - allow the message through unmolested.
1858
1859              "quarantine" - a virus was detected; quarantine it.
1860
1861              "tempfail" - something went wrong; tempfail the message.
1862
1863
1864
1865       message_contains_virus_trend()
1866
1867       message_contains_virus_nai()
1868
1869       message_contains_virus_bdc()
1870
1871       message_contains_virus_nvcc()
1872
1873       message_contains_virus_csav()
1874
1875       message_contains_virus_fsav()
1876
1877       message_contains_virus_hbedv()
1878
1879       message_contains_virus_vexira()
1880
1881       message_contains_virus_sophos()
1882
1883       message_contains_virus_clamav()
1884
1885       message_contains_virus_clamdscan()
1886
1887       message_contains_virus_avp()
1888
1889       message_contains_virus_avp5()
1890
1891       message_contains_virus_fprot()
1892
1893       message_contains_virus_fpscan()
1894
1895       message_contains_virus_fprotd()
1896
1897       message_contains_virus_fprotd_v6()
1898
1899       message_contains_virus_nod32()
1900
1901              These  functions should be called in list context.  They use the
1902              indicated anti-virus software to scan the message  for  viruses.
1903              These  functions  are intended for use in filter_begin() to make
1904              an initial scan of the e-mail message.
1905
1906              The supported virus scanners are:
1907
1908       nai    NAI "uvscan" - http://www.nai.com/
1909
1910       Bitdefender "bdc" - http://www.bitdefender.com/
1911
1912       csav   Command Anti-Virus - http://www.commandsoftware.com/
1913
1914       fsav   F-Secure Anti-Virus - http://www.f-secure.com/
1915
1916       hbedv  H+BEDV "AntiVir" - http://www.hbedv.com/
1917
1918       vexira Vexira "Vexira" - http://www.centralcommand.com/
1919
1920       sophos Sophos AntiVirus - http://www.sophos.com/
1921
1922       avp    Kaspersky AVP and aveclient (AVP5) - http://www.avp.ru/
1923
1924       clamav Clam AntiVirus - http://www.clamav.net/
1925
1926       f-prot F-RISK F-PROT - http://www.f-prot.com/
1927
1928       nod32cli
1929              ESET NOD32 - http://www.eset.com/
1930
1931
1932       message_contains_virus_carrier_scan([$host])
1933              Connects to the specified  host:port:local_or_nonlocal  (default
1934              $CSSHost),  where  the Symantec CarrierScan Server daemon is ex‐
1935              pected to be listening.  Return values are the same as the other
1936              message_contains_virus functions.
1937
1938
1939       message_contains_virus_sophie([$sophie_sock])
1940              Connects  to  the  specified socket (default $SophieSock), where
1941              the Sophie daemon is expected to be  listening.   Return  values
1942              are the same as the other message_contains_virus functions.
1943
1944
1945       message_contains_virus_clamd([$clamd_sock])
1946              Connects to the specified socket (default $ClamdSock), where the
1947              clamd daemon is expected to be listening.  Return values are the
1948              same as the other message_contains_virus functions.
1949
1950
1951       message_contains_virus_trophie([$trophie_sock])
1952              Connects  to  the specified socket (default $TrophieSock), where
1953              the Trophie daemon is expected to be listening.   Return  values
1954              are the same as the other message_contains_virus functions.
1955
1956
1957       entity_contains_virus($entity)
1958
1959              This  function runs the specified MIME::Entity through every in‐
1960              stalled virus-scanner and returns the scanner results.  The  re‐
1961              turn values are the same as for message_contains_virus().
1962
1963
1964       entity_contains_virus_trend($entity)
1965
1966       entity_contains_virus_nai($entity)
1967
1968       entity_contains_virus_bdc($entity)
1969
1970       entity_contains_virus_nvcc($entity)
1971
1972       entity_contains_virus_csav($entity)
1973
1974       entity_contains_virus_fsav($entity)
1975
1976       entity_contains_virus_hbedv($entity)
1977
1978       entity_contains_virus_sophos($entity)
1979
1980       entity_contains_virus_clamav($entity)
1981
1982       entity_contains_virus_clamdscan($entity)
1983
1984       entity_contains_virus_avp($entity)
1985
1986       entity_contains_virus_avp5($entity)
1987
1988       entity_contains_virus_fprot($entity)
1989
1990       entity_contains_virus_fpscan($entity)
1991
1992       entity_contains_virus_fprotd($entity)
1993
1994       entity_contains_virus_fprotd_v6($entity)
1995
1996       entity_contains_virus_nod32($entity)
1997              These  functions,  meant to be called from filter(), are similar
1998              to the message_contains_virus functions except  they  scan  only
1999              the  current part.  They should be called from list context, and
2000              their return  values  are  as  described  for  the  message_con‐
2001              tains_virus functions.
2002
2003
2004       entity_contains_virus_carrier_scan($entity[, $host])
2005              Connects  to  the specified host:port:local_or_nonlocal (default
2006              $CSSHost), where the Symantec CarrierScan Server daemon  is  ex‐
2007              pected to be listening.  Return values are the same as the other
2008              entity_contains_virus functions.
2009
2010
2011       entity_contains_virus_sophie($entity[, $sophie_sock])
2012              Connects to the specified socket  (default  $SophieSock),  where
2013              the  Sophie  daemon  is expected to be listening.  Return values
2014              are the same as the other entity_contains_virus functions.
2015
2016
2017       entity_contains_virus_trophie($entity[, $trophie_sock])
2018              Connects to the specified socket (default  $TrophieSock),  where
2019              the  Trophie  daemon is expected to be listening.  Return values
2020              are the same as the other entity_contains_virus functions.
2021
2022
2023       entity_contains_virus_clamd($entity[, $clamd_sock])
2024              Connects to the specified socket (default $ClamdSock), where the
2025              clamd daemon is expected to be listening.  Return values are the
2026              same as the other entity_contains_virus functions.
2027
2028

SMTP FLOW

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

PRESERVING RELAY INFORMATION

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

GLOBAL VARIABLE LIFETIME

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

MAINTAINING STATE

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

SOCKET MAPS

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

TICK REQUESTS

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

SUPPORTED VIRUS SCANNERS

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

AUTHORS

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

SEE ALSO

2392       mimedefang(8), mimedefang.pl(8)
2393
2394
2395
2396
2397
2398
23994th Berkeley Distribution       8 February 2005           MIMEDEFANG-FILTER(5)
Impressum