1This directory contains the source files for libmilter. 2 3The sendmail Mail Filter API (Milter) is designed to allow third-party 4programs access to mail messages as they are being processed in order to 5filter meta-information and content. 6 7This README file describes the steps needed to compile and run a filter, 8through reference to a sample filter which is attached at the end of this 9file. It is necessary to first build libmilter.a, which can be done by 10issuing the './Build' command in SRCDIR/libmilter . 11 12Starting with 8.13 sendmail is compiled by default with support for 13the milter API. 14 15Note: if you want to write a milter in Java, then see 16http://sendmail-jilter.sourceforge.net/ 17 18+----------------+ 19| SECURITY HINTS | 20+----------------+ 21 22Note: we strongly recommend not to run any milter as root. Libmilter 23does not need root access to communicate with sendmail. It is a 24good security practice to run a program only with root privileges 25if really necessary. A milter should probably check first whether 26it runs as root and refuse to start in that case. libmilter will 27not unlink a socket when running as root. 28 29+----------------------+ 30| CONFIGURATION MACROS | 31+----------------------+ 32 33Libmilter uses a set of C preprocessor macros to specify platform specific 34features of the C compiler and standard C libraries. 35 36SM_CONF_POLL 37 Set to 1 if poll(2) should be used instead of select(2). 38 39+-------------------+ 40| BUILDING A FILTER | 41+-------------------+ 42 43The following command presumes that the sample code from the end of this 44README is saved to a file named 'sample.c' and built in the local platform- 45specific build subdirectory (SRCDIR/obj.*/libmilter). 46 47 cc -I../../include -o sample sample.c libmilter.a ../libsm/libsm.a -pthread 48 49It is recommended that you build your filters in a location outside of 50the sendmail source tree. Modify the compiler include references (-I) 51and the library locations accordingly. Also, some operating systems may 52require additional libraries. For example, SunOS 5.X requires '-lresolv 53-lsocket -lnsl'. Depending on your operating system you may need a library 54instead of the option -pthread, e.g., -lpthread. 55 56Filters must be thread-safe! Many operating systems now provide support for 57POSIX threads in the standard C libraries. The compiler flag to link with 58threading support differs according to the compiler and linker used. Check 59the Makefile in your appropriate obj.*/libmilter build subdirectory if you 60are unsure of the local flag used. 61 62Note that since filters use threads, it may be necessary to alter per 63process limits in your filter. For example, you might look at using 64setrlimit() to increase the number of open file descriptors if your filter 65is going to be busy. 66 67 68+----------------------------------------+ 69| SPECIFYING FILTERS IN SENDMAIL CONFIGS | 70+----------------------------------------+ 71 72Filters are specified with a key letter ``X'' (for ``eXternal''). 73 74For example: 75 76 Xfilter1, S=local:/var/run/f1.sock, F=R 77 Xfilter2, S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m 78 Xfilter3, S=inet:3333@localhost 79 80specifies three filters. Filters can be specified in your .mc file using 81the following: 82 83 INPUT_MAIL_FILTER(`filter1', `S=local:/var/run/f1.sock, F=R') 84 INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m') 85 INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost') 86 87The first attaches to a Unix-domain socket in the /var/run directory; the 88second uses an IPv6 socket on port 999 of localhost, and the third uses an 89IPv4 socket on port 3333 of localhost. The current flags (F=) are: 90 91 R Reject connection if filter unavailable 92 T Temporary fail connection if filter unavailable 93 4 Shut down connection if filter unavailable 94 (with a 421 temporary error). 95 96If none of these is specified, the message is passed through sendmail 97in case of filter errors as if the failing filters were not present. 98 99Finally, you can override the default timeouts used by sendmail when 100talking to the filters using the T= equate. There are four fields inside 101of the T= equate: 102 103Letter Meaning 104 C Timeout for connecting to a filter (if 0, use system timeout) 105 S Timeout for sending information from the MTA to a filter 106 R Timeout for reading reply from the filter 107 E Overall timeout between sending end-of-message to filter 108 and waiting for the final acknowledgment 109 110Note the separator between each is a ';' as a ',' already separates equates 111and therefore can't separate timeouts. The default values (if not set in 112the config) are: 113 114T=C:5m;S:10s;R:10s;E:5m 115 116where 's' is seconds and 'm' is minutes. 117 118Which filters are invoked and their sequencing is handled by the 119InputMailFilters option. Note: if InputMailFilters is not defined no filters 120will be used. 121 122 O InputMailFilters=filter1, filter2, filter3 123 124This is is set automatically according to the order of the 125INPUT_MAIL_FILTER commands in your .mc file. Alternatively, you can 126reset its value by setting confINPUT_MAIL_FILTERS in your .mc file. 127This options causes the three filters to be called in the same order 128they were specified. It allows for possible future filtering on output 129(although this is not intended for this release). 130 131Also note that a filter can be defined without adding it to the input 132filter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your 133.mc file. 134 135To test sendmail with the sample filter, the following might be added (in 136the appropriate locations) to your .mc file: 137 138 INPUT_MAIL_FILTER(`sample', `S=local:/var/run/f1.sock') 139 140 141+------------------+ 142| TESTING A FILTER | 143+------------------+ 144 145Once you have compiled a filter, modified your .mc file and restarted 146the sendmail process, you will want to test that the filter performs as 147intended. 148 149The sample filter takes one argument -p, which indicates the local port 150on which to create a listening socket for the filter. Maintaining 151consistency with the suggested options for sendmail.cf, this would be the 152UNIX domain socket located in /var/run/f1.sock. 153 154 % ./sample -p local:/var/run/f1.sock 155 156If the sample filter returns immediately to a command line, there was either 157an error with your command or a problem creating the specified socket. 158Further logging can be captured through the syslogd daemon. Using the 159'netstat -a' command can ensure that your filter process is listening on 160the appropriate local socket. 161 162Email messages must be injected via SMTP to be filtered. There are two 163simple means of doing this; either using the 'sendmail -bs' command, or 164by telnetting to port 25 of the machine configured for milter. Once 165connected via one of these options, the session can be continued through 166the use of standard SMTP commands. 167 168% sendmail -bs 169220 test.sendmail.com ESMTP Sendmail 8.14.0/8.14.0; Thu, 22 Jun 2006 13:05:23 -0500 (EST) 170HELO localhost 171250 test.sendmail.com Hello testy@localhost, pleased to meet you 172MAIL From:<testy> 173250 2.1.0 <testy>... Sender ok 174RCPT To:<root> 175250 2.1.5 <root>... Recipient ok 176DATA 177354 Enter mail, end with "." on a line by itself 178From: testy@test.sendmail.com 179To: root@test.sendmail.com 180Subject: testing sample filter 181 182Sample body 183. 184250 2.0.0 dB73Zxi25236 Message accepted for delivery 185QUIT 186221 2.0.0 test.sendmail.com closing connection 187 188In the above example, the lines beginning with numbers are output by the 189mail server, and those without are your input. If everything is working 190properly, you will find a file in /tmp by the name of msg.XXXXXXXX (where 191the Xs represent any combination of letters and numbers). This file should 192contain the message body and headers from the test email entered above. 193 194If the sample filter did not log your test email, there are a number of 195methods to narrow down the source of the problem. Check your system 196logs written by syslogd and see if there are any pertinent lines. You 197may need to reconfigure syslogd to capture all relevant data. Additionally, 198the logging level of sendmail can be raised with the LogLevel option. 199See the sendmail(8) manual page for more information. 200 201 202+--------------+ 203| REQUIREMENTS | 204+--------------+ 205 206libmilter requires pthread support in the operating system. Moreover, it 207requires that the library functions it uses are thread safe; which is true 208for the operating systems libmilter has been developed and tested on. On 209some operating systems this requires special compile time options (e.g., 210not just -pthread). libmilter is currently known to work on (modulo problems 211in the pthread support of some specific versions): 212 213FreeBSD 3.x, 4.x 214SunOS 5.x (x >= 5) 215AIX 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