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 five 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 three arguments to  filter_relay  are  $port,  $myip  and
128       $myport which contain the client's TCP port, the Sendmail daemon's lis‐
129       tening IP address and the Sendmail daemon's listening port.
130
131
132       filter_relay must return a two-element list: ($code, $msg).  $msg spec‐
133       ifies  the text message to use for the SMTP reply, but because of limi‐
134       tations in the Milter API, this message is for  documentation  purposes
135       only---you cannot set the text of the SMTP message returned to the SMTP
136       client from filter_relay.
137
138       $code is a literal string, and can have one of the following values:
139
140
141       'REJECT'
142              if the connection should be rejected.
143
144
145       'CONTINUE'
146              if the connection should be accepted.
147
148
149       'TEMPFAIL'
150              if a temporary failure code should be returned.
151
152
153       'DISCARD'
154              if the message should be accepted and silently discarded.
155
156
157       'ACCEPT_AND_NO_MORE_FILTERING'
158              if the connection should be accepted and  no  further  filtering
159              done.
160
161
162       Earlier versions of MIMEDefang used -1 for TEMPFAIL, 0 for REJECT and 1
163       for CONTINUE.  These values still work, but are deprecated.
164
165
166       In the case of REJECT or TEMPFAIL, $msg specifies the text part of  the
167       SMTP reply.  $msg must not contain newlines.
168
169
170       For example, if you wish to reject connection attempts from any machine
171       in the spammer.com domain, you could use this function:
172
173       sub filter_relay {
174            my ($ip, $name) = @_;
175            if ($name =~ /spammer\.com$/) {
176                 return ('REJECT', "Sorry; spammer.com is blacklisted");
177            }
178            return ('CONTINUE', "ok");
179       }
180
181

FILTERING BY HELO

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

FILTERING BY SENDER

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

FILTERING BY RECIPIENT

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

INITIALIZATION AND CLEANUP

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

CONTROLLING PARSING

370       If you define a function called filter_create_parser  taking  no  argu‐
371       ments,  then mimedefang.pl will call it to create a MIME::Parser object
372       for parsing mail messages.
373
374       Filter_create_parser is expected to return a MIME::Parser object (or an
375       instance of a class derived from MIME::Parser).
376
377       You  can  use  filter_create_parser  to  change  the  behavior  of  the
378       MIME::Parser used by mimedefang.pl.
379
380       If you do not define a filter_create_parser function, then  a  built-in
381       version equivalent to this is used:
382
383            sub filter_create_parser () {
384                 my $parser = MIME::Parser->new();
385                 $parser->extract_nested_messages(1);
386                 $parser->extract_uuencode(1);
387                 $parser->output_to_core(0);
388                 $parser->tmp_to_core(0);
389                 return $parser;
390            }
391

EXTENDING MIMEDEFANG

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

REJECTING UNKNOWN USERS EARLY

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

GLOBAL VARIABLES YOU CAN SET

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

FILTER

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

GLOBAL VARIABLES SET BY MIMEDEFANG.PL

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

ACTIONS

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

USEFUL ROUTINES

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

LOGGING

