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