NAME¶
mimedefang-protocol - Conventions used by
mimedefang(8) to communicate
with filter programs.
DESCRIPTION¶
mimedefang(8) and
mimedefang-multiplexor(8) provide a simplified
mechanism for hooking scripts and programs into Sendmail's milter API.
The milter API is multi-threaded and written in C;
mimedefang lets you
write single-threaded filters written in the language of your choice. Some of
the flexibility and speed of milter is sacrificed, but the ease of writing
filters more than compensates for this slight loss.
This manual describes how
mimedefang communicates with the filter
program, and gives you enough information to write your own filter program as
a replacement for
mimedefang.pl if you wish.
PROTOCOL OVERVIEW¶
The protocol is a simple file-based protocol. For each invocation of a filter,
mimedefang creates a unique working directory and populates it with
files. It calls the filter, which is expected to populate the working
directory with more files, which communicate the scan results back to
mimedefang. This simple mechanism allows you to easily write filters in
scripting languages without worrying about C-level details.
FILTER INVOCATION¶
The filter program may be invoked in one of five ways:
- filter_prog directory
- If the program is invoked with a single argument which is
an absolute path name (called the working directory, the program is
expected to perform filtering in that directory and then exit.
- filter_prog -server
- If the program is invoked with the single argument
-server, it is expected to run as a server. See SERVER MODE for
details.
- filter_prog -serveru
- If the program is invoked with the single argument
-serveru, it is expected to run as a server. In addition, anything
it prints to file descriptor 3 is used to update the "slave
status" field in the multiplexor. This lets the filter inform
administrators exactly what it is doing. (See the -Z option to
mimedefang-multiplexor.)
- filter_prog -embserver
- Similar to -server, but used by the embedded Perl
code. The program should run any initialization routines and then exit.
The multiplexor will subsequently call the Perl routine
do_main_loop when it is time for the slave to begin running in
server mode.
- filter_prog -embserveru
- Similar to -embserver with the additional magic of
updating the slave status from data written to file descriptor 3.
INITIAL FILE LAYOUT¶
When the filter begins a scan, it should change directories to the working
directory. In that directory, it will find the following files.
- INPUTMSG
- A file containing the complete input e-mail message,
including headers.
- HEADERS
- A file containing just the headers, one per line. Headers
which are continued over several lines in the original message are
collapsed into a single line in this file.
- COMMANDS
- A file containing a list of commands. Each command is a
single letter and may be followed by arguments. Each command is on its own
line.
THE COMMANDS FILE¶
All commands have their arguments encoded as follows: All characters outside the
range 33 to 126 ASCII, as well as the characters "%", "\",
"'" and double-quote, are replaced by a percent sign followed by two
hex digits specifying the character's numerical value. The filter must
un-escape the arguments when it reads the COMMANDS file.
The commands from the C to Perl filters are:
- Ssender
- The sender of the message.
- sesmtp_arg
- An ESMTP argument associated with the sender (such as
SIZE=54432). There is one s line for each ESMTP argument.
- Usubject
- The message subject.
- Xmessage_id
- The Message-ID.
- Rrecipient mailer host
addr
- A recipient. There is one R line for each recipient.
The mailer, host and addr parts of the line are the
values of the Sendmail {rcpt_mailer}, {rcpt_host} and {rcpt_addr} macros
if they are available, or "?" if not.
- resmtp_arg
- An ESMTP argument associated with the most recent
recipient (such as NOTIFY=never). There is one r line for each SMTP
argument.
- !
- If this command is present, there are suspicious characters
in the message headers.
- ?
- If this command is present, there are suspicious characters
in the message body.
- Ihost_addr
- The SMTP relay host's IP address in dotted-quad notation.
- iidentifier
- An identifier generated by MIMEDefang. On a given host,
this identifier is very likely to be unique over a timespan of about 24
years.
- Jhost_addr
- The "real" SMTP relay host's IP address in
dotted-quad notation. Multi-stage MIMEDefang relays can use a special IP
validation header so that even the innermost MIMEDefang relay can see the
"original" relay's IP address.
- Hhost_name
- The SMTP relay host name.
- Eargument
- The argument to the SMTP "EHLO" or
"HELO" command.
- Qqid
- The message's Sendmail queue-ID.
- =macro val
- Set the value of the specified Sendmail macro to
val. Both macro and val are percent-encoded, but the
single space character between them is not.
FILTER OPERATION¶
When the filter performs a scan, it can make use of all the information in the
files mentioned previously. If the filter needs temporary working files, it
should create a subdirectory under the working directory for its own use. In
this case, you do not have to clean up your working files, because
mimedefang deletes the working directory when the filter returns.
FINAL FILE LAYOUT¶
The filter communicates the results of the scan back to
mimedefang by
creating additional files in the working directory. The most important file is
called RESULTS, and it contains a list of one-letter, one-line commands back
to the filter. As usual, command arguments are percent-escaped. The commands
from the filter back to
mimedefang are:
- Bcode dsn reply_text
- Bounce (reject) the message with the specified SMTP reply
code, DSN code and reply text.
- D
- Silently discard the message and pretend it was delivered.
- Tcode dsn reply_text
- Return an SMTP temporary failure code with the specified
SMTP code, DSN and reply text.
- C
- Replace the message body. If this command is present, the
file NEWBODY must contain the new message body.
- Mheader_val
- Replace the MIME Content-Type header with a new value. Used
to change MIME boundaries or convert non-MIME to MIME messages.
- Hheader val
- Add a new header header with value val. The
header should not contain a colon. Each of header and
val is percent-escaped, but the single space between them is not.
- Nheader index val
- Adds a new header header with value val in
position index. An index of zero specifies that the new header
should be prepended before all existing headers.
- Iheader index val
- Replace the index'th occurrence of header
with value val. The index is 1-based. The header
should not contain a colon. Each of header, index and
val is percent-escaped, but the single space between them is not.
- Jheader index
- Delete the index'th occurrence of header.
- Rrecip
- Add a new recipient recip to the message.
- Srecip
- Delete recip from the list of message recipients.
- fsender
- Change the envelope sender to sender. This is only
supported by Sendmail 8.14.0 and higher.
- F
- Indicate that we have finished issuing commands. Anything
after an F line is ignored.
SERVER MODE¶
In server mode,
mimedefang-multiplexor runs the filter program
continuously in a server loop. The filter program reads commands from standard
input, and writes results to standard output. The filter program
must
exit shortly after it sees EOF on its standard input. If it does not exit
within 10 seconds, it will be terminated with SIGTERM. If that still does not
work, then after a further 10 seconds, it is killed with SIGKILL.
- SERVER COMMANDS
-
All server commands are single line commands. Each command is followed by a
space-separated list of arguments; each argument is percent-encoded. The
commands defined are:
- ping
- Elicits a reply of "PONG" from the server.
- scan dir
- Run a scan in the directory dir. The command is
terminated with a newline. The server must write a newline-terminated
"ok" if the scan completed successfully, or "error:
msg" if something went wrong.
-
relayok ip_addr hostname
- Test whether or not to accept a connection from the
specified host. The server must write "ok 1" if we will accept
the connection, or "ok 0 error_message code dsn" if not. It can
indicate a temporary failure by writing "ok -1 error_message code
dsn". Note that even if the connection is accepted, a later scan can
still reject the message based on other criteria. "ip_addr" is
the IP address of the relay and "hostname" is the hostname (if
it could be determined; otherwise, the IP address in square brackets).
- senderok sender_addr ip_addr
hostname helo_string dir queue_id
[esmtp_args...]
-
Test whether or not to accept mail from the specified sender. The server
must write "ok 1" if we will accept the mail attempt, or
"ok 0 error_message code dsn" if not. "ok -1 error_message
code dsn" indicates a temporary failure. Note that even if the sender
is accepted, a later scan can still reject the message based on other
criteria. "sender_addr" is the sender's e-mail address. The
"ip_addr" and "hostname" arguments are as in
relayok. "helo_string" is the argument to the SMTP
HELO/EHLO command. "dir" is the MIMEDefang spool directory, and
"queue_id" is the Sendmail queue identifier.
The optional "esmtp_args" are space-separated, percent-encoded
ESMTP arguments supplied with the MAIL FROM: command.
- recipok recip_addr sender_addr
ip_addr hostname first_recip helo_string
dir queue_id [esmtp_args...]
- Test whether or not to accept mail for the specified
recipient. The server must write "ok 1" if we will accept it, or
"ok 0 error_message code dsn" if not. ok -1 error_message code
dsn" indicates a temporary-failure.
"recip_addr" is the argument to the RCPT TO: command, and
"first_recip" is the argument to the first RCPT TO: command for
this message. Other arguments are as in senderok.
- map map_name key
- If you are using a map socket (the -N option to
mimedefang-multiplexor), then the server should look up the key
key in the map map_name. The server should print a single
line to standard output. The first word on the line should be one of OK,
NOTFOUND, TEMP, TIMEOUT or PERM, indicating a successful lookup, absence
of the key, a temporary failure, a timeout or a permanent failure,
respectively. This should be followed by a space and a percent-encoded
string representing the value of the key (if it was found) or an optional
error message (if something went wrong.)
- tick band
- The filter should run filter_tick with the specified
band argument. It should print a single line to standard output:
tock band
- Additional Commands
- The filter can define a function filter_unknown_cmd
that can extend the list of server commands. If you do this, make sure all
of your commands start with an upper-case letter to avoid conflicts if
more built-in commands are defined in the future.
- SERVER REPLIES
-
The reply codes are:
- ok [return_code] [parameters]
- The operation completed successfully. Some operations have
an associated return code, and possibly other parameters as well. See the
source code for the gory details.
- error: Message
- The operation failed. Message may give additional
details.
In server mode, you should
not write anything to standard output except
reply codes, or the multiplexor will become confused. You should
not
terminate the program in server mode; simply echo an
error: reply and
return to the server loop.
When you send a reply code back to the multiplexor, be sure to terminate it with
a newline, and to flush standard output. If your program uses the Standard I/O
library, standard output may not be flushed immediately, and
mimedefang-multiplexor will wait forever for the filter's reply, and
eventually kill the filter on the assumption it has hung up.
In server mode, if the filter program receives a SIGINT signal, it must
terminate. This is used by
mimedefang-multiplexor to terminate slaves
after they have processed a given number of e-mail messages.
AUTHOR¶
mimedefang was written by David F. Skoll <dfs@roaringpenguin.com>.
The
mimedefang home page is
http://www.mimedefang.org/.
SEE ALSO¶
mimedefang.pl(8),
mimedefang(8),
mimedefang-multiplexor(8),
mimedefang-filter(5)