1497       md_graphdefang_log_enable($facility, $enum_recips)
1498              Enables the md_graphdefang_log function (described  next).   The
1499              function  logs  to  syslog using the specified facility.  If you
1500              omit $facility, it defaults to  'mail'.   If  you  do  not  call
1501              md_graphdefang_log_enable  in  your  filter,  then  any calls to
1502              md_graphdefang_log simply do nothing.
1503
1504              If you supply $enum_recips as 1, then a line of logging is  out‐
1505              put  for  each recipient of a mail message.  If it is zero, then
1506              only a single line is output for  each  message.   If  you  omit
1507              $enum_recips, it defaults to 1.
1508
1509
1510       md_graphdefang_log($event, $v1, $v2)
1511              Logs  an  event  with  up to two optional additional parameters.
1512              The log message has a specific format useful for graphing tools;
1513              the message looks like this:
1514
1515                   MDLOG,msgid,event,v1,v2,sender,recipient,subj
1516
1517              "MDLOG"  is literal text.  "msgid" is the Sendmail queue identi‐
1518              fier.  "event" is the event name, and  "v1"  and  "v2"  are  the
1519              additional parameters.  "sender" is the sender's e-mail address.
1520              "recipient" is the recipient's e-mail address, and "subj" is the
1521              message  subject.   If  a  message  has more than one recipient,
1522              md_graphdefang_log may log an event message for each  recipient,
1523              depending on how you called md_graphdefang_log_enable.
1524
1525              Note that md_graphdefang_log should not be used in filter_relay,
1526              filter_sender or  filter_recipient.   The  global  variables  it
1527              relies on are not valid in that context.
1528
1529              If  you want to log general text strings, do not use md_graphde‐
1530              fang_log.  Instead, use md_syslog (described next).
1531
1532
1533       md_syslog($level, $msg)
1534              Logs the message $msg to syslog, using level $level.  The  level
1535              is a literal string, and should be one of 'err', 'debug', 'warn‐
1536              ing', ´emerg', 'crit', 'notice' or 'info'.  (See  syslog(3)  for
1537              details.)
1538
1539              Note  that  md_syslog  does not perform %-subsitutions like sys‐
1540              log(3) does.  Depending on  your  Perl  installation,  md_syslog
1541              boils  down  to  a  call  to  Unix::Syslog::syslog  or Sys::Sys‐
1542              log::syslog.  See the Unix::Syslog or Sys::Syslog man pages  for
1543              more details.
1544
1545
1546       md_openlog($tag, $facility)
1547              Sets the tag used in syslog messages to $tag, and sends the logs
1548              to the $facility facility.  If you do not call md_openlog before
1549              you  call  md_syslog, then it is called implicitly with $tag set
1550              to mimedefang.pl and $facility set to mail.
1551
1552

RBL LOOKUP FUNCTIONS

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

TEST FUNCTIONS

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

SMTP FLOW

1983       This section illustrates the flow of messages through MIMEDefang.
1984
1985
1986       1. INITIAL CONNECTION
1987              If  you invoked mimedefang with the -r option and have defined a
1988              filter_relay routine, it is called.
1989
1990
1991       2. SMTP HELO COMMAND
1992              The HELO string is stored internally, but  no  filter  functions
1993              are called.
1994
1995
1996       3. SMTP MAIL FROM: COMMAND
1997              If  you invoked mimedefang with the -s option and have defined a
1998              filter_sender routine, it is called.
1999
2000
2001       4. SMTP RCPT TO: COMMAND
2002              If you invoked mimedefang with the -t option and have defined  a
2003              filter_recipient routine, it is called.
2004
2005
2006       5. END OF SMTP DATA
2007              filter_begin  is  called.  For each MIME part, filter is called.
2008              Then filter_end is called.
2009
2010

PRESERVING RELAY INFORMATION

