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"), and $hostname is the host name
113 if 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{"HTMLCleaner"} is 1 if Anomy::HTMLCleaner is
695 installed; 0 otherwise.
696
697 $Features{"HTML::Parser"} is 1 if HTML::Parser is installed; 0
698 otherwise.
699
700 $Features{"Virus:FPROTD"} is currently always 0. Set it to 1 in
701 your filter file if you have F-Risk's FPROTD scanner.
702
703 $Features{"Virus:SymantecCSS"} is currently always 0. Set it to
704 1 in your filter file if you have the Symantec CarrierScan
705 Server virus scanner.
706
707 $Features{"Virus:NAI"} is the full path to NAI uvscan if it is
708 installed; 0 if it is not.
709
710 $Features{"Virus:BDC"} is the full path to Bitdefender bdc if it
711 is installed; 0 if it is not.
712
713 $Features{"Virus:NVCC"} is the full path to Norman Virus Control
714 nvcc if it is installed; 0 if it is not.
715
716 $Features{"Virus:HBEDV"} is the full path to H+BEDV AntiVir if
717 it is installed; 0 if it is not.
718
719 $Features{"Virus:VEXIRA"} is the full path to Central Command
720 Vexira if it is installed; 0 if it is not.
721
722 $Features{"Virus:SOPHOS"} is the full path to Sophos sweep if it
723 is installed; 0 if it is not.
724
725 $Features{"Virus:SAVSCAN"} is the full path to Sophos savscan if
726 it is installed; 0 if it is not.
727
728 $Features{"Virus:CLAMAV"} is the full path to Clam AV clamscan
729 if it is installed; 0 if it is not.
730
731 $Features{"Virus:AVP"} is the full path to AVP AvpLinux if it is
732 installed; 0 if it is not.
733
734 $Features{"Virus:AVP5"} is the full path to Kaspersky "ave‐
735 client" if it is installed; 0 if it is not.
736
737 $Features{"Virus:CSAV"} is the full path to Command csav if it
738 is installed; 0 if it is not.
739
740 $Features{"Virus:FSAV"} is the full path to F-Secure fsav if it
741 is installed; 0 if it is not.
742
743 $Features{"Virus:FPROT"} is the full path to F-Risk f-prot if it
744 is installed; 0 if it is not.
745
746 $Features{"Virus:SOPHIE"} is the full path to Sophie if it is
747 installed; 0 if it is not.
748
749 $Features{"Virus:CLAMD"} is the full path to clamd if it is
750 installed; 0 if it is not.
751
752 $Features{"Virus:TROPHIE"} is the full path to Trophie if it is
753 installed; 0 if it is not.
754
755 $Features{"Virus:NOD32"} is the full path to ESET NOD32 nod32cli
756 if it is installed; 0 if it is not.
757
758 NOTE: Perl-module based features (SpamAssassin and HTMLCleaner)
759 are determined at runtime and may change as these are added and
760 removed. Most Virus features are predetermined at the time of
761 configuration and do not adapt to runtime availability unless
762 changed by the filter rules.
763
764
765 $CWD This variable holds the working directory for the current mes‐
766 sage. During filter processing, mimedefang.pl chdir's into this
767 directory before calling any of the filter_ functions. Note
768 that this variable is set correctly in filter_sender and fil‐
769 ter_recipient, but not in filter_relay.
770
771
772 $SuspiciousCharsInHeaders
773 If this variable is true, then mimedefang has discovered suspi‐
774 cious characters in message headers. This might be an exploit
775 for bugs in MIME-parsing routines in some badly-written mail
776 user agents (e.g. Microsoft Outlook.) You should always drop
777 such messages.
778
779
780 $SuspiciousCharsInBody
781 If this variable is true, then mimedefang has discovered suspi‐
782 cious characters in the message body. This might be an exploit
783 for bugs in MIME-parsing routines in some badly-written mail
784 user agents (e.g. Microsoft Outlook.) You should always drop
785 such messages.
786
787
788 $RelayHostname
789 The host name of the relay. This is the name of the host that
790 is attempting to send e-mail to your host. May be "undef" if
791 the host name could not be determined. This variable is avail‐
792 able in filter_relay, filter_sender and filter_recipient.
793
794
795 $RelayAddr
796 The IP address of the sending relay (as a string consisting of
797 four dot-separated decimal numbers.) One potential use of
798 $RelayAddr is to limit mailing to certain lists to people within
799 your organization. This variable is available in filter_relay,
800 filter_sender and filter_recipient.
801
802
803 $Helo The argument given to the SMTP "HELO" command. This variable is
804 available in filter_sender and filter_recipient, but not in fil‐
805 ter_relay.
806
807
808 $Subject
809 The contents of the "Subject:" header.
810
811
812 $Sender
813 The sender of the e-mail. This variable is set in filter_sender
814 and filter_recipient.
815
816
817 @Recipients
818 A list of the recipients. In filter_recipient, it is set to the
819 single recipient currently under consideration. Or, after call‐
820 ing read_commands_file within filter_recipient, the current
821 recipient under consideration is in the final position of the
822 array, at $Recipients[-1], while any previous (and accepted)
823 recipients are at the beginning of the array, that is, in
824 @Recipients[0 .. $#Recipients-1].
825
826
827
828 $MessageID
829 The contents of the "Message-ID:" header if one is present.
830 Otherwise, contains the string "NOQUEUE".
831
832
833 $QueueID
834 The Sendmail queue identifier if it could be determined. Other‐
835 wise, contains the string "NOQUEUE". This variable is set cor‐
836 rectly in filter_sender and filter_recipient, but it is not
837 available in filter_relay.
838
839
840 $MsgID Set to $QueueID if the queue ID could be determined; otherwise,
841 set to $MessageID. This identifier should be used in logging,
842 because it matches the identifier used by Sendmail to log mes‐
843 sages. Note that this variable is set correctly in fil‐
844 ter_sender and filter_recipient, but it is not available in fil‐
845 ter_relay.
846
847
848 $VirusScannerMessages
849 Each time a virus-scanning function is called, messages (if any)
850 from the virus scanner are accumulated in this variable. You
851 can use it in filter_end to formulate a notification (if you
852 wish.)
853
854
855 $VirusName
856 If a virus-scanning function found a virus, this variable will
857 hold the virus name (if it could be determined.)
858
859
860 $SASpamTester
861 If defined, this is the configured Mail::SpamAssassin object
862 used for mail tests. It may be initialized with a call to
863 spam_assassin_init which also returns it.
864
865
866 %SendmailMacros
867 This hash contains the values of some Sendmail macros. The hash
868 elements exist only for macros defined by Sendmail. See the
869 Sendmail documentation for the meanings of the macros.
870
871 By default, mimedefang passes the values of the following
872 macros: ${daemon_name}, ${if_name}, ${if_addr}, $j, $_, $i,
873 ${tls_version}, ${cipher}, ${cipher_bits}, ${cert_subject},
874 ${cert_issuer}, ${auth_type}, ${auth_authen}, ${auth_ssf},
875 ${auth_author}, ${mail_mailer}, ${mail_host} and ${mail_addr}.
876
877 If any macro is not set or not passed to milter, it will be
878 unavailable. To access the value of a macro, use:
879
880
881 $SendmailMacros{"macro_name"}
882
883
884 Do not place curly brackets around the macro name. This vari‐
885 able is available in filter_sender and filter_recipient after a
886 call to read_commands_file.
887
888
889 @SenderESMTPArgs
890 This array contains all the ESMTP arguments supplied in the MAIL
891 FROM: command. For example:
892
893 sub print_sender_esmtp_args {
894 foreach (@SenderESMTPArgs) {
895 print STDERR "Sender ESMTP arg: $_0;
896 }
897 }
898
899
900 %RecipientESMTPArgs
901 This hash contains all the ESMTP arguments supplied in each RCPT
902 TO: command. For example:
903
904 sub print_recip_esmtp_args {
905 foreach my $recip (@Recipients) {
906 foreach(@{$RecipientESMTPArgs{$recip}}) {
907 print STDERR "Recip ESMTP arg for $recip: $_0;
908 }
909 }
910 }
911
912
913 %RecipientMailers
914 This hash contains the Sendmail "mailer-host-address" triple for
915 each recipient. Here's an example of how to use it:
916
917 sub print_mailer_info {
918 my($recip, $mailer, $host, $addr);
919 foreach $recip (@Recipients) {
920 $mailer = ${RecipientMailers{$recip}}[0];
921 $host = ${RecipientMailers{$recip}}[1];
922 $addr = ${RecipientMailers{$recip}}[2];
923 print STDERR "$recip: mailer=$mailer, host=$host, addr=$addr\n";
924 }
925 }
926
927 In filter_recipient, this variable by default only contains
928 information on the recipient currently under investigation.
929 Information on all recipients is available after calling
930 read_commands_file.
931
932
934 When the filter procedure decides how to dispose of a part, it should
935 call one or more action_ subroutines. The action subroutines are:
936
937
938 action_accept()
939 Accept the part.
940
941
942 action_rebuild()
943 Rebuild the mail body, even if mimedefang thinks no changes were
944 made. Normally, mimedefang does not alter a message if no
945 changes were made. action_rebuild may be used if you make
946 changes to entities directly (by manipulating the MIME::Head,
947 for example.) Unless you call action_rebuild, mimedefang will
948 be unaware of the changes. Note that all the built-in action...
949 routines that change a message implicitly call action_rebuild.
950
951
952 action_add_header($hdr, $val)
953 Add a header to the message. This can be used in filter_begin
954 or filter_end. The $hdr component is the header name without
955 the colon, and the $val is the header value. For example, to
956 add the header:
957
958 X-MyHeader: A nice piece of text
959
960 use:
961
962 action_add_header("X-MyHeader", "A nice piece of text");
963
964
965 action_change_header($hdr, $val, $index)
966 Changes an existing header in the message. This can be used in
967 filter_begin or filter_end. The $hdr parameter is the header
968 name without the colon, and $val is the header value. If the
969 header does not exist, then a header with the given name and
970 value is added.
971
972 The $index parameter is optional; it defaults to 1. If you sup‐
973 ply it, then the $index'th occurrence of the header is changed,
974 if there is more than one header with the same name. (This is
975 common with the Received: header, for example.)
976
977
978 action_insert_header($hdr, $val, $index)
979 Add a header to the message int the specified position $index.
980 A position of 0 specifies that the header should be prepended
981 before existing headers. This can be used in filter_begin or
982 filter_end. The $hdr component is the header name without the
983 colon, and the $val is the header value.
984
985
986 action_delete_header($hdr, $index)
987 Deletes an existing header in the message. This can be used in
988 filter_begin or filter_end. The $hdr parameter is the header
989 name without the colon.
990
991 The $index parameter is optional; it defaults to 1. If you sup‐
992 ply it, then the $index'th occurrence of the header is deleted,
993 if there is more than one header with the same name.
994
995
996 action_delete_all_headers($hdr)
997 Deletes all headers with the specified name. This can be used
998 in filter_begin or filter_end. The $hdr parameter is the header
999 name without the colon.
1000
1001
1002 action_drop()
1003 Drop the part. If called from filter_multipart, drops all con‐
1004 tained parts also.
1005
1006
1007 action_drop_with_warning($msg)
1008 Drop the part, but add the warning $msg to the e-mail message.
1009 If called from filter_multipart, drops all contained parts also.
1010
1011
1012 action_accept_with_warning($msg)
1013 Accept the part, but add the warning $msg to the e-mail message.
1014
1015
1016 action_replace_with_warning($msg)
1017 Drop the part and replace it with a text part $msg. If called
1018 from filter_multipart, drops all contained parts also.
1019
1020
1021 action_replace_with_url($entity, $doc_root, $base_url, $msg, [$cd_data,
1022 $salt])
1023 Drop the part, but save it in a unique location under $doc_root.
1024 The part is replaced with the text message $msg. The string
1025 "_URL_" in $msg is replaced with $base_url/something, that can
1026 be used to retrieve the message.
1027
1028 You should not use this function in filter_multipart.
1029
1030 This action is intended for stripping large parts out of the
1031 message and replacing them to a link on a Web server. Here's
1032 how you would use it in filter():
1033
1034 $size = (stat($entity->bodyhandle->path))[7];
1035 if ($size > 1000000) {
1036 return action_replace_with_url($entity,
1037 "/home/httpd/html/mail_parts",
1038 "http://mailserver.company.com/mail_parts",
1039 "The attachment was larger than 1,000,000 bytes.\n" .
1040 "It was removed, but may be accessed at this URL:\n\n" .
1041 "\t_URL_\n");
1042 }
1043
1044 This example moves attachments greater than 1,000,000 bytes into
1045 /home/httpd/html/mail_parts and replaces them with a link. The
1046 directory should be accessible via a Web server at
1047 http://mailserver.company.com/mail_parts.
1048
1049 The generated name is created by performing a SHA1 hash of the
1050 part and adding the extension to the ASCII-HEX representation of
1051 the hash. If many different e-mails are sent containing an
1052 identical large part, only one copy of the part is stored,
1053 regardless of the number of senders or recipients.
1054
1055 For privacy reasons, you must turn off Web server indexing in
1056 the directory in which you place mail parts, or anyone will be
1057 able to read them. If indexing is disabled, an attacker would
1058 have to guess the SHA1 hash of a part in order to read it.
1059
1060 Optionally, a fifth argument can supply data to be saved into a
1061 hidden dot filename based on the generated name. This data can
1062 then be read in on the fly by a CGI script or mod_perl module
1063 before serving the file to a web client, and used to add infor‐
1064 mation to the response, such as Content-Disposition data.
1065
1066 A sixth optional argument, $salt, is mixed in to the SHA1 hash.
1067 This salt can be any string and should be kept confidential.
1068 The salt is designed to prevent people from guessing whether or
1069 not a particular attachment has been received on your server by
1070 altering the SHA1 hash calculation.
1071
1072
1073 action_defang($entity, $name, $fname, $type)
1074 Accept the part, but change its name to $name, its suggested
1075 filename to $fname and its MIME type to $type. If $name or
1076 $fname are "", then mimedefang.pl generates generic names. Do
1077 not use this action in filter_multipart.
1078
1079 If you use action_defang, you must define a subroutine called
1080 defang_warning in your filter. This routine takes two argu‐
1081 ments: $oldfname (the original name of an attachment) and $fname
1082 (the defanged version.) It should return a message telling the
1083 user what happened. For example:
1084
1085 sub defang_warning {
1086 my($oldfname, $fname) = @_;
1087 return "The attachment '$oldfname' was renamed to '$fname'\n";
1088 }
1089
1090
1091
1092 action_external_filter($entity, $cmd)
1093 Run an external UNIX command $cmd. This command must read the
1094 part from the file ./FILTERINPUT and leave the result in ./FIL‐
1095 TEROUTPUT. If the command executes successfully, returns 1,
1096 otherwise 0. You can test the return value and call another
1097 action_ if the filter failed. Do not use this action in fil‐
1098 ter_multipart.
1099
1100
1101 action_quarantine($entity, $msg)
1102 Drop and quarantine the part, but add the warning $msg to the e-
1103 mail message.
1104
1105
1106 action_quarantine_entire_message($msg)
1107 Quarantines the entire message in a quarantine directory on the
1108 mail server, but does not otherwise affect disposition of the
1109 message. If "$msg" is non-empty, it is included in any adminis‐
1110 trator notification.
1111
1112
1113 action_sm_quarantine($reason)
1114 Quarantines a message in the Sendmail mail queue using the new
1115 QUARANTINE facility of Sendmail 8.13. Consult the Sendmail doc‐
1116 umentation for details about this facility. If you use
1117 action_sm_quarantine with a version of Sendmail that lacks the
1118 QUARANTINE facility, mimedefang will log an error message and
1119 not quarantine the message.
1120
1121
1122 action_bounce($reply, $code, $dsn)
1123 Reject the entire e-mail message with an SMTP failure code, and
1124 the one-line error message $reply. If the optional $code and
1125 $dsn arguments are supplied, they specify the numerical SMTP
1126 reply code and the extended status code (DSN code). If the
1127 codes you supply do not make sense for a bounce, they are
1128 replaced with "554" and "5.7.1" respectively.
1129
1130 action_bounce merely makes a note that the message is to be
1131 bounced; remaining parts are still processed. If action_bounce
1132 is called for more than one part, the mail is bounced with the
1133 message in the final call to action_bounce. You can profitably
1134 call action_quarantine followed by action_bounce if you want to
1135 keep a copy of the offending part. Note that the message is not
1136 bounced immediately; rather, remaining parts are processed and
1137 the message is bounced after all parts have been processed.
1138
1139 Note that despite its name, action_bounce does not generate a
1140 "bounce message". It merely rejects the message with an SMTP
1141 failure code.
1142
1143 WARNING: action_bounce() may cause the sending relay to generate
1144 spurious bounce messages if the sender address is faked. This
1145 is a particular problem with viruses. However, we believe that
1146 on balance, it's better to bounce a virus than to silently dis‐
1147 card it. It's almost never a good idea to hide a problem.
1148
1149
1150 action_tempfail($msg, $code, $dsn)
1151 Cause an SMTP "temporary failure" code to be returned, so the
1152 sending mail relay requeues the message and tries again later.
1153 The message $msg is included with the temporary failure code.
1154 If the optional $code and $dsn arguments are supplied, they
1155 specify the numerical SMTP reply code and the extended status
1156 code (DSN code). If the codes you supply do not make sense for
1157 a temporary failure, they are replaced with "450" and "4.7.1"
1158 respectively.
1159
1160
1161 action_discard()
1162 Silently discard the message, notifying nobody. You can prof‐
1163 itably call action_quarantine followed by action_discard if you
1164 want to keep a copy of the offending part. Note that the mes‐
1165 sage is not discarded immediately; rather, remaining parts are
1166 processed and the message is discarded after all parts have been
1167 processed.
1168
1169
1170 action_notify_sender($message)
1171 This action sends an e-mail back to the original sender with the
1172 indicated message. You may call another action after this one.
1173 If action_notify_sender is called more than once, the messages
1174 are accumulated into a single e-mail message -- at most one
1175 notification message is sent per incoming message. The message
1176 should be terminated with a newline.
1177
1178 The notification is delivered in deferred mode; you should run a
1179 client-queue runner if you are using Sendmail 8.12.
1180
1181 NOTE: Viruses often fake the sender address. For that reason,
1182 if a virus-scanner has detected a virus, action_notify_sender is
1183 disabled and will simply log an error message if you try to use
1184 it.
1185
1186
1187 action_notify_administrator($message)
1188 This action e-mails the MIMEDefang administrator the supplied
1189 message. You may call another action after this one;
1190 action_notify_administrator does not affect mail processing. If
1191 action_notify_administrator is called more than once, the mes‐
1192 sages are accumulated into a single e-mail message -- at most
1193 one notification message is sent per incoming message. The mes‐
1194 sage should be terminated with a newline.
1195
1196 The notification is delivered in deferred mode; you should run a
1197 client-queue runner if you are using Sendmail 8.12.
1198
1199
1200 anomy_clean_html($entity, {"name" => val , ...})
1201 If you have the Anomy mail cleaning tools (http://mail‐
1202 tools.anomy.net) and have installed the Anomy modules in a stan‐
1203 dard Perl include directory, this function uses an Anomy::HTML‐
1204 Cleaner object to sanitize the HTML code in $entity, which
1205 assumed to be of type text/html. The configuration arguments
1206 are optional; possible values are documented in comments in the
1207 Anomy/HTMLCleaner.pm Perl module.
1208
1209
1210 append_text_boilerplate($entity, $boilerplate, $all)
1211 This action should only be called from filter_end. It appends
1212 the text "\n$boilerplate\n" to the first text/plain part (if
1213 $all is 0) or to all text/plain parts (if $all is 1).
1214
1215
1216 append_html_boilerplate($entity, $boilerplate, $all)
1217 This action should only be called from filter_end. It adds the
1218 text "\n$boilerplate\n" to the first text/html part (if $all is
1219 0) or to all text/html parts (if $all is 1). This function
1220 tries to be smart about inserting the boilerplate; it uses
1221 HTML::Parser to detect closing tags and inserts the boilerplate
1222 before the </body> tag if there is one, or before the </html>
1223 tag if there is no </body>. If there is no </body> or </html>
1224 tag, it appends the boilerplate to the end of the part.
1225
1226 Do not use append_html_boilerplate unless you have installed the
1227 HTML::Parser Perl module.
1228
1229 Here is an example illustrating how to use the boilerplate func‐
1230 tions:
1231
1232 sub filter_end {
1233 my($entity) = @_;
1234 append_text_boilerplate($entity,
1235 "Lame text disclaimer", 0);
1236 append_html_boilerplate($entity,
1237 "<em>Lame</em> HTML disclaimer", 0);
1238 }
1239
1240
1241 action_add_part($entity, $type, $encoding, $data, $fname, $disposition
1242 [, $offset])
1243 This action should only be called from the filter_end routine.
1244 It adds a new part to the message, converting the original mes‐
1245 sage to mutipart if necessary. The function returns the part so
1246 that additional mime attributes may be set on it. Here's an
1247 example:
1248
1249 sub filter_end {
1250 my($entity) = @_;
1251
1252 action_add_part($entity, "text/plain", "-suggest",
1253 "This e-mail does not represent" .
1254 "the official policy of FuBar, Inc.\n",
1255 "disclaimer.txt", "inline");
1256 }
1257
1258 The $entity parameter must be the argument passed in to fil‐
1259 ter_end. The $offset parameter is optional; if omitted, it
1260 defaults to -1, which adds the new part at the end. See the
1261 MIME::Entity man page and the add_part member function for the
1262 meaning of $offset.
1263
1264 Note that action_add_part tries to be more intelligent than sim‐
1265 ply calling $entity->add_part. The decision process is as fol‐
1266 lows:
1267
1268
1269 o If the top-level entity is multipart/mixed, then the part is
1270 simply added.
1271
1272
1273 o Otherwise, a new top-level multipart/mixed container is gener‐
1274 ated, and the original top-level entity is made the first part
1275 of the multipart/mixed container. The new part is then added to
1276 the multipart/mixed container.
1277
1278
1280 mimedefang.pl includes some useful functions you can call from your
1281 filter:
1282
1283
1284 detect_and_load_perl_modules()
1285 Unless you really know what you're doing, this function must be
1286 called first thing in your filter file. It causes mimedefang.pl
1287 to detect and load Perl modules such as Mail::SpamAssassin,
1288 Net::DNS, etc., and to populate the %Features hash.
1289
1290
1291 send_quarantine_notifications()
1292 This function should be called from filter_end. If any parts
1293 were quarantined, a quarantine notification is sent to the
1294 MIMEDefang administrator. Please note that if you do not call
1295 send_quarantine_notifications, then no quarantine notifications
1296 are sent.
1297
1298
1299 get_quarantine_dir()
1300 This function returns the full path name of the quarantine
1301 directory. If you have not yet quarantined any parts of the
1302 message, a quarantine directory is created and its pathname
1303 returned.
1304
1305
1306 change_sender($sender)
1307 This function changes the envelope sender to $sender. It can
1308 only be called from filter_begin or any later function. Please
1309 note that this function is only supported with Sendmail/Milter
1310 8.14.0 or newer. It has no effect if you're running older ver‐
1311 sions.
1312
1313
1314 add_recipient($recip)
1315 This function adds $recip to the list of envelope recipients. A
1316 copy of the message (after any modifications by MIMEDefang) will
1317 be sent to $recip in addition to the original recipients. Note
1318 that add_recipient does not modify the @Recipients array; it
1319 just makes a note to Sendmail to add the recipient.
1320
1321
1322 delete_recipient($recip)
1323 This function deletes $recip from the list of recipients. That
1324 person will not receive a copy of the mail. $recip should
1325 exactly match an entry in the @Recipients array for
1326 delete_recipient() to work. Note that delete_recipient does not
1327 modify the @Recipients array; it just makes a note to Sendmail
1328 to delete the recipient.
1329
1330 resend_message($recip1, $recip2, ...)
1331 or
1332
1333 resend_message(@recips)
1334 This function immediately resends the original, unmodified mail
1335 message to each of the named recipients. The sender's address
1336 is preserved. Be very careful when using this function, because
1337 it resends the original message, which may contain undesired
1338 attachments. Also, you should not call this function from fil‐
1339 ter(), because it resends the message each time it is called.
1340 This may result in multiple copies being sent if you are not
1341 careful. Call from filter_begin() or filter_end() to be safe.
1342
1343 The function returns true on success, or false if it fails.
1344
1345 Note that the resend_message function delivers the mail in
1346 deferred mode (using Sendmail's "-odd" flag.) You must run a
1347 client-submission queue processor if you use Sendmail 8.12. We
1348 recommend executing this command as part of the Sendmail startup
1349 sequence:
1350
1351 sendmail -Ac -q5m
1352
1353
1354 remove_redundant_html_parts($entity)
1355 This function should only be called from filter_end. It removes
1356 redundant HTML parts from the message. It works by deleting any
1357 part of type text/html from the message if (1) it is a sub-part
1358 of a multipart/alternative part, and (2) there is another part
1359 of type text/plain under the multipart/alternative part.
1360
1361
1362 replace_entire_message($entity)
1363 This function can only be called from filter_end. It replaces
1364 the entire message with $entity, a MIME::Entity object that you
1365 have constructed. You can use any of the MIME::Tools functions
1366 to construct the entity.
1367
1368
1369 read_commands_file()
1370 This function should only be called from filter_sender and fil‐
1371 ter_recipient. This will read the COMMANDS file (as described in
1372 mimedefang-protocol(7)), and will fill or update the following
1373 global variables: $Sender, @Recipients, %RecipientMailers,
1374 $RelayAddr, $RealRelayAddr, $RelayHostname, $RealRelayHostname,
1375 $QueueID, $Helo, %SendmailMacros.
1376
1377 If you do not call read_commands_file, then the only information
1378 available in filter_sender and filter_recipient is that which is
1379 passed as an argument to the function.
1380
1381
1382 stream_by_domain()
1383 Do not use this function unless you have Sendmail 8.12 and
1384 locally- submitted e-mail is submitted using SMTP.
1385
1386 This function should only be called at the very beginning of
1387 filter_begin(), like this:
1388
1389 sub filter_begin {
1390 if (stream_by_domain()) {
1391 return;
1392 }
1393 # Rest of filter_begin
1394 }
1395
1396 stream_by_domain() looks at all the recipients of the message,
1397 and if they belong to the same domain (e.g., joe@domain.com,
1398 jane@domain.com and sue@domain.com), it returns 0 and sets the
1399 global variable $Domain to the domain (domain.com in this exam‐
1400 ple.)
1401
1402 If users are in different domains, stream_by_domain() resends
1403 the message (once to each domain) and returns 1 For example, if
1404 the original recipients are joe@abc.net, jane@xyz.net and
1405 sue@abc.net, the original message is resent twice: One copy to
1406 joe@abc.net and sue@abc.net, and another copy to jane@xyz.net.
1407 Also, any subsequent scanning is canceled (filter() and fil‐
1408 ter_end() will not be called for the original message) and the
1409 message is silently discarded.
1410
1411 If you have Sendmail 8.12, then locally-submitted messages are
1412 sent via SMTP, and MIMEDefang will be called for each resent
1413 message. It is possible to set up Sendmail 8.12 so locally-sub‐
1414 mitted messages are delivered directly; in this case,
1415 stream_by_domain will not work.
1416
1417 Using stream_by_domain allows you to customize your filter rules
1418 for each domain. If you use the function as described above,
1419 you can do this in your filter routine:
1420
1421 sub filter {
1422 my($entity, $fname, $ext, $type) = @_;
1423 if ($Domain eq "abc.com") {
1424 # Filter actions for abc.com
1425 } elsif ($Domain eq "xyz.com") {
1426 # Filter actions for xyz.com
1427 } else {
1428 # Default filter actions
1429 }
1430 }
1431
1432 You cannot rely on $Domain being set unless you have called
1433 stream_by_domain().
1434
1435
1436 stream_by_recipient()
1437 Do not use this function unless you have Sendmail 8.12 and
1438 locally- submitted e-mail is submitted using SMTP.
1439
1440 This function should only be called at the very beginning of
1441 filter_begin(), like this:
1442
1443 sub filter_begin {
1444 if (stream_by_recipient()) {
1445 return;
1446 }
1447 # Rest of filter_begin
1448 }
1449
1450 If there is more than one recipient, stream_by_recipient()
1451 resends the message once to each recipient. That way, you can
1452 customize your filter rules on a per-recipient basis. This may
1453 increase the load on your mail server considerably.
1454
1455 Also, a "recipient" is determined before alias expansion. So
1456 "all@mydomain.com" is considered a single recipient, even if
1457 Sendmail delivers to a list.
1458
1459 If you have Sendmail 8.12, then locally-submitted messages are
1460 sent via SMTP, and MIMEDefang will be called for each resent
1461 message. It is possible to set up Sendmail 8.12 so locally-sub‐
1462 mitted messages are delivered directly; in this case,
1463 stream_by_recipient() will not work.
1464
1465 stream_by_recipient() allows you to customize your filter rules
1466 for each recipient in a manner similar to stream_by_domain().
1467
1468
1470 md_graphdefang_log_enable($facility, $enum_recips)
1471 Enables the md_graphdefang_log function (described next). The
1472 function logs to syslog using the specified facility. If you
1473 omit $facility, it defaults to 'mail'. If you do not call
1474 md_graphdefang_log_enable in your filter, then any calls to
1475 md_graphdefang_log simply do nothing.
1476
1477 If you supply $enum_recips as 1, then a line of logging is out‐
1478 put for each recipient of a mail message. If it is zero, then
1479 only a single line is output for each message. If you omit
1480 $enum_recips, it defaults to 1.
1481
1482
1483 md_graphdefang_log($event, $v1, $v2)
1484 Logs an event with up to two optional additional parameters.
1485 The log message has a specific format useful for graphing tools;
1486 the message looks like this:
1487
1488 MDLOG,msgid,event,v1,v2,sender,recipient,subj
1489
1490 "MDLOG" is literal text. "msgid" is the Sendmail queue identi‐
1491 fier. "event" is the event name, and "v1" and "v2" are the
1492 additional parameters. "sender" is the sender's e-mail address.
1493 "recipient" is the recipient's e-mail address, and "subj" is the
1494 message subject. If a message has more than one recipient,
1495 md_graphdefang_log may log an event message for each recipient,
1496 depending on how you called md_graphdefang_log_enable.
1497
1498 Note that md_graphdefang_log should not be used in filter_relay,
1499 filter_sender or filter_recipient. The global variables it
1500 relies on are not valid in that context.
1501
1502 If you want to log general text strings, do not use md_graphde‐
1503 fang_log. Instead, use md_syslog (described next).
1504
1505
1506 md_syslog($level, $msg)
1507 Logs the message $msg to syslog, using level $level. The level
1508 is a literal string, and should be one of 'err', 'debug', 'warn‐
1509 ing', ´emerg', 'crit', 'notice' or 'info'. (See syslog(3) for
1510 details.)
1511
1512 Note that md_syslog does not perform %-subsitutions like sys‐
1513 log(3) does. Depending on your Perl installation, md_syslog
1514 boils down to a call to Unix::Syslog::syslog or Sys::Sys‐
1515 log::syslog. See the Unix::Syslog or Sys::Syslog man pages for
1516 more details.
1517
1518
1519 md_openlog($tag, $facility)
1520 Sets the tag used in syslog messages to $tag, and sends the logs
1521 to the $facility facility. If you do not call md_openlog before
1522 you call md_syslog, then it is called implicitly with $tag set
1523 to mimedefang.pl and $facility set to mail.
1524
1525
1527 mimedefang.pl includes the following functions for looking up IP
1528 addresses in DNS-based real-time blacklists.
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.64").
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_fprotd()
1818
1819 message_contains_virus_nod32()
1820
1821 These functions should be called in list context. They use the
1822 indicated anti-virus software to scan the message for viruses.
1823 These functions are intended for use in filter_begin() to make
1824 an initial scan of the e-mail message.
1825
1826 The supported virus scanners are:
1827
1828 nai NAI "uvscan" - http://www.nai.com/
1829
1830 Bitdefender "bdc" - http://www.bitdefender.com/
1831
1832 csav Command Anti-Virus - http://www.commandsoftware.com/
1833
1834 fsav F-Secure Anti-Virus - http://www.f-secure.com/
1835
1836 hbedv H+BEDV "AntiVir" - http://www.hbedv.com/
1837
1838 vexira Vexira "Vexira" - http://www.centralcommand.com/
1839
1840 sophos Sophos AntiVirus - http://www.sophos.com/
1841
1842 avp Kaspersky AVP and aveclient (AVP5) - http://www.avp.ru/
1843
1844 clamav Clam AntiVirus - http://www.clamav.net/
1845
1846 f-prot F-RISK F-PROT - http://www.f-prot.com/
1847
1848 nod32cli
1849 ESET NOD32 - http://www.eset.com/
1850
1851
1852 message_contains_virus_carrier_scan([$host])
1853 Connects to the specified host:port:local_or_nonlocal (default
1854 $CSSHost), where the Symantec CarrierScan Server daemon is
1855 expected to be listening. Return values are the same as the
1856 other message_contains_virus functions.
1857
1858
1859 message_contains_virus_sophie([$sophie_sock])
1860 Connects to the specified socket (default $SophieSock), where
1861 the Sophie daemon is expected to be listening. Return values
1862 are the same as the other message_contains_virus functions.
1863
1864
1865 message_contains_virus_clamd([$clamd_sock])
1866 Connects to the specified socket (default $ClamdSock), where the
1867 clamd daemon is expected to be listening. Return values are the
1868 same as the other message_contains_virus functions.
1869
1870
1871 message_contains_virus_trophie([$trophie_sock])
1872 Connects to the specified socket (default $TrophieSock), where
1873 the Trophie daemon is expected to be listening. Return values
1874 are the same as the other message_contains_virus functions.
1875
1876
1877 entity_contains_virus($entity)
1878
1879 This function runs the specified MIME::Entity through every
1880 installed virus-scanner and returns the scanner results. The
1881 return values are the same as for message_contains_virus().
1882
1883
1884 entity_contains_virus_trend($entity)
1885
1886 entity_contains_virus_nai($entity)
1887
1888 entity_contains_virus_bdc($entity)
1889
1890 entity_contains_virus_nvcc($entity)
1891
1892 entity_contains_virus_csav($entity)
1893
1894 entity_contains_virus_fsav($entity)
1895
1896 entity_contains_virus_hbedv($entity)
1897
1898 entity_contains_virus_sophos($entity)
1899
1900 entity_contains_virus_clamav($entity)
1901
1902 entity_contains_virus_avp($entity)
1903
1904 entity_contains_virus_avp5($entity)
1905
1906 entity_contains_virus_fprot($entity)
1907
1908 entity_contains_virus_fprotd($entity)
1909
1910 entity_contains_virus_nod32($entity)
1911 These functions, meant to be called from filter(), are similar
1912 to the message_contains_virus functions except they scan only
1913 the current part. They should be called from list context, and
1914 their return values are as described for the message_con‐
1915 tains_virus functions.
1916
1917
1918 entity_contains_virus_carrier_scan($entity[, $host])
1919 Connects to the specified host:port:local_or_nonlocal (default
1920 $CSSHost), where the Symantec CarrierScan Server daemon is
1921 expected to be listening. Return values are the same as the
1922 other entity_contains_virus functions.
1923
1924
1925 entity_contains_virus_sophie($entity[, $sophie_sock])
1926 Connects to the specified socket (default $SophieSock), where
1927 the Sophie daemon is expected to be listening. Return values
1928 are the same as the other entity_contains_virus functions.
1929
1930
1931 entity_contains_virus_trophie($entity[, $trophie_sock])
1932 Connects to the specified socket (default $TrophieSock), where
1933 the Trophie daemon is expected to be listening. Return values
1934 are the same as the other entity_contains_virus functions.
1935
1936
1937 entity_contains_virus_clamd($entity[, $clamd_sock])
1938 Connects to the specified socket (default $ClamdSock), where the
1939 clamd daemon is expected to be listening. Return values are the
1940 same as the other entity_contains_virus functions.
1941
1942
1944 This section illustrates the flow of messages through MIMEDefang.
1945
1946
1947 1. INITIAL CONNECTION
1948 If you invoked mimedefang with the -r option and have defined a
1949 filter_relay routine, it is called.
1950
1951
1952 2. SMTP HELO COMMAND
1953 The HELO string is stored internally, but no filter functions
1954 are called.
1955
1956
1957 3. SMTP MAIL FROM: COMMAND
1958 If you invoked mimedefang with the -s option and have defined a
1959 filter_sender routine, it is called.
1960
1961
1962 4. SMTP RCPT TO: COMMAND
1963 If you invoked mimedefang with the -t option and have defined a
1964 filter_recipient routine, it is called.
1965
1966
1967 5. END OF SMTP DATA
1968 filter_begin is called. For each MIME part, filter is called.
1969 Then filter_end is called.
1970
1971
1973 Most organizations have more than one machine handling internet e-mail.
1974 If the primary machine is down, mail is routed to a secondary (or ter‐
1975 tiary, etc.) MX server, which stores the mail until the primary MX host
1976 comes back up. Mail is then relayed to the primary MX host.
1977
1978
1979 Relaying from a secondary to a primary MX host has the unfortunate side
1980 effect of losing the original relay's IP address information. MIMEDe‐
1981 fang allows you to preserve this information. One way around the prob‐
1982 lem is to run MIMEDefang on all the secondary MX hosts and use the same
1983 filter. However, you may not have control over the secondary MX hosts.
1984 If you can persuade the owners of the secondary MX hosts to run MIMEDe‐
1985 fang with a simple filter that only preserves relay information and
1986 does no other scanning, your primary MX host can obtain relay informa‐
1987 tion and make decisions using $RelayAddr and $RelayHostname.
1988
1989
1990 When you configure MIMEDefang, supply the "--with-ipheader" argument to
1991 the ./configure script. When you install MIMEDefang, a file called
1992 /etc/mail/mimedefang-ip-key will be created which contains a randomly-
1993 generated header name. Copy this file to all of your mail relays. It
1994 is important that all of your MX hosts have the same key. The key
1995 should be kept confidential, but it's not disastrous if it leaks out.
1996
1997
1998 On your secondary MX hosts, add this line to filter_end:
1999
2000 add_ip_validation_header();
2001
2002
2003 Note: You should only add the validation header to mail destined for
2004 one of your other MX hosts! Otherwise, the validation header will leak
2005 out.
2006
2007
2008 When the secondary MX hosts relay to the primary MX host, $RelayAddr
2009 and $RelayHostname will be set based on the IP validation header. If
2010 MIMEDefang notices this header, it sets the global variable $WasResent
2011 to 1. Since you don't want to trust the header unless it was set by
2012 one of your secondary MX hosts, you should put this code in fil‐
2013 ter_begin:
2014
2015 if ($WasResent) {
2016 if ($RealRelayAddr ne "ip.of.secondary.mx" and
2017 $RealRelayAddr ne "ip.of.tertiary.mx") {
2018 $RelayAddr = $RealRelayAddr;
2019 $RelayHostname = $RealRelayHostname;
2020 }
2021 }
2022
2023 This resets the relay address and hostname to the actual relay address
2024 and hostname, unless the message is coming from one of your other MX
2025 hosts.
2026
2027
2028 On the primary MX host, you should add this in filter_begin:
2029
2030 delete_ip_validation_header();
2031
2032
2033 This prevents the validation header from leaking out to recipients.
2034
2035
2036 Note: The IP validation header works only in message-oriented func‐
2037 tions. It (obviously) has no effect on filter_relay, filter_sender and
2038 filter_recipient, because no header information is available yet. You
2039 must take this into account when writing your filter; you must defer
2040 relay-based decisions to the message filter for mail arriving from your
2041 other MX hosts.
2042
2043
2045 The following list describes the lifetime of global variables (thanks
2046 to Tony Nugent for providing this documentation.)
2047
2048 If you set a global variable:
2049
2050
2051 Outside a subroutine in your filter file
2052 It is available to all functions, all the time.
2053
2054
2055 In filter_relay, filter_sender or filter_recipient
2056 Not guaranteed to be available to any other function, not even
2057 from one filter_recipient call to the next, when receiving a
2058 multi-recipient email message.
2059
2060
2061 In filter_begin
2062 Available to filter_begin, filter and filter_end
2063
2064
2065 In filter
2066 Available to filter and filter_end
2067
2068
2069 In filter_end
2070 Available within filter_end
2071
2072
2073 The "built-in" globals like $Subject, $Sender, etc. are always avail‐
2074 able to filter_begin, filter and filter_end. Some are available to fil‐
2075 ter_relay, filter_sender or filter_recipient, but you should check the
2076 documentation of the variable above for details.
2077
2078
2080 There are four basic groups of filtering functions:
2081
2082
2083 1 filter_relay
2084
2085
2086 2 filter_sender
2087
2088
2089 3 filter_recipient
2090
2091
2092 4 filter_begin, filter, filter_multipart, filter_end
2093
2094
2095 In general, for a given mail message, these groups of functions may be
2096 called in completely different Perl processes. Thus, there is no way
2097 to maintain state inside Perl between groups of functions. That is,
2098 you cannot set a variable in filter_relay and expect it to be available
2099 in filter_sender, because the filter_sender invocation might take place
2100 in a completely different process.
2101
2102
2103 However, for a given mail message, the $CWD global variable holds the
2104 message spool directory, and the current working directory is set to
2105 $CWD. Therefore, you can store state in files inside $CWD. If fil‐
2106 ter_sender stores data in a file inside $CWD, then filter_recipient can
2107 retrieve that data.
2108
2109
2110 Since filter_relay is called directly after a mail connection is estab‐
2111 lished, there is no message context yet, no per-message mimedefang
2112 spool directory, and the $CWD global is not set. Therefore, it is not
2113 possible to share information from filter_relay to one of the other
2114 filter functions. The only thing that filter_relay has in common with
2115 the other functions are the values in the globals $RelayAddr and
2116 $RelayHostname. These could be used to access per-remote-host informa‐
2117 tion in some database.
2118
2119
2120 Inside $CWD, we reserve filenames beginning with upper-case letters for
2121 internal MIMEDefang use. If you want to create files to store state,
2122 name them beginning with a lower-case letter to avoid clashes with
2123 future releases of MIMEDefang.
2124
2125
2127 If you have Sendmail 8.13 or later, and have compiled it with the SOCK‐
2128 ETMAP option, then you can use a special map type that communicates
2129 over a socket with another program (rather than looking up a key in a
2130 Berkeley database, for example.)
2131
2132
2133 mimedefang-multiplexor implements the Sendmail SOCKETMAP protocol if
2134 you supply the -N option. In that case, you can define a function
2135 called filter_map to implement map lookups. filter_map takes two argu‐
2136 ments: $mapname is the name of the Sendmail map (as given in the K
2137 sendmail configuration directive), and $key is the key to be looked up.
2138
2139
2140 filter_map must return a two-element list: ($code, $val) $code can be
2141 one of:
2142
2143
2144 OK The lookup was successful. In this case, $val must be the
2145 result of the lookup
2146
2147
2148 NOTFOUND
2149 The lookup was unsuccessful -- the key was not found. In this
2150 case, $val should be the empty string.
2151
2152
2153 TEMP There was a temporary failure of some kind. $val can be an
2154 explanatory error message.
2155
2156
2157 TIMEOUT
2158 There was a timeout of some kind. $val can be an explanatory
2159 error message.
2160
2161
2162 PERM There was a permanent failure. This is not the same as an
2163 unsuccessful lookup; it should be used only to indicate a seri‐
2164 ous misconfiguration. As before, $val can be an explanatory
2165 error message.
2166
2167
2168 Consider this small example. Here is a minimal Sendmail configuration
2169 file:
2170
2171 V10/Berkeley
2172 Kmysock socket unix:/var/spool/MIMEDefang/map.sock
2173 kothersock socket unix:/var/spool/MIMEDefang/map.sock
2174
2175
2176 If mimedefang-multiplexor is invoked with the arguments -N
2177 unix:/var/spool/MIMEDefang/map.sock, and the filter defines filter_map
2178 as follows:
2179
2180 sub filter_map ($$) {
2181 my($mapname, $key) = @_;
2182 my $ans;
2183 if($mapname ne "mysock") {
2184 return("PERM", "Unknown map $mapname");
2185 }
2186 $ans = reverse($key);
2187 return ("OK", $ans);
2188 }
2189
2190 Then in Sendmail's testing mode, we see the following:
2191
2192 > /map mysock testing123
2193 map_lookup: mysock (testing123) returns 321gnitset (0)
2194 > /map othersock foo
2195 map_lookup: othersock (foo) no match (69)
2196
2197
2198 (The return code of 69 means EX_UNAVAILABLE or Service Unavailable)
2199
2200
2201 A real-world example could do map lookups in an LDAP directory or SQL
2202 database, or perform other kinds of processing. You can even implement
2203 standard Sendmail maps like virtusertable, mailertable, access_db, etc.
2204 using SOCKETMAP.
2205
2206
2208 If you supply the -X option to mimedefang-multiplexor, then every so
2209 often, a "tick" request is sent to a free slave. If your filter
2210 defines a function called filter_tick, then this function is called
2211 with a single argument: the tick type. If you run multiple parallel
2212 ticks, then each tick has a type ranging from 0 to n-1, where n is the
2213 number of parallel ticks. If you're only running one tick request,
2214 then the argument to filter_tick is always 0.
2215
2216 You can use this facility to run periodic tasks from within MIMEDefang.
2217 Note, however, that you have no control over which slave is picked to
2218 run filter_tick. Also, at most one filter_tick call with a particular
2219 "type" argument will be active at any time, and if there are no free
2220 slaves when a tick would occur, the tick is skipped.
2221
2222
2224 The following virus scanners are supported by MIMEDefang:
2225
2226
2227 o Symantec CarrierScan Server (http://www.syman‐
2228 tec.com/region/can/eng/product/scs/)
2229
2230
2231 o Trend Micro vscan (http://www.antivirus.com/)
2232
2233
2234 o Sophos Sweep (http://www.sophos.com/products/antivirus/savu‐
2235 nix.html)
2236
2237
2238 o H+BEDV AntiVir (http://www.hbedv.com/)
2239
2240
2241 o Central Command Vexira (http://www.centralcommand.com/)
2242
2243
2244 o NAI uvscan (http://www.nai.com)
2245
2246
2247 o Bitdefender bdc (http://www.bitdefender.com)
2248
2249
2250 o Norman Virus Control (NVCC) (http://www.norman.no/)
2251
2252
2253 o Command csav (http://www.commandsoftware.com)
2254
2255
2256 o F-Secure fsav (http://www.f-secure.com)
2257
2258
2259 o The clamscan command-line scanner and the clamd daemon from Clam
2260 AntiVirus (http://www.clamav.net/)
2261
2262
2263 o Kaspersky Anti-Virus (AVP) (http://www.kaspersky.com/)
2264
2265
2266 o F-Risk F-Prot (http://www.f-prot.com/)
2267
2268
2269 o F-Risk FPROTD (daemonized version of F-Prot)
2270
2271
2272 o Symantec CarrierScan Server (http://www.syman‐
2273 tec.ca/region/can/eng/product/scs/buymenu.html)
2274
2275
2276 o Sophie (http://www.vanja.com/tools/sophie/), which uses the lib‐
2277 savi library from Sophos, is supported in daemon-scanning mode.
2278
2279
2280 o Trophie (http://www.vanja.com/tools/trophie/), which uses the
2281 libvsapi library from Trend Micro, is supported in daemon-scan‐
2282 ning mode.
2283
2284
2285 o ESET NOD32 (http://www.eset.com/)
2286
2287
2289 mimedefang was written by David F. Skoll <dfs@roaringpenguin.com>. The
2290 mimedefang home page is http://www.mimedefang.org/.
2291
2292
2294 mimedefang(8), mimedefang.pl(8)
2295
2296
2297
2298
2299
2300
23014th Berkeley Distribution 8 February 2005 MIMEDEFANG-FILTER(5)