README revision 266692
1284285SjkimThis directory contains the source files for libmilter.
2110010Smarkm
3110010SmarkmThe sendmail Mail Filter API (Milter) is designed to allow third-party
4142429Snectarprograms access to mail messages as they are being processed in order to
5110010Smarkmfilter meta-information and content.
6110010Smarkm
7110010SmarkmThis README file describes the steps needed to compile and run a filter,
8110010Smarkmthrough reference to a sample filter which is attached at the end of this
9110010Smarkmfile.  It is necessary to first build libmilter.a, which can be done by
10110010Smarkmissuing the './Build' command in SRCDIR/libmilter .
11110010Smarkm
12110010SmarkmStarting with 8.13 sendmail is compiled by default with support for
13110010Smarkmthe milter API.
14110010Smarkm
15110010SmarkmNote: if you want to write a milter in Java, then see
16110010Smarkmhttp://sendmail-jilter.sourceforge.net/
17110010Smarkm
18110010Smarkm+----------------+
19110010Smarkm| SECURITY HINTS |
20215698Ssimon+----------------+
21215698Ssimon
22215698SsimonNote: we strongly recommend not to run any milter as root.  Libmilter
23215698Ssimondoes not need root access to communicate with sendmail.  It is a
24215698Ssimongood security practice to run a program only with root privileges
25110010Smarkmif really necessary.  A milter should probably check first whether
26110010Smarkmit runs as root and refuse to start in that case.  libmilter will
27110010Smarkmnot unlink a socket when running as root.
28110010Smarkm
29110010Smarkm+----------------------+
30110010Smarkm| CONFIGURATION MACROS |
31110010Smarkm+----------------------+
32110010Smarkm
33110010SmarkmLibmilter uses a set of C preprocessor macros to specify platform specific
34110010Smarkmfeatures of the C compiler and standard C libraries.
35110010Smarkm
36110010SmarkmSM_CONF_POLL
37110010Smarkm	Set to 1 if poll(2) should be used instead of select(2).
38110010Smarkm
39110010Smarkm+-------------------+
40110010Smarkm| BUILDING A FILTER |
41276864Sjkim+-------------------+
42276864Sjkim
43110010SmarkmThe following command presumes that the sample code from the end of this
44110010SmarkmREADME is saved to a file named 'sample.c' and built in the local platform-
45215698Ssimonspecific build subdirectory (SRCDIR/obj.*/libmilter).
46215698Ssimon
47215698Ssimon	cc -I../../include -o sample sample.c libmilter.a ../libsm/libsm.a -pthread
48215698Ssimon
49142429SnectarIt is recommended that you build your filters in a location outside of
50215698Ssimonthe sendmail source tree.  Modify the compiler include references (-I)
51142429Snectarand the library locations accordingly.  Also, some operating systems may
52142429Snectarrequire additional libraries.  For example, SunOS 5.X requires '-lresolv
53276864Sjkim-lsocket -lnsl'.  Depending on your operating system you may need a library
54276864Sjkiminstead of the option -pthread, e.g., -lpthread.
55276864Sjkim
56110010SmarkmFilters must be thread-safe!  Many operating systems now provide support for
57276864SjkimPOSIX threads in the standard C libraries.  The compiler flag to link with
58276864Sjkimthreading support differs according to the compiler and linker used.  Check
59276864Sjkimthe Makefile in your appropriate obj.*/libmilter build subdirectory if you
60276864Sjkimare unsure of the local flag used.
61276864Sjkim
62276864SjkimNote that since filters use threads, it may be necessary to alter per
63215698Ssimonprocess limits in your filter.  For example, you might look at using
64276864Sjkimsetrlimit() to increase the number of open file descriptors if your filter
65276864Sjkimis going to be busy.
66276864Sjkim
67276864Sjkim
68276864Sjkim+----------------------------------------+
69215698Ssimon| SPECIFYING FILTERS IN SENDMAIL CONFIGS |
70276864Sjkim+----------------------------------------+
71110010Smarkm
72110010SmarkmFilters are specified with a key letter ``X'' (for ``eXternal'').
73110010Smarkm
74110010SmarkmFor example:
75110010Smarkm
76110010Smarkm	Xfilter1, S=local:/var/run/f1.sock, F=R
77110010Smarkm	Xfilter2, S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m
78110010Smarkm	Xfilter3, S=inet:3333@localhost
79110010Smarkm
80110010Smarkmspecifies three filters.  Filters can be specified in your .mc file using
81110010Smarkmthe following:
82110010Smarkm
83110010Smarkm	INPUT_MAIL_FILTER(`filter1', `S=local:/var/run/f1.sock, F=R')
84110010Smarkm	INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m')
85110010Smarkm	INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost')
86110010Smarkm
87110010SmarkmThe first attaches to a Unix-domain socket in the /var/run directory; the
88110010Smarkmsecond uses an IPv6 socket on port 999 of localhost, and the third uses an
89110010SmarkmIPv4 socket on port 3333 of localhost.  The current flags (F=) are:
90110010Smarkm
91110010Smarkm	R		Reject connection if filter unavailable
92110010Smarkm	T		Temporary fail connection if filter unavailable
93110010Smarkm	4		Shut down connection if filter unavailable
94110010Smarkm			(with a 421 temporary error).
95110010Smarkm
96110010SmarkmIf none of these is specified, the message is passed through sendmail
97110010Smarkmin case of filter errors as if the failing filters were not present.
98110010Smarkm
99110010SmarkmFinally, you can override the default timeouts used by sendmail when
100110010Smarkmtalking to the filters using the T= equate.  There are four fields inside
101110010Smarkmof the T= equate:
102110010Smarkm
103110010SmarkmLetter		Meaning
104110010Smarkm  C		Timeout for connecting to a filter (if 0, use system timeout)
105110010Smarkm  S		Timeout for sending information from the MTA to a filter
106110010Smarkm  R		Timeout for reading reply from the filter
107110010Smarkm  E		Overall timeout between sending end-of-message to filter
108110010Smarkm		and waiting for the final acknowledgment
109110010Smarkm
110110010SmarkmNote the separator between each is a ';' as a ',' already separates equates
111110010Smarkmand therefore can't separate timeouts.  The default values (if not set in
112110010Smarkmthe config) are:
113110010Smarkm
114110010SmarkmT=C:5m;S:10s;R:10s;E:5m
115110010Smarkm
116110010Smarkmwhere 's' is seconds and 'm' is minutes.
117110010Smarkm
118110010SmarkmWhich filters are invoked and their sequencing is handled by the 
119110010SmarkmInputMailFilters option. Note: if InputMailFilters is not defined no filters
120110010Smarkmwill be used.
121110010Smarkm
122110010Smarkm	O InputMailFilters=filter1, filter2, filter3
123110010Smarkm
124110010SmarkmThis is is set automatically according to the order of the
125110010SmarkmINPUT_MAIL_FILTER commands in your .mc file.  Alternatively, you can
126110010Smarkmreset its value by setting confINPUT_MAIL_FILTERS in your .mc file.
127110010SmarkmThis options causes the three filters to be called in the same order
128110010Smarkmthey were specified.  It allows for possible future filtering on output
129110010Smarkm(although this is not intended for this release).
130110010Smarkm
131110010SmarkmAlso note that a filter can be defined without adding it to the input
132110010Smarkmfilter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your
133142429Snectar.mc file.
134110010Smarkm
135110655SnectarTo test sendmail with the sample filter, the following might be added (in
136285330Sjkimthe appropriate locations) to your .mc file:
137215698Ssimon
138215698Ssimon	INPUT_MAIL_FILTER(`sample', `S=local:/var/run/f1.sock')
139215698Ssimon
140215698Ssimon
141110010Smarkm+------------------+
142142429Snectar| TESTING A FILTER |
143110010Smarkm+------------------+
144110010Smarkm
145110010SmarkmOnce you have compiled a filter, modified your .mc file and restarted
146110010Smarkmthe sendmail process, you will want to test that the filter performs as
147110010Smarkmintended.
148110010Smarkm
149110010SmarkmThe sample filter takes one argument -p, which indicates the local port
150110010Smarkmon which to create a listening socket for the filter.  Maintaining
151110010Smarkmconsistency with the suggested options for sendmail.cf, this would be the
152110010SmarkmUNIX domain socket located in /var/run/f1.sock.
153110010Smarkm
154110010Smarkm	% ./sample -p local:/var/run/f1.sock
155110010Smarkm
156110010SmarkmIf the sample filter returns immediately to a command line, there was either
157110010Smarkman error with your command or a problem creating the specified socket.
158110010SmarkmFurther logging can be captured through the syslogd daemon.  Using the
159142429Snectar'netstat -a' command can ensure that your filter process is listening on
160110010Smarkmthe appropriate local socket.
161110010Smarkm
162110010SmarkmEmail messages must be injected via SMTP to be filtered.  There are two
163110010Smarkmsimple means of doing this; either using the 'sendmail -bs' command, or
164142429Snectarby telnetting to port 25 of the machine configured for milter.  Once
165110010Smarkmconnected via one of these options, the session can be continued through
166110010Smarkmthe use of standard SMTP commands.
167110010Smarkm
168110010Smarkm% sendmail -bs
169142429Snectar220 test.sendmail.com ESMTP Sendmail 8.14.0/8.14.0; Thu, 22 Jun 2006 13:05:23 -0500 (EST)
170110010SmarkmHELO localhost
171110010Smarkm250 test.sendmail.com Hello testy@localhost, pleased to meet you
172110010SmarkmMAIL From:<testy>
173142429Snectar250 2.1.0 <testy>... Sender ok
174110010SmarkmRCPT To:<root>
175110010Smarkm250 2.1.5 <root>... Recipient ok
176110010SmarkmDATA
177142429Snectar354 Enter mail, end with "." on a line by itself
178110010SmarkmFrom: testy@test.sendmail.com
179110010SmarkmTo: root@test.sendmail.com
180110010SmarkmSubject: testing sample filter
181110010Smarkm
182110010SmarkmSample body
183142429Snectar.
184110010Smarkm250 2.0.0 dB73Zxi25236 Message accepted for delivery
185110010SmarkmQUIT
186110010Smarkm221 2.0.0 test.sendmail.com closing connection
187110010Smarkm
188110010SmarkmIn the above example, the lines beginning with numbers are output by the
189110010Smarkmmail server, and those without are your input.  If everything is working
190110010Smarkmproperly, you will find a file in /tmp by the name of msg.XXXXXXXX (where
191110010Smarkmthe Xs represent any combination of letters and numbers).  This file should
192215698Ssimoncontain the message body and headers from the test email entered above.
193110010Smarkm
194142429SnectarIf the sample filter did not log your test email, there are a number of
195110010Smarkmmethods to narrow down the source of the problem.  Check your system
196110010Smarkmlogs written by syslogd and see if there are any pertinent lines.  You
197110010Smarkmmay need to reconfigure syslogd to capture all relevant data.  Additionally,
198110010Smarkmthe logging level of sendmail can be raised with the LogLevel option.
199215698SsimonSee the sendmail(8) manual page for more information.
200215698Ssimon
201110010Smarkm
202110010Smarkm+--------------+
203110010Smarkm| REQUIREMENTS |
204110010Smarkm+--------------+
205276864Sjkim
206110010Smarkmlibmilter requires pthread support in the operating system.  Moreover, it
207110010Smarkmrequires that the library functions it uses are thread safe; which is true
208110010Smarkmfor the operating systems libmilter has been developed and tested on.  On
209142429Snectarsome operating systems this requires special compile time options (e.g.,
210110010Smarkmnot just -pthread).  libmilter is currently known to work on (modulo problems
211110010Smarkmin the pthread support of some specific versions):
212110010Smarkm
213110010SmarkmFreeBSD 3.x, 4.x
214110010SmarkmSunOS 5.x (x >= 5)
215142429SnectarAIX 4.3.x
216HP UX 11.x
217Linux (recent versions/distributions)
218
219libmilter is currently not supported on:
220
221IRIX 6.x
222Ultrix
223
224Feedback about problems (and possible fixes) is welcome.
225
226+--------------------------+
227| SOURCE FOR SAMPLE FILTER |
228+--------------------------+
229
230Note that the filter example.c may not be thread safe on some operating
231systems.  You should check your system man pages for the functions used
232below to verify the functions are thread safe.
233
234$Revision: 8.42 $, Last updated $Date: 2006-06-29 17:10:16 $
235