2012       Most organizations have more than one machine handling internet e-mail.
2013       If  the primary machine is down, mail is routed to a secondary (or ter‐
2014       tiary, etc.) MX server, which stores the mail until the primary MX host
2015       comes back up.  Mail is then relayed to the primary MX host.
2016
2017
2018       Relaying from a secondary to a primary MX host has the unfortunate side
2019       effect of losing the original relay's IP address information.   MIMEDe‐
2020       fang allows you to preserve this information.  One way around the prob‐
2021       lem is to run MIMEDefang on all the secondary MX hosts and use the same
2022       filter.  However, you may not have control over the secondary MX hosts.
2023       If you can persuade the owners of the secondary MX hosts to run MIMEDe‐
2024       fang  with  a  simple  filter that only preserves relay information and
2025       does no other scanning, your primary MX host can obtain relay  informa‐
2026       tion and make decisions using $RelayAddr and $RelayHostname.
2027
2028
2029       When you configure MIMEDefang, supply the "--with-ipheader" argument to
2030       the ./configure script.  When you install  MIMEDefang,  a  file  called
2031       /etc/mail/mimedefang-ip-key  will be created which contains a randomly-
2032       generated header name.  Copy this file to all of your mail relays.   It
2033       is  important  that  all  of  your MX hosts have the same key.  The key
2034       should be kept confidential, but it's not disastrous if it leaks out.
2035
2036
2037       On your secondary MX hosts, add this line to filter_end:
2038
2039            add_ip_validation_header();
2040
2041
2042       Note:  You should only add the validation header to mail  destined  for
2043       one of your other MX hosts!  Otherwise, the validation header will leak
2044       out.
2045
2046
2047       When the secondary MX hosts relay to the primary  MX  host,  $RelayAddr
2048       and  $RelayHostname  will be set based on the IP validation header.  If
2049       MIMEDefang notices this header, it sets the global variable  $WasResent
2050       to  1.   Since  you don't want to trust the header unless it was set by
2051       one of your secondary MX hosts,  you  should  put  this  code  in  fil‐
2052       ter_begin:
2053
2054            if ($WasResent) {
2055                 if ($RealRelayAddr ne "ip.of.secondary.mx" and
2056                     $RealRelayAddr ne "ip.of.tertiary.mx") {
2057                      $RelayAddr = $RealRelayAddr;
2058                      $RelayHostname = $RealRelayHostname;
2059                 }
2060            }
2061
2062       This  resets the relay address and hostname to the actual relay address
2063       and hostname, unless the message is coming from one of  your  other  MX
2064       hosts.
2065
2066
2067       On the primary MX host, you should add this in filter_begin:
2068
2069            delete_ip_validation_header();
2070
2071
2072       This prevents the validation header from leaking out to recipients.
2073
2074
2075       Note:  The  IP  validation  header works only in message-oriented func‐
2076       tions.  It (obviously) has no effect on filter_relay, filter_sender and
2077       filter_recipient,  because no header information is available yet.  You
2078       must take this into account when writing your filter;  you  must  defer
2079       relay-based decisions to the message filter for mail arriving from your
2080       other MX hosts.
2081
2082

GLOBAL VARIABLE LIFETIME

2084       The following list describes the lifetime of global  variables  (thanks
2085       to Tony Nugent for providing this documentation.)
2086
2087       If you set a global variable:
2088
2089
2090       Outside a subroutine in your filter file
2091              It is available to all functions, all the time.
2092
2093
2094       In filter_relay, filter_sender or filter_recipient
2095              Not  guaranteed  to be available to any other function, not even
2096              from one filter_recipient call to the  next,  when  receiving  a
2097              multi-recipient email message.
2098
2099
2100       In filter_begin
2101              Available to filter_begin, filter and filter_end
2102
2103
2104       In filter
2105              Available to filter and filter_end
2106
2107
2108       In filter_end
2109              Available within filter_end
2110
2111
2112       The  "built-in"  globals like $Subject, $Sender, etc. are always avail‐
2113       able to filter_begin, filter and filter_end. Some are available to fil‐
2114       ter_relay,  filter_sender or filter_recipient, but you should check the
2115       documentation of the variable above for details.
2116
2117

MAINTAINING STATE

