1MIMEDEFANG-FILTER(5) File Formats Manual MIMEDEFANG-FILTER(5)
2
3
4
6 mimedefang-filter - Configuration file for MIMEDefang mail filter.
7
8
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
17 Incoming messages are scanned as follows:
18
19
20 1) A temporary working directory is created. It is made the current
21 working directory and the e-mail message is split into parts in this
22 directory. Each part is represented internally as an instance of
23 MIME::Entity.
24
25
26 2) If the file /etc/mail/mimedefang-filter.pl defines a Perl function
27 called filter_begin, it is called with a single argument consisting of
28 a MIME::Entity representing the parsed e-mail message. Any return
29 value is ignored.
30
31
32 3) For each leaf part of the mail message, filter is called with four
33 arguments: entity, a MIME::Entity object; fname, the suggested filename
34 taken from the MIME Content-Disposition header; ext, the file exten‐
35 sion, and type, the MIME Content-Type value. For each non-leaf part of
36 the mail message, filter_multipart is called with the same four argu‐
37 ments as filter. A non-leaf part of a message is a part that contains
38 nested parts. Such a part has no useful body, but you should still
39 perform filename checks to check for viruses that use malformed MIME to
40 masquerade as non-leaf parts (like message/rfc822). In general, any
41 action you perform in filter_multipart applies to the part itself and
42 any contained parts.
43
44
45 Note that both filter and filter_multipart are optional. If you do not
46 define them, a default function that simply accepts each part is used.
47
48
49 4) After all parts have been processed, the function filter_end is
50 called if it has been defined. It is passed a single argument consist‐
51 ing of the (possibly modified) MIME::Entity object representing the
52 message about to be delivered.
53
54
56 mimedefang.pl examines each part of the MIME message and chooses a dis‐
57 position for that part. (A disposition is selected by calling one of
58 the following functions from filter and then immediately returning.)
59 Available dispositions are:
60
61
62 action_accept
63 The part is passed through unchanged. If no disposition func‐
64 tion is returned, this is the default.
65
66
67 action_accept_with_warning
68 The part is passed through unchanged, but a warning is added to
69 the mail message.
70
71
72 action_drop
73 The part is deleted without any notification to the recipients.
74
75
76 action_drop_with_warning
77 The part is deleted and a warning is added to the mail message.
78
79
80 action_replace_with_warning
81 The part is deleted and instead replaced with a text message.
82
83
84 action_quarantine
85 The part is deleted and a warning is added to the mail message.
86 In addition, a copy of the part is saved on the mail server in
87 the directory /var/spool/MD-Quarantine and a notification is
88 sent to the MIMEDefang administrator.
89
90
91 action_bounce
92 The entire e-mail message is rejected and an error returned to
93 the sender. The intended recipients are not notified. Note
94 that in spite of the name, MIMEDefang does not generate and e-
95 mail a failure notification. Rather, it causes the SMTP server
96 to return a 5XX SMTP failure code.
97
98
99 action_discard
100 The entire e-mail message is discarded silently. Neither the
101 sender nor the intended recipients are notified.
102
103
105 You can define a function called filter_relay in your filter. This
106 lets you reject SMTP connection attempts early on in the SMTP dialog,
107 rather than waiting until the whole message has been sent. Note that
108 for this check to take place, you must use the -r flag with mimedefang.
109
110
111 filter_relay is passed two arguments: $hostip is the IP address of the
112 relay host (for example, "127.0.0.1"), $hostname is the host name if
113 known (for example, "localhost.localdomain"). If the host name could
114 not be determined, $hostname is $hostip enclosed in square brackets.
115 (That is, ("$hostname" eq "[$hostip]") will be true.)
116
117
118 filter_relay must return a two-element list: ($code, $msg). $msg spec‐
119 ifies the text message to use for the SMTP reply, but because of limi‐
120 tations in the Milter API, this message is for documentation purposes
121 only---you cannot set the text of the SMTP message returned to the SMTP
122 client from filter_relay.
123
124 $code is a literal string, and can have one of the following values:
125
126
127 'REJECT'
128 if the connection should be rejected.
129
130
131 'CONTINUE'
132 if the connection should be accepted.
133
134
135 'TEMPFAIL'
136 if a temporary failure code should be returned.
137
138
139 'DISCARD'
140 if the message should be accepted and silently discarded.
141
142
143 'ACCEPT_AND_NO_MORE_FILTERING'
144 if the connection should be accepted and no further filtering
145 done.
146
147
148 Earlier versions of MIMEDefang used -1 for TEMPFAIL, 0 for REJECT and 1
149 for CONTINUE. These values still work, but are deprecated.
150
151
152 In the case of REJECT or TEMPFAIL, $msg specifies the text part of the
153 SMTP reply. $msg must not contain newlines.
154
155
156 For example, if you wish to reject connection attempts from any machine
157 in the spammer.com domain, you could use this function:
158
159 sub filter_relay {
160 my ($ip, $name) = @_;
161 if ($name =~ /spammer\.com$/) {
162 return ('REJECT', "Sorry; spammer.com is blacklisted");
163 }
164 return ('CONTINUE', "ok");
165 }
166
167
169 You can define a function called filter_helo in your filter. This lets
170 you reject connections after the HELO/EHLO SMTP command. Note that for
171 this function to be called, you must use the -H flag with mimedefang.
172
173
174 filter_helo is passed three arguments: $ip and $name are the IP address
175 and name of the sending relay, as in filter_relay. The third argument,
176 $helo, is the argument supplied in the HELO/EHLO command.
177
178
179 filter_helo must return a two-to-five element list: ($code, $msg,
180 $smtp_code, $smtp_dsn, $delay). $code is a return code, with the same
181 meaning as the $code return from filter_relay. $msg specifies the text
182 message to use for the SMTP reply. If $smtp_code and $smtp_dsn are
183 supplied, they become the SMTP numerical reply code and the enhanced
184 status delivery code (DSN code). If they are not supplied, sensible
185 defaults are used. $delay specifies a delay in seconds; the C milter
186 code will sleep for $delay seconds before returning the reply to Send‐
187 mail. $delay defaults to zero.
188
189 (Note that the delay is implemented in the Milter C code; if you spec‐
190 ify a delay of 30 seconds, that doesn't mean a Perl slave is tied up
191 for the duration of the delay. The delay only costs one Milter
192 thread.)
193
194
196 You can define a function called filter_sender in your filter. This
197 lets you reject messages from certain senders, rather than waiting
198 until the whole message has been sent. Note that for this check to
199 take place, you must use the -s flag with mimedefang.
200
201
202 filter_sender is passed four arguments: $sender is the envelope e-mail
203 address of the sender (for example, "<dfs@roaringpenguin.com>"). The
204 address may or may not be surrounded by angle brackets. $ip and $name
205 are the IP address and host name of the SMTP relay. Finally, $helo is
206 the argument to the SMTP "HELO" command.
207
208
209 Inside filter_sender, you can access any ESMTP arguments (such as
210 "SIZE=12345") in the array @ESMTPArgs. Each ESMTP argument occupies
211 one array element.
212
213
214 filter_sender must return a two-to-five element list, with the same
215 meaning as the return value from filter_helo.
216
217
218 For example, if you wish to reject messages from spammer@badguy.com,
219 you could use this function:
220
221 sub filter_sender {
222 my ($sender, $ip, $hostname, $helo) = @_;
223 if ($sender =~ /^<?spammer\@badguy\.com>?$/i) {
224 return ('REJECT', 'Sorry; spammer@badguy.com is blacklisted.');
225 }
226 return ('CONTINUE', "ok");
227 }
228
229
230 As another example, some spammers identify their own machine as your
231 machine in the SMTP "HELO" command. This function rejects a machine
232 claiming to be in the "roaringpenguin.com" domain unless it really is a
233 Roaring Penguin machine:
234
235 sub filter_sender {
236 my($sender, $ip, $hostname, $helo) = @_;
237 if ($helo =~ /roaringpenguin.com/i) {
238 if ($ip ne "127.0.0.1" and
239 $ip ne "216.191.236.23" and
240 $ip ne "216.191.236.30") {
241 return('REJECT', "Go away... $ip is not in roaringpenguin.com");
242 }
243 }
244 return ('CONTINUE', "ok");
245 }
246
247
248 As a third example, you may wish to prevent spoofs by requiring SMTP
249 authentication when email is sent from some email addresses. This func‐
250 tion rejects mail from "king@example.com", unless the connecting user
251 properly authenticated as "elvisp". Note that this needs access to the
252 %SendmailMacros global, that is not available in filter_sender until
253 after a call to read_commands_file.
254
255 sub filter_sender {
256 my($sender, $ip, $hostname, $helo) = @_;
257 read_commands_file();
258 ### notice: This assumes The King uses authentication without realm!
259 if ($sender =~ /^<?king\@example\.com>?$/i and
260 $SendmailMacros{auth_authen} ne "elvisp") {
261 return('REJECT', "Faking mail from the king is not allowed.");
262 }
263 return ('CONTINUE', "ok");
264 }
265
266
267
269 You can define a function called filter_recipient in your filter. This
270 lets you reject messages to certain recipients, rather than waiting
271 until the whole message has been sent. Note that for this check to
272 take place, you must use the -t flag with mimedefang.
273
274
275 filter_recipient is passed nine arguments: $recipient is the envelope
276 address of the recipient and $sender is the envelope e-mail address of
277 the sender (for example, "<dfs@roaringpenguin.com>"). The addresses
278 may or may not be surrounded by angle brackets. $ip and $name are the
279 IP address and host name of the SMTP relay. $first is the envelope
280 address of the first recipient for this message, and $helo is the argu‐
281 ment to the SMTP "HELO" command. The last three arguments,
282 $rcpt_mailer, $rcpt_host and $rcpt_addr are the Sendmail mailer, host
283 and address triple for the recipient address. For example, for local
284 recipients, $rcpt_mailer is likely to be "local", while for remote
285 recipients, it is likely to be "esmtp".
286
287
288 Inside filter_recipient, you can access any ESMTP arguments (such as
289 "NOTIFY=never") in the array @ESMTPArgs. Each ESMTP argument occupies
290 one array element.
291
292
293 filter_recipient must return a two-to-five element list whose interpre‐
294 tation is the same as for filter_sender. Note, however, that if fil‐
295 ter_recipient returns 'DISCARD', then the entire message for all recip‐
296 ients is discarded. (It doesn't really make sense, but that's how Mil‐
297 ter works.)
298
299
300 For example, if you wish to reject messages from spammer@badguy.com,
301 unless they are to postmaster@mydomain.com, you could use this func‐
302 tion:
303
304 sub filter_recipient {
305 my ($recipient, $sender, $ip, $hostname, $first, $helo,
306 $rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
307 if ($sender =~ /^<?spammer\@badguy\.com>?$/i) {
308 if ($recipient =~ /^<?postmaster\@mydomain\.com>?$/i) {
309 return ('CONTINUE', "ok");
310 }
311 return ('REJECT', 'Sorry; spammer@badguy.com is blacklisted.');
312 }
313 return ('CONTINUE', "ok");
314 }
315
316
318 Just before a slave begins processing messages, mimedefang.pl calls the
319 functions filter_initialize (if it is defined) with no arguments. By
320 the time filter_initialize is called, all the other initialization
321 (such as setting up syslog facility and priority) has been done.
322
323 If you are not using an embedded Perl interpreter, then performing an
324 action inside filter_initialize is practically the same as performing
325 it directly in the filter file, outside any function definition. How‐
326 ever, if you are using an embedded Perl interpreter, then anything you
327 call directly from outside a function definition is executed once only
328 in the parent process. Anything in filter_initialize is executed once
329 per slave. If you use any code that opens a descriptor (for example, a
330 connection to a database server), you must run that code inside fil‐
331 ter_initialize and not directly from the filter, because the multi‐
332 plexor closes all open descriptors when it activates a new slave.
333
334 When a slave is about to exit, mimedefang.pl calls the function fil‐
335 ter_cleanup (if it is defined) with no arguments. This function can do
336 whatever cleanup you like, such as closing file descriptors and clean‐
337 ing up long-lived slave resources. The return value from fil‐
338 ter_cleanup becomes the slave's exit status.
339
340
341 If filter_cleanup takes longer than 10 seconds to run, the slave is
342 sent a SIGTERM signal. If that doesn't kill it (because you're catch‐
343 ing signals, perhaps), then a further 10 seconds later, the slave is
344 sent a SIGKILL signal.
345
346
348 If you define a function called filter_create_parser taking no argu‐
349 ments, then mimedefang.pl will call it to create a MIME::Parser object
350 for parsing mail messages.
351
352 Filter_create_parser is expected to return a MIME::Parser object (or an
353 instance of a class derived from MIME::Parser).
354
355 You can use filter_create_parser to change the behavior of the
356 MIME::Parser used by mimedefang.pl.
357
358 If you do not define a filter_create_parser function, then a built-in
359 version equivalent to this is used:
360
361 sub filter_create_parser () {
362 my $parser = MIME::Parser->new();
363 $parser->extract_nested_messages(1);
364 $parser->extract_uuencode(1);
365 $parser->output_to_core(0);
366 $parser->tmp_to_core(0);
367 return $parser;
368 }
369
371 The man page for mimedefang-protocol(7) lists commands that are passed
372 to slaves in server mode (see "SERVER COMMANDS".) You can define a
373 function called filter_unknown_cmd to extend the set of commands your
374 filter can handle.
375
376 If you define filter_unknown_cmd, it is passed the unknown command as a
377 single argument. It should return a list of values as follows: The
378 first element of the list must be either "ok" or "error:" (with the
379 colon.) The remaining arguments are percent-encoded. All the result‐
380 ing pieces are joined together with a single space between them, and
381 the resulting string passed back as the reply to the multiplexor.
382
383 For example, the following function will make your filter reply to a
384 "PING" command with "PONG":
385
386 sub filter_unknown_cmd ($) {
387 my($cmd) = @_;
388 if ($cmd eq "PING") {
389 return("ok", "PONG");
390 }
391 return("error:", "Unknown command");
392 }
393
394 You can test this filter by typing the following as root:
395
396 md-mx-ctrl PING
397
398 The response should be:
399
400 ok PONG
401
402 If you extend the set of commands using filter_unknown_cmd, you should
403 make all your commands start with an upper-case letter to avoid clashes
404 with future built-in commands.
405
406
408 A very common mail setup is to have a MIMEDefang machine act as an SMTP
409 proxy, accepting and scanning mail and then relaying it to the real
410 mail server. Unfortunately, this means that the MIMEDefang machine
411 cannot know if a local address is valid or not, and will forward all
412 mail for the appropriate domains. If a mail comes in for an unknown
413 user, the MIMEDefang machine will be forced to generate a bounce mes‐
414 sage when it tries to relay the mail.
415
416
417 It's often desirable to have the MIMEDefang host reply with a "User
418 unknown" SMTP response directly. While this can be done by copying the
419 list of local users to the MIMEDefang machine, MIMEDefang has a built-
420 in function called md_check_against_smtp_server for querying another
421 relay host:
422
423
424 md_check_against_smtp_server($sender, $recip, $helo, $server, $port)
425 This
426 function connects to the SMTP server $server and pretends to
427 send mail from $sender to $recip. The return value is always a
428 two-element array. If the RCPT TO: command succeeds, the return
429 value is ("CONTINUE", "OK"). If the RCPT fails with a permanent
430 failure, the return value is ("REJECT", $msg), where $msg is the
431 message from the SMTP server. Any temporary failures, connec‐
432 tion errors, etc. result in a return value of ("TEMPFAIL",
433 $msg).
434
435 The optional argument $port specifies the TCP port to connect
436 to. If it is not supplied, then the default SMTP port of 25 is
437 used.
438
439
440 Suppose the machine filter.domain.tld is filtering mail destined for
441 the real mail server mail.domain.tld. You could have a filter_recipi‐
442 ent function like this:
443
444 sub filter_recipient
445 {
446 my($recip, $sender, $ip, $host, $first, $helo,
447 $rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
448 return md_check_against_smtp_server($sender, $recip,
449 "filter.domain.tld",
450 "mail.domain.tld");
451 }
452
453 For each RCPT TO: command, MIMEDefang opens an SMTP connection to
454 mail.domain.tld and checks if the command would succeed.
455
456
457 Please note that you should only use md_check_against_smtp_server if
458 your mail server responds with a failure code for nonexistent users at
459 the RCPT TO: level. Also, this function may impose too much overhead
460 if you receive a lot of e-mail, and it will generate lots of useless
461 log entries on the real mail server (because of all the RCPT TO:
462 probes.) It may also significantly increase the load on the real mail
463 server.
464
465
467 The following Perl global variables should be set in mimedefang-filter:
468
469
470 $AdminAddress
471 The e-mail address of the MIMEDefang administrator.
472
473
474 $DaemonAddress
475 The e-mail address from which MIMEDefang-originated notifica‐
476 tions come.
477
478
479 $AddWarningsInline
480 If this variable is set to 0, then all MIMEDefang warnings (such
481 as created by action_quarantine or action_drop_with_warning) are
482 collected together and added in a separate MIME part called
483 WARNING.TXT. If the variable is set to 1, then the warnings are
484 added directly in the first text/plain and text/html parts of
485 the message. If the message does not contain any text/plain or
486 text/html parts, then a WARNING.TXT MIME part is added as
487 before.
488
489
490 $MaxMIMEParts
491 A message containing many MIME parts can cause MIME::Tools to
492 consume large amounts of memory and bring your system to its
493 knees. If you set $MaxMIMEParts to a positive number, then MIME
494 parsing is terminated for messages with more than that many
495 parts, and the message is bounced. In this case, none of your
496 filter functions is called.
497
498 By default, $MaxMIMEParts is set to -1, meaning there is no
499 limit on the number of parts in a message. Note that in order
500 to use this variable, you must install the Roaring Penguin
501 patched version of MIME::Tools, version 5.411a-RP-Patched-02 or
502 newer.
503
504
505 $Stupidity{"NoMultipleInlines"}
506 Set this to 1 if your e-mail is too stupid to display multiple
507 MIME parts in-line. In this case, a nasty hack causes the first
508 part of the original message to appear as an attachment if warn‐
509 ing are issued. Mail clients that are not this stupid are Net‐
510 scape Communicator and Pine. On the other hand, Microsoft
511 Exchange and Microsoft Outlook are indeed this stupid. Perhaps
512 users of those clients should switch.
513
514 The following global variables may optionally be set. If they
515 are not set, sensible defaults are used:
516
517
518 $AddApparentlyToForSpamAssassin
519 By default, MIMEDefang tries to pass SpamAssassin a message that
520 looks exactly like one it would receive via procmail. This
521 means adding a Received: header, adding a Message-ID header if
522 necessary, and adding a Return-Path: header. If you set $AddAp‐
523 parentlyToForSpamAssassin to 1, then MIMEDefang also adds an
524 Apparently-To: header with all the envelope recipients before
525 passing the message to SpamAssassin. This lets SpamAssassin
526 detect possibly whitelisted recipient addresses.
527
528 The default value for $AddApparentlyToForSpamAssassin is 0.
529
530
531 $SyslogFacility
532 This specifies the logging facility used by mimedefang.pl. By
533 default, it is set to "mail", but you can set it to other possi‐
534 bilites. See the openlog(3) man page for details. You should
535 name facilities as all-lowercase without the leading "LOG_".
536 That is, use "local3", not "LOG_LOCAL3".
537
538
539 $WarningLocation (default 0)
540 If set to 0 (the default), non-inline warnings are placed first.
541 If you want the warning at the end of the e-mail, set $Warn‐
542 ingLocation to -1.
543
544
545 $DaemonName (default "MIMEDefang")
546 The full name used when MIMEDefang sends out notifications.
547
548
549 $AdminName (default "MIMEDefang Administrator")
550 The full name of the MIMEDefang administrator.
551
552
553 $SALocalTestsOnly (default 1)
554 If set to 1, SpamAssassin calls will use only local tests. This
555 is the default and recommended setting. This disables Received,
556 RBL and Razor tests in an all or nothing fashion. To use Razor
557 this MUST be set to 0. You can add 'skip_rbl_checks 1' to your
558 SpamAssassin config file if you need to.
559
560
561 $NotifySenderSubject (default "MIMEDefang Notification")
562 The subject used when e-mail is sent out by
563 action_notify_sender(). If you set this, you should set it each
564 time you call action_notify_sender() to ensure consistency.
565
566 $NotifyAdministratorSubject (default "MIMEDefang Notification")
567 The subject used when e-mail is sent out by action_notify_admin‐
568 istrator(). If you set this, you should set it each time you
569 call action_notify_administrator() to ensure consistency.
570
571
572 $QuarantineSubject (default "MIMEDefang Quarantine Report")
573 The subject used when a quarantine notice is sent to the admin‐
574 istrator. If you set this, you should set it each time you call
575 action_quarantine() or action_quarantine_entire_message().
576
577
578 $NotifyNoPreamble (default 0)
579 Normally, notifications sent by action_notify_sender() have a
580 preamble warning about message modifications. If you do not
581 want this, set $NotifyNoPreamble to 1.
582
583
584 $CSSHost (default 127.0.0.1:7777:local)
585 Host and port for the Symantec CarrierScan Server virus scanner.
586 This takes the form ip_addr:port:local_or_nonlocal. The ip_addr
587 and port are the host and port on which CarrierScan Server is
588 listening. If you want to scan local files, append :local to
589 force the use of the AVSCANLOCAL command. If the CarrierScan
590 Server is on another host, append :nonlocal to force the file
591 contents to be sent to the scanner over the socket.
592
593
594 $SophieSock (default /var/spool/MIMEDefang/sophie)
595 Socket used for Sophie daemon calls within message_con‐
596 tains_virus_sophie and entity_contains_virus_sophie unless a
597 socket is provided by the calling routine.
598
599
600 $ClamdSock (default /var/spool/MIMEDefang/clamd.sock)
601 Socket used for clamd daemon calls within message_con‐
602 tains_virus_clamd and entity_contains_virus_clamd unless a
603 socket is provided by the calling routine.
604
605
606 $TrophieSock (default /var/spool/MIMEDefang/trophie)
607 Socket used for Trophie daemon calls within message_con‐
608 tains_virus_trophie and entity_contains_virus_trophie unless a
609 socket is provided by the calling routine.
610
611
612
614 The heart of mimedefang-filter is the filter procedure. See the exam‐
615 ples that came with MIMEDefang to learn to write a filter. The filter
616 is called with the following arguments:
617
618
619 $entity
620 The MIME::Entity object. (See the MIME::tools Perl module docu‐
621 mentation.)
622
623
624 $fname The suggested attachment filename, or "" if none was supplied.
625
626
627 $ext The file extension (all characters from the rightmost period to
628 the end of the filename.)
629
630
631 $type The MIME type (for example, "text/plain".)
632
633
634 The filename is derived as follows:
635
636
637 o First, if the Content-Disposition header has a "filename" field,
638 it is used.
639
640
641 o Otherwise, if the Content-Type header has a "name" field, it is
642 used.
643
644
645 o Otherwise, the Content-Description header value is used.
646
647
648 Note that the truly paranoid will check all three fields for matches.
649 The functions re_match and re_match_ext perform regular expression
650 matches on all three of the fields named above, and return 1 if any
651 field matches. See the sample filters for details. The calling
652 sequence is:
653
654 re_match($entity, "regexp")
655 re_match_ext($entity, "regexp")
656
657 re_match returns true if any of the fields matches the regexp without
658 regard to case. re_match_ext returns true if the extension in any
659 field matches. An extension is defined as the last dot in a name and
660 all remaining characters.
661
662
663 A third function called re_match_in_zip_directory will look inside zip
664 files and return true if any of the file names inside the zip archive
665 match the regular expression. Call it like this:
666
667 my $bh = $entity->bodyhandle();
668 my $path = (defined($bh)) ? $bh->path() : undef;
669 if (defined($path) and re_match_in_zip_directory($path, "regexp")) {
670 # Take action...
671 }
672
673 You should not call re_match_in_zip_directory unless you know that the
674 entity is a zip file attachment.
675
676
678 The following global variables are set by mimedefang.pl and are avail‐
679 able for use in your filter. All of these variables are always avail‐
680 able to filter_begin, filter, filter_multipart and filter_end. In
681 addition, some of them are available in filter_relay, filter_sender or
682 filter_recipient. If this is the case, it will be noted below.
683
684
685 %Features
686 This hash lets you determine at run-time whether certain func‐
687 tionality is available. This hash is available at all times
688 assuming the detect_and_load_perl_modules() function has been
689 called. The defined features are:
690
691 $Features{"SpamAssassin"} is 1 if SpamAssassin 1.6 or better is
692 installed; 0 otherwise.
693
694 $Features{"HTML::Parser"} is 1 if HTML::Parser is installed; 0
695 otherwise.
696
697 $Features{"Virus:FPROTD"} is currently always 0. Set it to 1 in
698 your filter file if you have F-Risk's FPROTD scanner earlier
699 than version 6.
700
701 $Features{"Virus:FPROTD6"} is currently always 0. Set it to 1
702 in your filter file if you have version 6 of F-Risk's FPROTD
703 scanner.
704
705 $Features{"Virus:SymantecCSS"} is currently always 0. Set it to
706 1 in your filter file if you have the Symantec CarrierScan
707 Server virus scanner.
708
709 $Features{"Virus:NAI"} is the full path to NAI uvscan if it is
710 installed; 0 if it is not.
711
712 $Features{"Virus:BDC"} is the full path to Bitdefender bdc if it
713 is installed; 0 if it is not.
714
715 $Features{"Virus:NVCC"} is the full path to Norman Virus Control
716 nvcc if it is installed; 0 if it is not.
717
718 $Features{"Virus:HBEDV"} is the full path to H+BEDV AntiVir if
719 it is installed; 0 if it is not.
720
721 $Features{"Virus:VEXIRA"} is the full path to Central Command
722 Vexira if it is installed; 0 if it is not.
723
724 $Features{"Virus:SOPHOS"} is the full path to Sophos sweep if it
725 is installed; 0 if it is not.
726
727 $Features{"Virus:SAVSCAN"} is the full path to Sophos savscan if
728 it is installed; 0 if it is not.
729
730 $Features{"Virus:CLAMAV"} is the full path to Clam AV clamscan
731 if it is installed; 0 if it is not.
732
733 $Features{"Virus:AVP"} is the full path to AVP AvpLinux if it is
734 installed; 0 if it is not.
735
736 $Features{"Virus:AVP5"} is the full path to Kaspersky "ave‐
737 client" if it is installed; 0 if it is not.
738
739 $Features{"Virus:CSAV"} is the full path to Command csav if it
740 is installed; 0 if it is not.
741
742 $Features{"Virus:FSAV"} is the full path to F-Secure fsav if it
743 is installed; 0 if it is not.
744
745 $Features{"Virus:FPROT"} is the full path to F-Risk f-prot if it
746 is installed; 0 if it is not.
747
748 $Features{"Virus:FPSCAN"} is the full path to F-Risk fpscan if
749 it is installed; 0 if it is not.
750
751 $Features{"Virus:SOPHIE"} is the full path to Sophie if it is
752 installed; 0 if it is not.
753
754 $Features{"Virus:CLAMD"} is the full path to clamd if it is
755 installed; 0 if it is not.
756
757 $Features{"Virus:TROPHIE"} is the full path to Trophie if it is
758 installed; 0 if it is not.
759
760 $Features{"Virus:NOD32"} is the full path to ESET NOD32 nod32cli
761 if it is installed; 0 if it is not.
762
763 NOTE: Perl-module based features such as SpamAssassin are deter‐
764 mined at runtime and may change as these are added and removed.
765 Most Virus features are predetermined at the time of configura‐
766 tion and do not adapt to runtime availability unless changed by
767 the filter rules.
768
769
770 $CWD This variable holds the working directory for the current mes‐
771 sage. During filter processing, mimedefang.pl chdir's into this
772 directory before calling any of the filter_ functions. Note
773 that this variable is set correctly in filter_sender and fil‐
774 ter_recipient, but not in filter_relay.
775
776
777 $SuspiciousCharsInHeaders
778 If this variable is true, then mimedefang has discovered suspi‐
779 cious characters in message headers. This might be an exploit
780 for bugs in MIME-parsing routines in some badly-written mail
781 user agents (e.g. Microsoft Outlook.) You should always drop
782 such messages.
783
784
785 $SuspiciousCharsInBody
786 If this variable is true, then mimedefang has discovered suspi‐
787 cious characters in the message body. This might be an exploit
788 for bugs in MIME-parsing routines in some badly-written mail
789 user agents (e.g. Microsoft Outlook.) You should always drop
790 such messages.
791
792
793 $RelayHostname
794 The host name of the relay. This is the name of the host that
795 is attempting to send e-mail to your host. May be "undef" if
796 the host name could not be determined. This variable is avail‐
797 able in filter_relay, filter_sender and filter_recipient in
798 addition to the body filtering functions.
799
800
801 $RelayAddr
802 The IP address of the sending relay (as a string consisting of
803 four dot-separated decimal numbers.) One potential use of
804 $RelayAddr is to limit mailing to certain lists to people within
805 your organization. This variable is available in filter_relay,
806 filter_sender and filter_recipient in addition to the body fil‐
807 tering functions.
808
809 $Helo The argument given to the SMTP "HELO" command. This vari‐
810 able is available in filter_sender and filter_recipient, but not
811 in filter_relay.
812
813
814 $Subject
815 The contents of the "Subject:" header.
816
817
818 $Sender
819 The sender of the e-mail. This variable is set in filter_sender
820 and filter_recipient in addition to the body filtering func‐
821 tions.
822
823
824 @Recipients
825 A list of the recipients. In filter_recipient, it is set to the
826 single recipient currently under consideration. Or, after call‐
827 ing read_commands_file within filter_recipient, the current
828 recipient under consideration is in the final position of the
829 array, at $Recipients[-1], while any previous (and accepted)
830 recipients are at the beginning of the array, that is, in
831 @Recipients[0 .. $#Recipients-1].
832
833
834
835 $MessageID
836 The contents of the "Message-ID:" header if one is present.
837 Otherwise, contains the string "NOQUEUE".
838
839
840 $QueueID
841 The Sendmail queue identifier if it could be determined. Other‐
842 wise, contains the string "NOQUEUE". This variable is set cor‐
843 rectly in filter_sender and filter_recipient, but it is not
844 available in filter_relay.
845
846
847 $MsgID Set to $QueueID if the queue ID could be determined; otherwise,
848 set to $MessageID. This identifier should be used in logging,
849 because it matches the identifier used by Sendmail to log mes‐
850 sages. Note that this variable is set correctly in fil‐
851 ter_sender and filter_recipient, but it is not available in fil‐
852 ter_relay.
853
854
855 $VirusScannerMessages
856 Each time a virus-scanning function is called, messages (if any)
857 from the virus scanner are accumulated in this variable. You
858 can use it in filter_end to formulate a notification (if you
859 wish.)
860
861
862 $VirusName
863 If a virus-scanning function found a virus, this variable will
864 hold the virus name (if it could be determined.)
865
866
867 $SASpamTester
868 If defined, this is the configured Mail::SpamAssassin object
869 used for mail tests. It may be initialized with a call to
870 spam_assassin_init which also returns it.
871
872
873 %SendmailMacros
874 This hash contains the values of some Sendmail macros. The hash
875 elements exist only for macros defined by Sendmail. See the
876 Sendmail documentation for the meanings of the macros.
877
878 By default, mimedefang passes the values of the following
879 macros: ${daemon_name}, ${if_name}, ${if_addr}, $j, $_, $i,
880 ${tls_version}, ${cipher}, ${cipher_bits}, ${cert_subject},
881 ${cert_issuer}, ${auth_type}, ${auth_authen}, ${auth_ssf},
882 ${auth_author}, ${mail_mailer}, ${mail_host} and ${mail_addr}.
883
884 If any macro is not set or not passed to milter, it will be
885 unavailable. To access the value of a macro, use:
886
887
888 $SendmailMacros{"macro_name"}
889
890
891 Do not place curly brackets around the macro name. This vari‐
892 able is available in filter_sender and filter_recipient after a
893 call to read_commands_file.
894
895
896 @SenderESMTPArgs
897 This array contains all the ESMTP arguments supplied in the MAIL
898 FROM: command. For example:
899
900 sub print_sender_esmtp_args {
901 foreach (@SenderESMTPArgs) {
902 print STDERR "Sender ESMTP arg: $_0;
903 }
904 }
905
906
907 %RecipientESMTPArgs
908 This hash contains all the ESMTP arguments supplied in each RCPT
909 TO: command. For example:
910
911 sub print_recip_esmtp_args {
912 foreach my $recip (@Recipients) {
913 foreach(@{$RecipientESMTPArgs{$recip}}) {
914 print STDERR "Recip ESMTP arg for $recip: $_0;
915 }
916 }
917 }
918
919
920 %RecipientMailers
921 This hash contains the Sendmail "mailer-host-address" triple for
922 each recipient. Here's an example of how to use it:
923
924 sub print_mailer_info {
925 my($recip, $mailer, $host, $addr);
926 foreach $recip (@Recipients) {
927 $mailer = ${RecipientMailers{$recip}}[0];
928 $host = ${RecipientMailers{$recip}}[1];
929 $addr = ${RecipientMailers{$recip}}[2];
930 print STDERR "$recip: mailer=$mailer, host=$host, addr=$addr\n";
931 }
932 }
933
934 In filter_recipient, this variable by default only contains
935 information on the recipient currently under investigation.
936 Information on all recipients is available after calling
937 read_commands_file.
938
939
941 When the filter procedure decides how to dispose of a part, it should
942 call one or more action_ subroutines. The action subroutines are:
943
944
945 action_accept()
946 Accept the part.
947
948
949 action_rebuild()
950 Rebuild the mail body, even if mimedefang thinks no changes were
951 made. Normally, mimedefang does not alter a message if no
952 changes were made. action_rebuild may be used if you make
953 changes to entities directly (by manipulating the MIME::Head,
954 for example.) Unless you call action_rebuild, mimedefang will
955 be unaware of the changes. Note that all the built-in action...
956 routines that change a message implicitly call action_rebuild.
957
958
959 action_add_header($hdr, $val)
960 Add a header to the message. This can be used in filter_begin
961 or filter_end. The $hdr component is the header name without
962 the colon, and the $val is the header value. For example, to
963 add the header:
964
965 X-MyHeader: A nice piece of text
966
967 use:
968
969 action_add_header("X-MyHeader", "A nice piece of text");
970
971
972 action_change_header($hdr, $val, $index)
973 Changes an existing header in the message. This can be used in
974 filter_begin or filter_end. The $hdr parameter is the header
975 name without the colon, and $val is the header value. If the
976 header does not exist, then a header with the given name and
977 value is added.
978
979 The $index parameter is optional; it defaults to 1. If you sup‐
980 ply it, then the $index'th occurrence of the header is changed,
981 if there is more than one header with the same name. (This is
982 common with the Received: header, for example.)
983
984
985 action_insert_header($hdr, $val, $index)
986 Add a header to the message int the specified position $index.
987 A position of 0 specifies that the header should be prepended
988 before existing headers. This can be used in filter_begin or
989 filter_end. The $hdr component is the header name without the
990 colon, and the $val is the header value.
991
992
993 action_delete_header($hdr, $index)
994 Deletes an existing header in the message. This can be used in
995 filter_begin or filter_end. The $hdr parameter is the header
996 name without the colon.
997
998 The $index parameter is optional; it defaults to 1. If you sup‐
999 ply it, then the $index'th occurrence of the header is deleted,
1000 if there is more than one header with the same name.
1001
1002
1003 action_delete_all_headers($hdr)
1004 Deletes all headers with the specified name. This can be used
1005 in filter_begin or filter_end. The $hdr parameter is the header
1006 name without the colon.
1007
1008
1009 action_drop()
1010 Drop the part. If called from filter_multipart, drops all con‐
1011 tained parts also.
1012
1013
1014 action_drop_with_warning($msg)
1015 Drop the part, but add the warning $msg to the e-mail message.
1016 If called from filter_multipart, drops all contained parts also.
1017
1018
1019 action_accept_with_warning($msg)
1020 Accept the part, but add the warning $msg to the e-mail message.
1021
1022
1023 action_replace_with_warning($msg)
1024 Drop the part and replace it with a text part $msg. If called
1025 from filter_multipart, drops all contained parts also.
1026
1027
1028 action_replace_with_url($entity, $doc_root, $base_url, $msg, [$cd_data,
1029 $salt])
1030 Drop the part, but save it in a unique location under $doc_root.
1031 The part is replaced with the text message $msg. The string
1032 "_URL_" in $msg is replaced with $base_url/something, that can
1033 be used to retrieve the message.
1034
1035 You should not use this function in filter_multipart.
1036
1037 This action is intended for stripping large parts out of the
1038 message and replacing them to a link on a Web server. Here's
1039 how you would use it in filter():
1040
1041 $size = (stat($entity->bodyhandle->path))[7];
1042 if ($size > 1000000) {
1043 return action_replace_with_url($entity,
1044 "/home/httpd/html/mail_parts",
1045 "http://mailserver.company.com/mail_parts",
1046 "The attachment was larger than 1,000,000 bytes.\n" .
1047 "It was removed, but may be accessed at this URL:\n\n" .
1048 "\t_URL_\n");
1049 }
1050
1051 This example moves attachments greater than 1,000,000 bytes into
1052 /home/httpd/html/mail_parts and replaces them with a link. The
1053 directory should be accessible via a Web server at
1054 http://mailserver.company.com/mail_parts.
1055
1056 The generated name is created by performing a SHA1 hash of the
1057 part and adding the extension to the ASCII-HEX representation of
1058 the hash. If many different e-mails are sent containing an
1059 identical large part, only one copy of the part is stored,
1060 regardless of the number of senders or recipients.
1061
1062 For privacy reasons, you must turn off Web server indexing in
1063 the directory in which you place mail parts, or anyone will be
1064 able to read them. If indexing is disabled, an attacker would
1065 have to guess the SHA1 hash of a part in order to read it.
1066
1067 Optionally, a fifth argument can supply data to be saved into a
1068 hidden dot filename based on the generated name. This data can
1069 then be read in on the fly by a CGI script or mod_perl module
1070 before serving the file to a web client, and used to add infor‐
1071 mation to the response, such as Content-Disposition data.
1072
1073 A sixth optional argument, $salt, is mixed in to the SHA1 hash.
1074 This salt can be any string and should be kept confidential.
1075 The salt is designed to prevent people from guessing whether or
1076 not a particular attachment has been received on your server by
1077 altering the SHA1 hash calculation.
1078
1079
1080 action_defang($entity, $name, $fname, $type)
1081 Accept the part, but change its name to $name, its suggested
1082 filename to $fname and its MIME type to $type. If $name or
1083 $fname are "", then mimedefang.pl generates generic names. Do
1084 not use this action in filter_multipart.
1085
1086 If you use action_defang, you must define a subroutine called
1087 defang_warning in your filter. This routine takes two argu‐
1088 ments: $oldfname (the original name of an attachment) and $fname
1089 (the defanged version.) It should return a message telling the
1090 user what happened. For example:
1091
1092 sub defang_warning {
1093 my($oldfname, $fname) = @_;
1094 return "The attachment '$oldfname' was renamed to '$fname'\n";
1095 }
1096
1097
1098
1099 action_external_filter($entity, $cmd)
1100 Run an external UNIX command $cmd. This command must read the
1101 part from the file ./FILTERINPUT and leave the result in ./FIL‐
1102 TEROUTPUT. If the command executes successfully, returns 1,
1103 otherwise 0. You can test the return value and call another
1104 action_ if the filter failed. Do not use this action in fil‐
1105 ter_multipart.
1106
1107
1108 action_quarantine($entity, $msg)
1109 Drop and quarantine the part, but add the warning $msg to the e-
1110 mail message.
1111
1112
1113 action_quarantine_entire_message($msg)
1114 Quarantines the entire message in a quarantine directory on the
1115 mail server, but does not otherwise affect disposition of the
1116 message. If "$msg" is non-empty, it is included in any adminis‐
1117 trator notification.
1118
1119
1120 action_sm_quarantine($reason)
1121 Quarantines a message in the Sendmail mail queue using the new
1122 QUARANTINE facility of Sendmail 8.13. Consult the Sendmail doc‐
1123 umentation for details about this facility. If you use
1124 action_sm_quarantine with a version of Sendmail that lacks the
1125 QUARANTINE facility, mimedefang will log an error message and
1126 not quarantine the message.
1127
1128
1129 action_bounce($reply, $code, $dsn)
1130 Reject the entire e-mail message with an SMTP failure code, and
1131 the one-line error message $reply. If the optional $code and
1132 $dsn arguments are supplied, they specify the numerical SMTP
1133 reply code and the extended status code (DSN code). If the
1134 codes you supply do not make sense for a bounce, they are
1135 replaced with "554" and "5.7.1" respectively.
1136
1137 action_bounce merely makes a note that the message is to be
1138 bounced; remaining parts are still processed. If action_bounce
1139 is called for more than one part, the mail is bounced with the
1140 message in the final call to action_bounce. You can profitably
1141 call action_quarantine followed by action_bounce if you want to
1142 keep a copy of the offending part. Note that the message is not
1143 bounced immediately; rather, remaining parts are processed and
1144 the message is bounced after all parts have been processed.
1145
1146 Note that despite its name, action_bounce does not generate a
1147 "bounce message". It merely rejects the message with an SMTP
1148 failure code.
1149
1150 WARNING: action_bounce() may cause the sending relay to generate
1151 spurious bounce messages if the sender address is faked. This
1152 is a particular problem with viruses. However, we believe that
1153 on balance, it's better to bounce a virus than to silently dis‐
1154 card it. It's almost never a good idea to hide a problem.
1155
1156
1157 action_tempfail($msg, $code, $dsn)
1158 Cause an SMTP "temporary failure" code to be returned, so the
1159 sending mail relay requeues the message and tries again later.
1160 The message $msg is included with the temporary failure code.
1161 If the optional $code and $dsn arguments are supplied, they
1162 specify the numerical SMTP reply code and the extended status
1163 code (DSN code). If the codes you supply do not make sense for
1164 a temporary failure, they are replaced with "450" and "4.7.1"
1165 respectively.
1166
1167
1168 action_discard()
1169 Silently discard the message, notifying nobody. You can prof‐
1170 itably call action_quarantine followed by action_discard if you
1171 want to keep a copy of the offending part. Note that the mes‐
1172 sage is not discarded immediately; rather, remaining parts are
1173 processed and the message is discarded after all parts have been
1174 processed.
1175
1176
1177 action_notify_sender($message)
1178 This action sends an e-mail back to the original sender with the
1179 indicated message. You may call another action after this one.
1180 If action_notify_sender is called more than once, the messages
1181 are accumulated into a single e-mail message -- at most one
1182 notification message is sent per incoming message. The message
1183 should be terminated with a newline.
1184
1185 The notification is delivered in deferred mode; you should run a
1186 client-queue runner if you are using Sendmail 8.12.
1187
1188 NOTE: Viruses often fake the sender address. For that reason,
1189 if a virus-scanner has detected a virus, action_notify_sender is
1190 disabled and will simply log an error message if you try to use
1191 it.
1192
1193
1194 action_notify_administrator($message)
1195 This action e-mails the MIMEDefang administrator the supplied
1196 message. You may call another action after this one;
1197 action_notify_administrator does not affect mail processing. If
1198 action_notify_administrator is called more than once, the mes‐
1199 sages are accumulated into a single e-mail message -- at most
1200 one notification message is sent per incoming message. The mes‐
1201 sage should be terminated with a newline.
1202
1203 The notification is delivered in deferred mode; you should run a
1204 client-queue runner if you are using Sendmail 8.12.
1205
1206
1207 append_text_boilerplate($entity, $boilerplate, $all)
1208 This action should only be called from filter_end. It appends
1209 the text "\n$boilerplate\n" to the first text/plain part (if
1210 $all is 0) or to all text/plain parts (if $all is 1).
1211
1212
1213 append_html_boilerplate($entity, $boilerplate, $all)
1214 This action should only be called from filter_end. It adds the
1215 text "\n$boilerplate\n" to the first text/html part (if $all is
1216 0) or to all text/html parts (if $all is 1). This function
1217 tries to be smart about inserting the boilerplate; it uses
1218 HTML::Parser to detect closing tags and inserts the boilerplate
1219 before the </body> tag if there is one, or before the </html>
1220 tag if there is no </body>. If there is no </body> or </html>
1221 tag, it appends the boilerplate to the end of the part.
1222
1223 Do not use append_html_boilerplate unless you have installed the
1224 HTML::Parser Perl module.
1225
1226 Here is an example illustrating how to use the boilerplate func‐
1227 tions:
1228
1229 sub filter_end {
1230 my($entity) = @_;
1231 append_text_boilerplate($entity,
1232 "Lame text disclaimer", 0);
1233 append_html_boilerplate($entity,
1234 "<em>Lame</em> HTML disclaimer", 0);
1235 }
1236
1237
1238 action_add_part($entity, $type, $encoding, $data, $fname, $disposition
1239 [, $offset])
1240 This action should only be called from the filter_end routine.
1241 It adds a new part to the message, converting the original mes‐
1242 sage to mutipart if necessary. The function returns the part so
1243 that additional mime attributes may be set on it. Here's an
1244 example:
1245
1246 sub filter_end {
1247 my($entity) = @_;
1248
1249 action_add_part($entity, "text/plain", "-suggest",
1250 "This e-mail does not represent" .
1251 "the official policy of FuBar, Inc.\n",
1252 "disclaimer.txt", "inline");
1253 }
1254
1255 The $entity parameter must be the argument passed in to fil‐
1256 ter_end. The $offset parameter is optional; if omitted, it
1257 defaults to -1, which adds the new part at the end. See the
1258 MIME::Entity man page and the add_part member function for the
1259 meaning of $offset.
1260
1261 Note that action_add_part tries to be more intelligent than sim‐
1262 ply calling $entity->add_part. The decision process is as fol‐
1263 lows:
1264
1265
1266 o If the top-level entity is multipart/mixed, then the part is
1267 simply added.
1268
1269
1270 o Otherwise, a new top-level multipart/mixed container is gener‐
1271 ated, and the original top-level entity is made the first part
1272 of the multipart/mixed container. The new part is then added to
1273 the multipart/mixed container.
1274
1275
1277 mimedefang.pl includes some useful functions you can call from your
1278 filter:
1279
1280
1281 detect_and_load_perl_modules()
1282 Unless you really know what you're doing, this function must be
1283 called first thing in your filter file. It causes mimedefang.pl
1284 to detect and load Perl modules such as Mail::SpamAssassin,
1285 Net::DNS, etc., and to populate the %Features hash.
1286
1287
1288 send_quarantine_notifications()
1289 This function should be called from filter_end. If any parts
1290 were quarantined, a quarantine notification is sent to the
1291 MIMEDefang administrator. Please note that if you do not call
1292 send_quarantine_notifications, then no quarantine notifications
1293 are sent.
1294
1295
1296 get_quarantine_dir()
1297 This function returns the full path name of the quarantine
1298 directory. If you have not yet quarantined any parts of the
1299 message, a quarantine directory is created and its pathname
1300 returned.
1301
1302
1303 change_sender($sender)
1304 This function changes the envelope sender to $sender. It can
1305 only be called from filter_begin or any later function. Please
1306 note that this function is only supported with Sendmail/Milter
1307 8.14.0 or newer. It has no effect if you're running older ver‐
1308 sions.
1309
1310
1311 add_recipient($recip)
1312 This function adds $recip to the list of envelope recipients. A
1313 copy of the message (after any modifications by MIMEDefang) will
1314 be sent to $recip in addition to the original recipients. Note
1315 that add_recipient does not modify the @Recipients array; it
1316 just makes a note to Sendmail to add the recipient.
1317
1318
1319 delete_recipient($recip)
1320 This function deletes $recip from the list of recipients. That
1321 person will not receive a copy of the mail. $recip should
1322 exactly match an entry in the @Recipients array for
1323 delete_recipient() to work. Note that delete_recipient does not
1324 modify the @Recipients array; it just makes a note to Sendmail
1325 to delete the recipient.
1326
1327 resend_message($recip1, $recip2, ...)
1328 or
1329
1330 resend_message(@recips)
1331 This function immediately resends the original, unmodified mail
1332 message to each of the named recipients. The sender's address
1333 is preserved. Be very careful when using this function, because
1334 it resends the original message, which may contain undesired
1335 attachments. Also, you should not call this function from fil‐
1336 ter(), because it resends the message each time it is called.
1337 This may result in multiple copies being sent if you are not
1338 careful. Call from filter_begin() or filter_end() to be safe.
1339
1340 The function returns true on success, or false if it fails.
1341
1342 Note that the resend_message function delivers the mail in
1343 deferred mode (using Sendmail's "-odd" flag.) You must run a
1344 client-submission queue processor if you use Sendmail 8.12. We
1345 recommend executing this command as part of the Sendmail startup
1346 sequence:
1347
1348 sendmail -Ac -q5m
1349
1350
1351 remove_redundant_html_parts($entity)
1352 This function should only be called from filter_end. It removes
1353 redundant HTML parts from the message. It works by deleting any
1354 part of type text/html from the message if (1) it is a sub-part
1355 of a multipart/alternative part, and (2) there is another part
1356 of type text/plain under the multipart/alternative part.
1357
1358
1359 replace_entire_message($entity)
1360 This function can only be called from filter_end. It replaces
1361 the entire message with $entity, a MIME::Entity object that you
1362 have constructed. You can use any of the MIME::Tools functions
1363 to construct the entity.
1364
1365
1366 read_commands_file()
1367 This function should only be called from filter_sender and fil‐
1368 ter_recipient. This will read the COMMANDS file (as described in
1369 mimedefang-protocol(7)), and will fill or update the following
1370 global variables: $Sender, @Recipients, %RecipientMailers,
1371 $RelayAddr, $RealRelayAddr, $RelayHostname, $RealRelayHostname,
1372 $QueueID, $Helo, %SendmailMacros.
1373
1374 If you do not call read_commands_file, then the only information
1375 available in filter_sender and filter_recipient is that which is
1376 passed as an argument to the function.
1377
1378
1379 stream_by_domain()
1380 Do not use this function unless you have Sendmail 8.12 and
1381 locally- submitted e-mail is submitted using SMTP.
1382
1383 This function should only be called at the very beginning of
1384 filter_begin(), like this:
1385
1386 sub filter_begin {
1387 if (stream_by_domain()) {
1388 return;
1389 }
1390 # Rest of filter_begin
1391 }
1392
1393 stream_by_domain() looks at all the recipients of the message,
1394 and if they belong to the same domain (e.g., joe@domain.com,
1395 jane@domain.com and sue@domain.com), it returns 0 and sets the
1396 global variable $Domain to the domain (domain.com in this exam‐
1397 ple.)
1398
1399 If users are in different domains, stream_by_domain() resends
1400 the message (once to each domain) and returns 1 For example, if
1401 the original recipients are joe@abc.net, jane@xyz.net and
1402 sue@abc.net, the original message is resent twice: One copy to
1403 joe@abc.net and sue@abc.net, and another copy to jane@xyz.net.
1404 Also, any subsequent scanning is canceled (filter() and fil‐
1405 ter_end() will not be called for the original message) and the
1406 message is silently discarded.
1407
1408 If you have Sendmail 8.12, then locally-submitted messages are
1409 sent via SMTP, and MIMEDefang will be called for each resent
1410 message. It is possible to set up Sendmail 8.12 so locally-sub‐
1411 mitted messages are delivered directly; in this case,
1412 stream_by_domain will not work.
1413
1414 Using stream_by_domain allows you to customize your filter rules
1415 for each domain. If you use the function as described above,
1416 you can do this in your filter routine:
1417
1418 sub filter {
1419 my($entity, $fname, $ext, $type) = @_;
1420 if ($Domain eq "abc.com") {
1421 # Filter actions for abc.com
1422 } elsif ($Domain eq "xyz.com") {
1423 # Filter actions for xyz.com
1424 } else {
1425 # Default filter actions
1426 }
1427 }
1428
1429 You cannot rely on $Domain being set unless you have called
1430 stream_by_domain().
1431
1432
1433 stream_by_recipient()
1434 Do not use this function unless you have Sendmail 8.12 and
1435 locally- submitted e-mail is submitted using SMTP.
1436
1437 This function should only be called at the very beginning of
1438 filter_begin(), like this:
1439
1440 sub filter_begin {
1441 if (stream_by_recipient()) {
1442 return;
1443 }
1444 # Rest of filter_begin
1445 }
1446
1447 If there is more than one recipient, stream_by_recipient()
1448 resends the message once to each recipient. That way, you can
1449 customize your filter rules on a per-recipient basis. This may
1450 increase the load on your mail server considerably.
1451
1452 Also, a "recipient" is determined before alias expansion. So
1453 "all@mydomain.com" is considered a single recipient, even if
1454 Sendmail delivers to a list.
1455
1456 If you have Sendmail 8.12, then locally-submitted messages are
1457 sent via SMTP, and MIMEDefang will be called for each resent
1458 message. It is possible to set up Sendmail 8.12 so locally-sub‐
1459 mitted messages are delivered directly; in this case,
1460 stream_by_recipient() will not work.
1461
1462 stream_by_recipient() allows you to customize your filter rules
1463 for each recipient in a manner similar to stream_by_domain().
1464
1465
1467 md_graphdefang_log_enable($facility, $enum_recips)
1468 Enables the md_graphdefang_log function (described next). The
1469 function logs to syslog using the specified facility. If you
1470 omit $facility, it defaults to 'mail'. If you do not call
1471 md_graphdefang_log_enable in your filter, then any calls to
1472 md_graphdefang_log simply do nothing.
1473
1474 If you supply $enum_recips as 1, then a line of logging is out‐
1475 put for each recipient of a mail message. If it is zero, then
1476 only a single line is output for each message. If you omit
1477 $enum_recips, it defaults to 1.
1478
1479
1480 md_graphdefang_log($event, $v1, $v2)
1481 Logs an event with up to two optional additional parameters.
1482 The log message has a specific format useful for graphing tools;
1483 the message looks like this:
1484
1485 MDLOG,msgid,event,v1,v2,sender,recipient,subj
1486
1487 "MDLOG" is literal text. "msgid" is the Sendmail queue identi‐
1488 fier. "event" is the event name, and "v1" and "v2" are the
1489 additional parameters. "sender" is the sender's e-mail address.
1490 "recipient" is the recipient's e-mail address, and "subj" is the
1491 message subject. If a message has more than one recipient,
1492 md_graphdefang_log may log an event message for each recipient,
1493 depending on how you called md_graphdefang_log_enable.
1494
1495 Note that md_graphdefang_log should not be used in filter_relay,
1496 filter_sender or filter_recipient. The global variables it
1497 relies on are not valid in that context.
1498
1499 If you want to log general text strings, do not use md_graphde‐
1500 fang_log. Instead, use md_syslog (described next).
1501
1502
1503 md_syslog($level, $msg)
1504 Logs the message $msg to syslog, using level $level. The level
1505 is a literal string, and should be one of 'err', 'debug', 'warn‐
1506 ing', ´emerg', 'crit', 'notice' or 'info'. (See syslog(3) for
1507 details.)
1508
1509 Note that md_syslog does not perform %-subsitutions like sys‐
1510 log(3) does. Depending on your Perl installation, md_syslog
1511 boils down to a call to Unix::Syslog::syslog or Sys::Sys‐
1512 log::syslog. See the Unix::Syslog or Sys::Syslog man pages for
1513 more details.
1514
1515
1516 md_openlog($tag, $facility)
1517 Sets the tag used in syslog messages to $tag, and sends the logs
1518 to the $facility facility. If you do not call md_openlog before
1519 you call md_syslog, then it is called implicitly with $tag set
1520 to mimedefang.pl and $facility set to mail.
1521
1522
1524 mimedefang.pl includes the following functions for looking up IP
1525 addresses in DNS-based real-time blacklists. Note that the
1526 "relay_is_blacklisted" functions are deprecated and may be removed in a
1527 future release. Instead, you should use the module Net::DNSBL::Client
1528 from CPAN.
1529
1530
1531 relay_is_blacklisted($relay, $domain)
1532 This checks a DNS-based real-time spam blacklist, and returns
1533 true if the relay host is blacklisted, or false otherwise. (In
1534 fact, the return value is whatever the blacklist returns as a
1535 resolved hostname, such as "127.0.0.4")
1536
1537 Note that relay_is_blacklisted uses the built-in gethostbyname
1538 function; this is usually quite inefficient and does not permit
1539 you to set a timeout on the lookup. Instead, we recommend using
1540 one of the other DNS lookup function described in this section.
1541 (Note, though, that the other functions require the Perl
1542 Net::DNS module, whereas relay_is_blacklisted does not.)
1543
1544 Here's an example of how to use relay_is_blacklisted:
1545
1546 if (relay_is_blacklisted($RelayAddr, "rbl.spamhaus.org")) {
1547 action_add_header("X-Blacklist-Warning",
1548 "Relay $RelayAddr is blacklisted by Spamhaus");
1549 }
1550
1551
1552 relay_is_blacklisted_multi($relay, $timeout, $answers_wanted,
1553 [$domain1, $domain2, ...], $res)
1554 This function is similar to relay_is_blacklisted, except that it
1555 takes a timeout argument (specified in seconds) and an array of
1556 domains to check. The function checks all domains in parallel,
1557 and is guaranteed to return in $timeout seconds. (Actually, it
1558 may take up to one second longer.)
1559
1560 The parameters are:
1561
1562 $relay -- the IP address you want to look up
1563
1564 $timeout -- a timeout in seconds after which the function should
1565 return
1566
1567 $answers_wanted -- the maximum number of positive answers you
1568 care about. For example, if you're looking up an address in 10
1569 different RBLs, but are going to bounce it if it is on four or
1570 more, you can set $answers_wanted to 4, and the function returns
1571 as soon as four "hits" are discovered. If you set
1572 $answers_wanted to zero, then the function does not return
1573 early.
1574
1575 [$domain1, $domain2, ...] -- a reference to an array of strings,
1576 where each string is an RBL domain.
1577
1578 $res -- a Net::DNS::Resolver object. This argument is optional;
1579 if you do not supply it, then relay_is_blacklisted_multi con‐
1580 structs its own resolver.
1581
1582 The return value is a reference to a hash; the keys of the hash
1583 are the original domains, and the corresponding values are
1584 either SERVFAIL, NXDOMAIN, or a list of IP addresses in dotted-
1585 quad notation.
1586
1587 Here's an example:
1588
1589 $ans = relay_is_blacklisted_multi($RelayAddr, 8, 0,
1590 ["sbl.spamhaus.org", "relays.ordb.org"]);
1591
1592 foreach $domain (keys(%$ans)) {
1593 $r = $ans->{$domain};
1594 if (ref($r) eq "ARRAY") {
1595 # It's an array -- it IS listed in RBL
1596 print STDERR "Lookup in $domain yields [ ";
1597 foreach $addr (@$r) {
1598 print STDERR $addr . " ";
1599 }
1600 print STDERR "]\n";
1601 } else {
1602 # It is NOT listed in RBL
1603 print STDERR "Lookup in $domain yields "
1604 . $ans->{$domain} . "\n";
1605 }
1606 }
1607
1608 You should compare each of $ans->{$domain} to "SERVFAIL" and
1609 "NXDOMAIN" to see if the relay is not listed. Any other return
1610 value will be an array of IP addresses indicating that the relay
1611 is listed.
1612
1613 Any lookup that does not succeed within $timeout seconds has the
1614 corresponding return value set to SERVFAIL.
1615
1616
1617 relay_is_blacklisted_multi_list($relay, $timeout, $answers_wanted,
1618 [$domain1, $domain2, ...], $res)
1619 This function is similar to relay_is_blacklisted_multi except
1620 that the return value is simply an array of RBL domains in which
1621 the relay was listed.
1622
1623
1624 relay_is_blacklisted_multi_count($relay, $timeout, $answers_wanted,
1625 [$domain1, $domain2, ...], $res)
1626 This function is similar to relay_is_blacklisted_multi except
1627 that the return value is an integer specifying the number of
1628 domains on which the relay was blacklisted.
1629
1630
1631 md_get_bogus_mx_hosts($domain)
1632 This function is not really an RBL lookup. What it does is look
1633 up all the MX records for the specified domain, and return a
1634 list of "bogus" IP addresses found amongst the MX records. A
1635 "bogus" IP address is an IP address in a private network
1636 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), the loopback net‐
1637 work (127.0.0.0/8), local-link for auto-DHCP (169.254.0.0/16),
1638 IPv4 multicast (224.0.0.0/4) or reserved (240.0.0.0/4).
1639
1640
1641 Here's how you might use the function in filter_sender:
1642
1643 sub filter_sender {
1644 my ($sender, $ip, $hostname, $helo) = @_;
1645 if ($sender =~ /@([^>]+)/) {
1646 my $domain = $1;
1647 my @bogushosts = md_get_bogus_mx_hosts($domain);
1648 if (scalar(@bogushosts)) {
1649 return('REJECT', "Domain $domain contains bogus MX record(s) " .
1650 join(', ', @bogushosts));
1651 }
1652 }
1653 return ('CONTINUE', 'ok');
1654 }
1655
1656
1658 mimedefang.pl includes some "test" functions:
1659
1660
1661 md_version()
1662 returns the version of MIMEDefang as a string (for example,
1663 "2.72").
1664
1665
1666 message_rejected()
1667 Returns true if any of action_tempfail, action_bounce or
1668 action_discard have been called for this message; returns false
1669 otherwise.
1670
1671
1672 If you have the Mail::SpamAssassin Perl module installed (see
1673 http://www.spamassassin.org) you may call any of the spam_assassin_*
1674 functions. They should only be called from filter_begin or filter_end
1675 because they operate on the entire message at once. Most functions use
1676 an optionally provided config file. If no config file is provided,
1677 mimedefang.pl will look for one of four default SpamAssassin preference
1678 files. The first of the following found will be used:
1679
1680
1681 o /etc/mail/sa-mimedefang.cf
1682
1683 o /etc/mail/spamassassin/sa-mimedefang.cf
1684
1685 o /etc/mail/spamassassin/local.cf
1686
1687 o /etc/mail/spamassassin.cf
1688
1689
1690 Important Note: MIMEDefang does not permit SpamAssassin to modify mes‐
1691 sages. If you want to tag spam messages with special headers or alter
1692 the subject line, you must use MIMEDefang functions to do it. Setting
1693 SpamAssassin configuration options to alter messages will not work.
1694
1695
1696 spam_assassin_is_spam([ $config_file ])
1697 Determine if the current message is SPAM/UCE as determined by
1698 SpamAssassin. Compares the score of the message against the
1699 threshold score (see below) and returns true if it is. Uses
1700 spam_assassin_check below.
1701
1702
1703 spam_assassin_check([ $config_file ])
1704 This function returns a four-element list of the form ($hits,
1705 $required, $tests, $report). $hits is the "score" given to the
1706 message by SpamAssassin (higher score means more likely SPAM).
1707 $required is the number of hits required before SpamAssassin
1708 concludes that the message is SPAM. $tests is a comma-separated
1709 list of SpamAssassin test names, and $report is text detailing
1710 which tests triggered and their point score. This gives you
1711 insight into why SpamAssassin concluded that the message is
1712 SPAM. Uses spam_assassin_status below.
1713
1714
1715 spam_assassin_status([ $config_file ])
1716 This function returns a Mail::SpamAssasin::PerMsgStatus object.
1717 Read the SpamAssassin documentation for details about this
1718 object. You are responsible for calling the finish method when
1719 you are done with it. Uses spam_assassin_init and spam_assas‐
1720 sin_mail below.
1721
1722
1723 spam_assassin_init([ $config_file ])
1724 This function returns the new global Mail::SpamAssassin object
1725 with the specified or default config (outlined above). If the
1726 global object is already defined, returns it -- does not change
1727 config files! The object can be used to perform other SpamAs‐
1728 sassin related functions.
1729
1730
1731 spam_assassin_mail()
1732 This function returns a Mail::SpamAssassin::NoMailAudit object
1733 with the current email message contained in it. It may be used
1734 to perform other SpamAssassin related functions.
1735
1736
1737 md_copy_orig_msg_to_work_dir()
1738 Normally, virus-scanners are passed only the unpacked, decoded
1739 parts of a MIME message. If you want to pass the original,
1740 undecoded message in as well, call md_copy_orig_msg_to_work_dir
1741 prior to calling message_contains_virus.
1742
1743
1744 md_copy_orig_msg_to_work_dir_as_mbox_file()
1745 Normally, virus-scanners are passed only the unpacked, decoded
1746 parts of a MIME message. If you want to pass the original,
1747 undecoded message in as a UNIX-style "mbox" file, call
1748 md_copy_orig_msg_to_work_dir_as_mbox_file prior to calling mes‐
1749 sage_contains_virus. The only difference between this function
1750 and md_copy_orig_msg_to_work_dir is that this function prepends
1751 a "From_" line to make the message look like a UNIX-style mbox
1752 file. This is required for some virus scanners (such as Clam
1753 AntiVirus) to recognize the file as an e-mail message.
1754
1755
1756 message_contains_virus()
1757 This function runs every installed virus-scanner and returns the
1758 scanner results. The function should be called in list context;
1759 the return value is a three-element list ($code, $category,
1760 $action).
1761
1762 $code is the actual return code from the virus scanner.
1763
1764 $category is a string categorizing the return code:
1765
1766 "ok" - no viruses detected.
1767
1768 "not-installed" - indicated virus scanner is not installed.
1769
1770 "cannot-execute" - for some reason, the scanner could not be
1771 executed.
1772
1773 "virus" - a virus was found.
1774
1775 "suspicious" - a "suspicious" file was found.
1776
1777 "interrupted" - scanning was interrupted.
1778
1779 "swerr" - an internal scanner software error occurred.
1780
1781 $action is a string containing the recommended action:
1782
1783 "ok" - allow the message through unmolested.
1784
1785 "quarantine" - a virus was detected; quarantine it.
1786
1787 "tempfail" - something went wrong; tempfail the message.
1788
1789
1790
1791 message_contains_virus_trend()
1792
1793 message_contains_virus_nai()
1794
1795 message_contains_virus_bdc()
1796
1797 message_contains_virus_nvcc()
1798
1799 message_contains_virus_csav()
1800
1801 message_contains_virus_fsav()
1802
1803 message_contains_virus_hbedv()
1804
1805 message_contains_virus_vexira()
1806
1807 message_contains_virus_sophos()
1808
1809 message_contains_virus_clamav()
1810
1811 message_contains_virus_avp()
1812
1813 message_contains_virus_avp5()
1814
1815 message_contains_virus_fprot()
1816
1817 message_contains_virus_fpscan()
1818
1819 message_contains_virus_fprotd()
1820
1821 message_contains_virus_fprotd_v6()
1822
1823 message_contains_virus_nod32()
1824
1825 These functions should be called in list context. They use the
1826 indicated anti-virus software to scan the message for viruses.
1827 These functions are intended for use in filter_begin() to make
1828 an initial scan of the e-mail message.
1829
1830 The supported virus scanners are:
1831
1832 nai NAI "uvscan" - http://www.nai.com/
1833
1834 Bitdefender "bdc" - http://www.bitdefender.com/
1835
1836 csav Command Anti-Virus - http://www.commandsoftware.com/
1837
1838 fsav F-Secure Anti-Virus - http://www.f-secure.com/
1839
1840 hbedv H+BEDV "AntiVir" - http://www.hbedv.com/
1841
1842 vexira Vexira "Vexira" - http://www.centralcommand.com/
1843
1844 sophos Sophos AntiVirus - http://www.sophos.com/
1845
1846 avp Kaspersky AVP and aveclient (AVP5) - http://www.avp.ru/
1847
1848 clamav Clam AntiVirus - http://www.clamav.net/
1849
1850 f-prot F-RISK F-PROT - http://www.f-prot.com/
1851
1852 nod32cli
1853 ESET NOD32 - http://www.eset.com/
1854
1855
1856 message_contains_virus_carrier_scan([$host])
1857 Connects to the specified host:port:local_or_nonlocal (default
1858 $CSSHost), where the Symantec CarrierScan Server daemon is
1859 expected to be listening. Return values are the same as the
1860 other message_contains_virus functions.
1861
1862
1863 message_contains_virus_sophie([$sophie_sock])
1864 Connects to the specified socket (default $SophieSock), where
1865 the Sophie daemon is expected to be listening. Return values
1866 are the same as the other message_contains_virus functions.
1867
1868
1869 message_contains_virus_clamd([$clamd_sock])
1870 Connects to the specified socket (default $ClamdSock), where the
1871 clamd daemon is expected to be listening. Return values are the
1872 same as the other message_contains_virus functions.
1873
1874
1875 message_contains_virus_trophie([$trophie_sock])
1876 Connects to the specified socket (default $TrophieSock), where
1877 the Trophie daemon is expected to be listening. Return values
1878 are the same as the other message_contains_virus functions.
1879
1880
1881 entity_contains_virus($entity)
1882
1883 This function runs the specified MIME::Entity through every
1884 installed virus-scanner and returns the scanner results. The
1885 return values are the same as for message_contains_virus().
1886
1887
1888 entity_contains_virus_trend($entity)
1889
1890 entity_contains_virus_nai($entity)
1891
1892 entity_contains_virus_bdc($entity)
1893
1894 entity_contains_virus_nvcc($entity)
1895
1896 entity_contains_virus_csav($entity)
1897
1898 entity_contains_virus_fsav($entity)
1899
1900 entity_contains_virus_hbedv($entity)
1901
1902 entity_contains_virus_sophos($entity)
1903
1904 entity_contains_virus_clamav($entity)
1905
1906 entity_contains_virus_avp($entity)
1907
1908 entity_contains_virus_avp5($entity)
1909
1910 entity_contains_virus_fprot($entity)
1911
1912 entity_contains_virus_fpscan($entity)
1913
1914 entity_contains_virus_fprotd($entity)
1915
1916 entity_contains_virus_fprotd_v6($entity)
1917
1918 entity_contains_virus_nod32($entity)
1919 These functions, meant to be called from filter(), are similar
1920 to the message_contains_virus functions except they scan only
1921 the current part. They should be called from list context, and
1922 their return values are as described for the message_con‐
1923 tains_virus functions.
1924
1925
1926 entity_contains_virus_carrier_scan($entity[, $host])
1927 Connects to the specified host:port:local_or_nonlocal (default
1928 $CSSHost), where the Symantec CarrierScan Server daemon is
1929 expected to be listening. Return values are the same as the
1930 other entity_contains_virus functions.
1931
1932
1933 entity_contains_virus_sophie($entity[, $sophie_sock])
1934 Connects to the specified socket (default $SophieSock), where
1935 the Sophie daemon is expected to be listening. Return values
1936 are the same as the other entity_contains_virus functions.
1937
1938
1939 entity_contains_virus_trophie($entity[, $trophie_sock])
1940 Connects to the specified socket (default $TrophieSock), where
1941 the Trophie daemon is expected to be listening. Return values
1942 are the same as the other entity_contains_virus functions.
1943
1944
1945 entity_contains_virus_clamd($entity[, $clamd_sock])
1946 Connects to the specified socket (default $ClamdSock), where the
1947 clamd daemon is expected to be listening. Return values are the
1948 same as the other entity_contains_virus functions.
1949
1950
1952 This section illustrates the flow of messages through MIMEDefang.
1953
1954
1955 1. INITIAL CONNECTION
1956 If you invoked mimedefang with the -r option and have defined a
1957 filter_relay routine, it is called.
1958
1959
1960 2. SMTP HELO COMMAND
1961 The HELO string is stored internally, but no filter functions
1962 are called.
1963
1964
1965 3. SMTP MAIL FROM: COMMAND
1966 If you invoked mimedefang with the -s option and have defined a
1967 filter_sender routine, it is called.
1968
1969
1970 4. SMTP RCPT TO: COMMAND
1971 If you invoked mimedefang with the -t option and have defined a
1972 filter_recipient routine, it is called.
1973
1974
1975 5. END OF SMTP DATA
1976 filter_begin is called. For each MIME part, filter is called.
1977 Then filter_end is called.
1978
1979
1981 Most organizations have more than one machine handling internet e-mail.
1982 If the primary machine is down, mail is routed to a secondary (or ter‐
1983 tiary, etc.) MX server, which stores the mail until the primary MX host
1984 comes back up. Mail is then relayed to the primary MX host.
1985
1986
1987 Relaying from a secondary to a primary MX host has the unfortunate side
1988 effect of losing the original relay's IP address information. MIMEDe‐
1989 fang allows you to preserve this information. One way around the prob‐
1990 lem is to run MIMEDefang on all the secondary MX hosts and use the same
1991 filter. However, you may not have control over the secondary MX hosts.
1992 If you can persuade the owners of the secondary MX hosts to run MIMEDe‐
1993 fang with a simple filter that only preserves relay information and
1994 does no other scanning, your primary MX host can obtain relay informa‐
1995 tion and make decisions using $RelayAddr and $RelayHostname.
1996
1997
1998 When you configure MIMEDefang, supply the "--with-ipheader" argument to
1999 the ./configure script. When you install MIMEDefang, a file called
2000 /etc/mail/mimedefang-ip-key will be created which contains a randomly-
2001 generated header name. Copy this file to all of your mail relays. It
2002 is important that all of your MX hosts have the same key. The key
2003 should be kept confidential, but it's not disastrous if it leaks out.
2004
2005
2006 On your secondary MX hosts, add this line to filter_end:
2007
2008 add_ip_validation_header();
2009
2010
2011 Note: You should only add the validation header to mail destined for
2012 one of your other MX hosts! Otherwise, the validation header will leak
2013 out.
2014
2015
2016 When the secondary MX hosts relay to the primary MX host, $RelayAddr
2017 and $RelayHostname will be set based on the IP validation header. If
2018 MIMEDefang notices this header, it sets the global variable $WasResent
2019 to 1. Since you don't want to trust the header unless it was set by
2020 one of your secondary MX hosts, you should put this code in fil‐
2021 ter_begin:
2022
2023 if ($WasResent) {
2024 if ($RealRelayAddr ne "ip.of.secondary.mx" and
2025 $RealRelayAddr ne "ip.of.tertiary.mx") {
2026 $RelayAddr = $RealRelayAddr;
2027 $RelayHostname = $RealRelayHostname;
2028 }
2029 }
2030
2031 This resets the relay address and hostname to the actual relay address
2032 and hostname, unless the message is coming from one of your other MX
2033 hosts.
2034
2035
2036 On the primary MX host, you should add this in filter_begin:
2037
2038 delete_ip_validation_header();
2039
2040
2041 This prevents the validation header from leaking out to recipients.
2042
2043
2044 Note: The IP validation header works only in message-oriented func‐
2045 tions. It (obviously) has no effect on filter_relay, filter_sender and
2046 filter_recipient, because no header information is available yet. You
2047 must take this into account when writing your filter; you must defer
2048 relay-based decisions to the message filter for mail arriving from your
2049 other MX hosts.
2050
2051
2053 The following list describes the lifetime of global variables (thanks
2054 to Tony Nugent for providing this documentation.)
2055
2056 If you set a global variable:
2057
2058
2059 Outside a subroutine in your filter file
2060 It is available to all functions, all the time.
2061
2062
2063 In filter_relay, filter_sender or filter_recipient
2064 Not guaranteed to be available to any other function, not even
2065 from one filter_recipient call to the next, when receiving a
2066 multi-recipient email message.
2067
2068
2069 In filter_begin
2070 Available to filter_begin, filter and filter_end
2071
2072
2073 In filter
2074 Available to filter and filter_end
2075
2076
2077 In filter_end
2078 Available within filter_end
2079
2080
2081 The "built-in" globals like $Subject, $Sender, etc. are always avail‐
2082 able to filter_begin, filter and filter_end. Some are available to fil‐
2083 ter_relay, filter_sender or filter_recipient, but you should check the
2084 documentation of the variable above for details.
2085
2086
2088 There are four basic groups of filtering functions:
2089
2090
2091 1 filter_relay
2092
2093
2094 2 filter_sender
2095
2096
2097 3 filter_recipient
2098
2099
2100 4 filter_begin, filter, filter_multipart, filter_end
2101
2102
2103 In general, for a given mail message, these groups of functions may be
2104 called in completely different Perl processes. Thus, there is no way
2105 to maintain state inside Perl between groups of functions. That is,
2106 you cannot set a variable in filter_relay and expect it to be available
2107 in filter_sender, because the filter_sender invocation might take place
2108 in a completely different process.
2109
2110
2111 However, for a given mail message, the $CWD global variable holds the
2112 message spool directory, and the current working directory is set to
2113 $CWD. Therefore, you can store state in files inside $CWD. If fil‐
2114 ter_sender stores data in a file inside $CWD, then filter_recipient can
2115 retrieve that data.
2116
2117
2118 Since filter_relay is called directly after a mail connection is estab‐
2119 lished, there is no message context yet, no per-message mimedefang
2120 spool directory, and the $CWD global is not set. Therefore, it is not
2121 possible to share information from filter_relay to one of the other
2122 filter functions. The only thing that filter_relay has in common with
2123 the other functions are the values in the globals $RelayAddr, and
2124 $RelayHostname. These could be used to access per-remote-host informa‐
2125 tion in some database.
2126
2127
2128 Inside $CWD, we reserve filenames beginning with upper-case letters for
2129 internal MIMEDefang use. If you want to create files to store state,
2130 name them beginning with a lower-case letter to avoid clashes with
2131 future releases of MIMEDefang.
2132
2133
2135 If you have Sendmail 8.13 or later, and have compiled it with the SOCK‐
2136 ETMAP option, then you can use a special map type that communicates
2137 over a socket with another program (rather than looking up a key in a
2138 Berkeley database, for example.)
2139
2140
2141 mimedefang-multiplexor implements the Sendmail SOCKETMAP protocol if
2142 you supply the -N option. In that case, you can define a function
2143 called filter_map to implement map lookups. filter_map takes two argu‐
2144 ments: $mapname is the name of the Sendmail map (as given in the K
2145 sendmail configuration directive), and $key is the key to be looked up.
2146
2147
2148 filter_map must return a two-element list: ($code, $val) $code can be
2149 one of:
2150
2151
2152 OK The lookup was successful. In this case, $val must be the
2153 result of the lookup
2154
2155
2156 NOTFOUND
2157 The lookup was unsuccessful -- the key was not found. In this
2158 case, $val should be the empty string.
2159
2160
2161 TEMP There was a temporary failure of some kind. $val can be an
2162 explanatory error message.
2163
2164
2165 TIMEOUT
2166 There was a timeout of some kind. $val can be an explanatory
2167 error message.
2168
2169
2170 PERM There was a permanent failure. This is not the same as an
2171 unsuccessful lookup; it should be used only to indicate a seri‐
2172 ous misconfiguration. As before, $val can be an explanatory
2173 error message.
2174
2175
2176 Consider this small example. Here is a minimal Sendmail configuration
2177 file:
2178
2179 V10/Berkeley
2180 Kmysock socket unix:/var/spool/MIMEDefang/map.sock
2181 kothersock socket unix:/var/spool/MIMEDefang/map.sock
2182
2183
2184 If mimedefang-multiplexor is invoked with the arguments -N
2185 unix:/var/spool/MIMEDefang/map.sock, and the filter defines filter_map
2186 as follows:
2187
2188 sub filter_map ($$) {
2189 my($mapname, $key) = @_;
2190 my $ans;
2191 if($mapname ne "mysock") {
2192 return("PERM", "Unknown map $mapname");
2193 }
2194 $ans = reverse($key);
2195 return ("OK", $ans);
2196 }
2197
2198 Then in Sendmail's testing mode, we see the following:
2199
2200 > /map mysock testing123
2201 map_lookup: mysock (testing123) returns 321gnitset (0)
2202 > /map othersock foo
2203 map_lookup: othersock (foo) no match (69)
2204
2205
2206 (The return code of 69 means EX_UNAVAILABLE or Service Unavailable)
2207
2208
2209 A real-world example could do map lookups in an LDAP directory or SQL
2210 database, or perform other kinds of processing. You can even implement
2211 standard Sendmail maps like virtusertable, mailertable, access_db, etc.
2212 using SOCKETMAP.
2213
2214
2216 If you supply the -X option to mimedefang-multiplexor, then every so
2217 often, a "tick" request is sent to a free slave. If your filter
2218 defines a function called filter_tick, then this function is called
2219 with a single argument: the tick type. If you run multiple parallel
2220 ticks, then each tick has a type ranging from 0 to n-1, where n is the
2221 number of parallel ticks. If you're only running one tick request,
2222 then the argument to filter_tick is always 0.
2223
2224 You can use this facility to run periodic tasks from within MIMEDefang.
2225 Note, however, that you have no control over which slave is picked to
2226 run filter_tick. Also, at most one filter_tick call with a particular
2227 "type" argument will be active at any time, and if there are no free
2228 slaves when a tick would occur, the tick is skipped.
2229
2230
2232 The following virus scanners are supported by MIMEDefang:
2233
2234
2235 o Symantec CarrierScan Server (http://www.syman‐
2236 tec.com/region/can/eng/product/scs/)
2237
2238
2239 o Trend Micro vscan (http://www.antivirus.com/)
2240
2241
2242 o Sophos Sweep (http://www.sophos.com/products/antivirus/savu‐
2243 nix.html)
2244
2245
2246 o H+BEDV AntiVir (http://www.hbedv.com/)
2247
2248
2249 o Central Command Vexira (http://www.centralcommand.com/)
2250
2251
2252 o NAI uvscan (http://www.nai.com)
2253
2254
2255 o Bitdefender bdc (http://www.bitdefender.com)
2256
2257
2258 o Norman Virus Control (NVCC) (http://www.norman.no/)
2259
2260
2261 o Command csav (http://www.commandsoftware.com)
2262
2263
2264 o F-Secure fsav (http://www.f-secure.com)
2265
2266
2267 o The clamscan command-line scanner and the clamd daemon from Clam
2268 AntiVirus (http://www.clamav.net/)
2269
2270
2271 o Kaspersky Anti-Virus (AVP) (http://www.kaspersky.com/)
2272
2273
2274 o F-Risk F-Prot (http://www.f-prot.com/)
2275
2276
2277 o F-Risk F-Prot v6 (http://www.f-prot.com/)
2278
2279
2280
2281 o F-Risk FPROTD (daemonized version of F-Prot)
2282
2283
2284 o Symantec CarrierScan Server (http://www.syman‐
2285 tec.ca/region/can/eng/product/scs/buymenu.html)
2286
2287
2288 o Sophie (http://www.vanja.com/tools/sophie/), which uses the lib‐
2289 savi library from Sophos, is supported in daemon-scanning mode.
2290
2291
2292 o Trophie (http://www.vanja.com/tools/trophie/), which uses the
2293 libvsapi library from Trend Micro, is supported in daemon-scan‐
2294 ning mode.
2295
2296
2297 o ESET NOD32 (http://www.eset.com/)
2298
2299
2301 mimedefang was written by David F. Skoll <dfs@roaringpenguin.com>. The
2302 mimedefang home page is http://www.mimedefang.org/.
2303
2304
2306 mimedefang(8), mimedefang.pl(8)
2307
2308
2309
2310
2311
2312
23134th Berkeley Distribution 8 February 2005 MIMEDEFANG-FILTER(5)