2119       There are four basic groups of filtering functions:
2120
2121
2122       1      filter_relay
2123
2124
2125       2      filter_sender
2126
2127
2128       3      filter_recipient
2129
2130
2131       4      filter_begin, filter, filter_multipart, filter_end
2132
2133
2134       In general, for a given mail message, these groups of functions may  be
2135       called  in  completely different Perl processes.  Thus, there is no way
2136       to maintain state inside Perl between groups of  functions.   That  is,
2137       you cannot set a variable in filter_relay and expect it to be available
2138       in filter_sender, because the filter_sender invocation might take place
2139       in a completely different process.
2140
2141
2142       For a given mail message, it is always the case that filter_begin, fil‐
2143       ter, filter_multipart and  filter_end  are  called  in  the  same  Perl
2144       process.   Therefore, you can use global variables to carry state among
2145       those functions.  You should be very careful to initialize  such  vari‐
2146       ables  in  filter_begin  to  ensure  no  data leaks from one message to
2147       another.
2148
2149
2150       Also for a given mail message, the $CWD global variable holds the  mes‐
2151       sage spool directory, and the current working directory is set to $CWD.
2152       Therefore, you can store state in files inside $CWD.  If  filter_sender
2153       stores  data  in a file inside $CWD, then filter_recipient can retrieve
2154       that data.
2155
2156
2157       Since filter_relay is called directly after a mail connection is estab‐
2158       lished,  there  is  no  message  context yet, no per-message mimedefang
2159       spool directory, and the $CWD global is not set. Therefore, it  is  not
2160       possible  to  share  information  from filter_relay to one of the other
2161       filter functions. The only thing that filter_relay has in  common  with
2162       the  other  functions  are  the  values  in the globals $RelayAddr, and
2163       $RelayHostname. These could be used to access per-remote-host  informa‐
2164       tion in some database.
2165
2166
2167       Inside $CWD, we reserve filenames beginning with upper-case letters for
2168       internal MIMEDefang use.  If you want to create files to  store  state,
2169       name  them  beginning  with  a  lower-case letter to avoid clashes with
2170       future releases of MIMEDefang.
2171
2172

SOCKET MAPS

2174       If you have Sendmail 8.13 or later, and have compiled it with the SOCK‐
2175       ETMAP  option,  then  you  can use a special map type that communicates
2176       over a socket with another program (rather than looking up a key  in  a
2177       Berkeley database, for example.)
2178
2179
2180       mimedefang-multiplexor  implements  the  Sendmail SOCKETMAP protocol if
2181       you supply the -N option.  In that case,  you  can  define  a  function
2182       called filter_map to implement map lookups.  filter_map takes two argu‐
2183       ments:  $mapname is the name of the Sendmail map (as  given  in  the  K
2184       sendmail configuration directive), and $key is the key to be looked up.
2185
2186
2187       filter_map  must  return a two-element list: ($code, $val) $code can be
2188       one of:
2189
2190
2191       OK     The lookup was successful.  In  this  case,  $val  must  be  the
2192              result of the lookup
2193
2194
2195       NOTFOUND
2196              The  lookup  was unsuccessful -- the key was not found.  In this
2197              case, $val should be the empty string.
2198
2199
2200       TEMP   There was a temporary failure of some  kind.   $val  can  be  an
2201              explanatory error message.
2202
2203
2204       TIMEOUT
2205              There  was  a  timeout of some kind.  $val can be an explanatory
2206              error message.
2207
2208
2209       PERM   There was a permanent failure.  This  is  not  the  same  as  an
2210              unsuccessful  lookup; it should be used only to indicate a seri‐
2211              ous misconfiguration.  As before, $val  can  be  an  explanatory
2212              error message.
2213
2214
2215       Consider  this small example.  Here is a minimal Sendmail configuration
2216       file:
2217
2218            V10/Berkeley
2219            Kmysock socket unix:/var/spool/MIMEDefang/map.sock
2220            kothersock socket unix:/var/spool/MIMEDefang/map.sock
2221
2222
2223       If  mimedefang-multiplexor   is   invoked   with   the   arguments   -N
2224       unix:/var/spool/MIMEDefang/map.sock,  and the filter defines filter_map
2225       as follows:
2226
2227            sub filter_map ($$) {
2228                my($mapname, $key) = @_;
2229                my $ans;
2230                if($mapname ne "mysock") {
2231                    return("PERM", "Unknown map $mapname");
2232                }
2233                $ans = reverse($key);
2234                return ("OK", $ans);
2235            }
2236
2237       Then in Sendmail's testing mode, we see the following:
2238
2239            > /map mysock testing123
2240            map_lookup: mysock (testing123) returns 321gnitset (0)
2241            > /map othersock foo
2242            map_lookup: othersock (foo) no match (69)
2243
2244
2245       (The return code of 69 means EX_UNAVAILABLE or Service Unavailable)
2246
2247
2248       A real-world example could do map lookups in an LDAP directory  or  SQL
2249       database, or perform other kinds of processing.  You can even implement
2250       standard Sendmail maps like virtusertable, mailertable, access_db, etc.
2251       using SOCKETMAP.
2252
2253

TICK REQUESTS

2255       If  you  supply  the -X option to mimedefang-multiplexor, then every so
2256       often, a "tick" request is sent to  a  free  worker.   If  your  filter
2257       defines  a  function  called  filter_tick, then this function is called
2258       with a single argument: the tick type.  If you  run  multiple  parallel
2259       ticks,  then each tick has a type ranging from 0 to n-1, where n is the
2260       number of parallel ticks.  If you're only  running  one  tick  request,
2261       then the argument to filter_tick is always 0.
2262
2263       You can use this facility to run periodic tasks from within MIMEDefang.
2264       Note, however, that you have no control over which worker is picked  to
2265       run  filter_tick.  Also, at most one filter_tick call with a particular
2266       "type" argument will be active at any time, and if there  are  no  free
2267       workers when a tick would occur, the tick is skipped.
2268
2269

SUPPORTED VIRUS SCANNERS

2271       The following virus scanners are supported by MIMEDefang:
2272
2273
2274       o      Symantec       CarrierScan       Server       (http://www.syman
2275              tec.com/region/can/eng/product/scs/)
2276
2277
2278       o      Trend Micro vscan (http://www.antivirus.com/)
2279
2280
2281       o      Sophos   Sweep   (http://www.sophos.com/products/antivirus/savu
2282              nix.html)
2283
2284
2285       o      H+BEDV AntiVir (http://www.hbedv.com/)
2286
2287
2288       o      Central Command Vexira (http://www.centralcommand.com/)
2289
2290
2291       o      NAI uvscan (http://www.nai.com)
2292
2293
2294       o      Bitdefender bdc (http://www.bitdefender.com)
2295
2296
2297       o      Norman Virus Control (NVCC) (http://www.norman.no/)
2298
2299
2300       o      Command csav (http://www.commandsoftware.com)
2301
2302
2303       o      F-Secure fsav (http://www.f-secure.com)
2304
2305
2306       o      The clamscan command-line scanner and the clamd daemon from Clam
2307              AntiVirus (http://www.clamav.net/)
2308
2309
2310       o      Kaspersky Anti-Virus (AVP) (http://www.kaspersky.com/)
2311
2312
2313       o      F-Risk F-Prot (http://www.f-prot.com/)
2314
2315
2316       o      F-Risk F-Prot v6 (http://www.f-prot.com/)
2317
2318
2319
2320       o      F-Risk FPROTD (daemonized version of F-Prot)
2321
2322
2323       o      Symantec       CarrierScan       Server       (http://www.syman
2324              tec.ca/region/can/eng/product/scs/buymenu.html)
2325
2326
2327       o      Sophie (http://www.vanja.com/tools/sophie/), which uses the lib‐
2328              savi library from Sophos, is supported in daemon-scanning mode.
2329
2330
2331       o      Trophie (http://www.vanja.com/tools/trophie/),  which  uses  the
2332              libvsapi  library from Trend Micro, is supported in daemon-scan‐
2333              ning mode.
2334
2335
2336       o      ESET NOD32 (http://www.eset.com/)
2337
2338

AUTHORS

2340       mimedefang was written by Dianne Skoll  <dfs@roaringpenguin.com>.   The
2341       mimedefang home page is http://www.mimedefang.org/.
2342
2343

SEE ALSO

2345       mimedefang(8), mimedefang.pl(8)
2346
2347
2348
2349
2350
2351
23524th Berkeley Distribution       8 February 2005           MIMEDEFANG-FILTER(5)
Impressum