10Sstevel@tonic-gate# 2*3544Sjbeck# Copyright 2006 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate# Use is subject to license terms. 40Sstevel@tonic-gate# 50Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 60Sstevel@tonic-gate# 70Sstevel@tonic-gate 80Sstevel@tonic-gateThe sendmail Mail Filter API (Milter) is designed to allow third-party 90Sstevel@tonic-gateprograms access to mail messages as they are being processed in order to 100Sstevel@tonic-gatefilter meta-information and content. 110Sstevel@tonic-gate 120Sstevel@tonic-gateThis README file describes the steps needed to compile and run a filter, 130Sstevel@tonic-gatethrough reference to a sample filter which is attached at the end of this 140Sstevel@tonic-gatefile. 150Sstevel@tonic-gate 16616SjbeckNote: if you want to write a milter in Java, then see 17616Sjbeckhttp://sendmail-jilter.sourceforge.net/ 18616Sjbeck 190Sstevel@tonic-gate+----------------+ 200Sstevel@tonic-gate| SECURITY HINTS | 210Sstevel@tonic-gate+----------------+ 220Sstevel@tonic-gate 230Sstevel@tonic-gateNote: we strongly recommend not to run any milter as root. Libmilter 240Sstevel@tonic-gatedoes not need root access to communicate with sendmail. It is a 250Sstevel@tonic-gategood security practice to run a program only with root privileges 260Sstevel@tonic-gateif really necessary. A milter should probably check first whether 270Sstevel@tonic-gateit runs as root and refuse to start in that case. libmilter will 280Sstevel@tonic-gatenot unlink a socket when running as root. 290Sstevel@tonic-gate 300Sstevel@tonic-gate+-------------------+ 310Sstevel@tonic-gate| BUILDING A FILTER | 320Sstevel@tonic-gate+-------------------+ 330Sstevel@tonic-gate 340Sstevel@tonic-gateThe following command presumes that the sample code from the end of this 350Sstevel@tonic-gateREADME is saved to a file named 'sample.c'. 360Sstevel@tonic-gate 370Sstevel@tonic-gate cc -D_REENTRANT -o sample sample.c -lmilter 380Sstevel@tonic-gate 390Sstevel@tonic-gateFilters must be thread-safe! 400Sstevel@tonic-gate 410Sstevel@tonic-gateNote that since filters use threads, it may be necessary to alter per 420Sstevel@tonic-gateprocess limits in your filter. For example, you might look at using 430Sstevel@tonic-gatesetrlimit() to increase the number of open file descriptors if your filter 440Sstevel@tonic-gateis going to be busy. 450Sstevel@tonic-gate 460Sstevel@tonic-gate 470Sstevel@tonic-gate+----------------------------------------+ 480Sstevel@tonic-gate| SPECIFYING FILTERS IN SENDMAIL CONFIGS | 490Sstevel@tonic-gate+----------------------------------------+ 500Sstevel@tonic-gate 510Sstevel@tonic-gateFilters are specified with a key letter ``X'' (for ``eXternal''). 520Sstevel@tonic-gate 530Sstevel@tonic-gateFor example: 540Sstevel@tonic-gate 550Sstevel@tonic-gate Xfilter1, S=local:/var/run/f1.sock, F=R 560Sstevel@tonic-gate Xfilter2, S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m 570Sstevel@tonic-gate Xfilter3, S=inet:3333@localhost 580Sstevel@tonic-gate 590Sstevel@tonic-gatespecifies three filters. Filters can be specified in your .mc file using 600Sstevel@tonic-gatethe following: 610Sstevel@tonic-gate 620Sstevel@tonic-gate INPUT_MAIL_FILTER(`filter1', `S=local:/var/run/f1.sock, F=R') 630Sstevel@tonic-gate INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m') 640Sstevel@tonic-gate INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost') 650Sstevel@tonic-gate 660Sstevel@tonic-gateThe first attaches to a Unix-domain socket in the /var/run directory; the 670Sstevel@tonic-gatesecond uses an IPv6 socket on port 999 of localhost, and the third uses an 680Sstevel@tonic-gateIPv4 socket on port 3333 of localhost. The current flags (F=) are: 690Sstevel@tonic-gate 700Sstevel@tonic-gate R Reject connection if filter unavailable 710Sstevel@tonic-gate T Temporary fail connection if filter unavailable 72*3544Sjbeck 4 Shut down connection if filter unavailable 73*3544Sjbeck (with a 421 temporary error). 740Sstevel@tonic-gate 75*3544SjbeckIf none of these is specified, the message is passed through sendmail 760Sstevel@tonic-gatein case of filter errors as if the failing filters were not present. 770Sstevel@tonic-gate 780Sstevel@tonic-gateFinally, you can override the default timeouts used by sendmail when 790Sstevel@tonic-gatetalking to the filters using the T= equate. There are four fields inside 800Sstevel@tonic-gateof the T= equate: 810Sstevel@tonic-gate 820Sstevel@tonic-gateLetter Meaning 830Sstevel@tonic-gate C Timeout for connecting to a filter (if 0, use system timeout) 840Sstevel@tonic-gate S Timeout for sending information from the MTA to a filter 850Sstevel@tonic-gate R Timeout for reading reply from the filter 860Sstevel@tonic-gate E Overall timeout between sending end-of-message to filter 870Sstevel@tonic-gate and waiting for the final acknowledgment 880Sstevel@tonic-gate 890Sstevel@tonic-gateNote the separator between each is a ';' as a ',' already separates equates 900Sstevel@tonic-gateand therefore can't separate timeouts. The default values (if not set in 910Sstevel@tonic-gatethe config) are: 920Sstevel@tonic-gate 930Sstevel@tonic-gateT=C:5m;S:10s;R:10s;E:5m 940Sstevel@tonic-gate 950Sstevel@tonic-gatewhere 's' is seconds and 'm' is minutes. 960Sstevel@tonic-gate 970Sstevel@tonic-gateWhich filters are invoked and their sequencing is handled by the 980Sstevel@tonic-gateInputMailFilters option. Note: if InputMailFilters is not defined no filters 990Sstevel@tonic-gatewill be used. 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate O InputMailFilters=filter1, filter2, filter3 1020Sstevel@tonic-gate 1030Sstevel@tonic-gateThis is is set automatically according to the order of the 1040Sstevel@tonic-gateINPUT_MAIL_FILTER commands in your .mc file. Alternatively, you can 1050Sstevel@tonic-gatereset its value by setting confINPUT_MAIL_FILTERS in your .mc file. 1060Sstevel@tonic-gateThis options causes the three filters to be called in the same order 1070Sstevel@tonic-gatethey were specified. It allows for possible future filtering on output 1080Sstevel@tonic-gate(although this is not intended for this release). 1090Sstevel@tonic-gate 1100Sstevel@tonic-gateAlso note that a filter can be defined without adding it to the input 1110Sstevel@tonic-gatefilter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your 1120Sstevel@tonic-gate.mc file. 1130Sstevel@tonic-gate 1140Sstevel@tonic-gateTo test sendmail with the sample filter, the following might be added (in 1150Sstevel@tonic-gatethe appropriate locations) to your .mc file: 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate INPUT_MAIL_FILTER(`sample', `S=local:/var/run/f1.sock') 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate+------------------+ 1210Sstevel@tonic-gate| TESTING A FILTER | 1220Sstevel@tonic-gate+------------------+ 1230Sstevel@tonic-gate 1240Sstevel@tonic-gateOnce you have compiled a filter, modified your .mc file and restarted 1250Sstevel@tonic-gatethe sendmail process, you will want to test that the filter performs as 1260Sstevel@tonic-gateintended. 1270Sstevel@tonic-gate 1280Sstevel@tonic-gateThe sample filter takes one argument -p, which indicates the local port 1290Sstevel@tonic-gateon which to create a listening socket for the filter. Maintaining 1300Sstevel@tonic-gateconsistency with the suggested options for sendmail.cf, this would be the 1310Sstevel@tonic-gateUNIX domain socket located in /var/run/f1.sock. 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate % ./sample -p local:/var/run/f1.sock 1340Sstevel@tonic-gate 1350Sstevel@tonic-gateIf the sample filter returns immediately to a command line, there was either 1360Sstevel@tonic-gatean error with your command or a problem creating the specified socket. 1370Sstevel@tonic-gateFurther logging can be captured through the syslogd daemon. Using the 1380Sstevel@tonic-gate'netstat -a' command can ensure that your filter process is listening on 1390Sstevel@tonic-gatethe appropriate local socket. 1400Sstevel@tonic-gate 1410Sstevel@tonic-gateEmail messages must be injected via SMTP to be filtered. There are two 1420Sstevel@tonic-gatesimple means of doing this; either using the 'sendmail -bs' command, or 1430Sstevel@tonic-gateby telnetting to port 25 of the machine configured for milter. Once 1440Sstevel@tonic-gateconnected via one of these options, the session can be continued through 1450Sstevel@tonic-gatethe use of standard SMTP commands. 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate% sendmail -bs 148*3544Sjbeck220 test.sendmail.com ESMTP Sendmail 8.14.0/8.14.0; Thu, 22 Jun 2006 13:05:23 -0500 (EST) 1490Sstevel@tonic-gateHELO localhost 1500Sstevel@tonic-gate250 test.sendmail.com Hello testy@localhost, pleased to meet you 1510Sstevel@tonic-gateMAIL From:<testy> 1520Sstevel@tonic-gate250 2.1.0 <testy>... Sender ok 1530Sstevel@tonic-gateRCPT To:<root> 1540Sstevel@tonic-gate250 2.1.5 <root>... Recipient ok 1550Sstevel@tonic-gateDATA 1560Sstevel@tonic-gate354 Enter mail, end with "." on a line by itself 1570Sstevel@tonic-gateFrom: testy@test.sendmail.com 1580Sstevel@tonic-gateTo: root@test.sendmail.com 1590Sstevel@tonic-gateSubject: testing sample filter 1600Sstevel@tonic-gate 1610Sstevel@tonic-gateSample body 1620Sstevel@tonic-gate. 1630Sstevel@tonic-gate250 2.0.0 dB73Zxi25236 Message accepted for delivery 1640Sstevel@tonic-gateQUIT 1650Sstevel@tonic-gate221 2.0.0 test.sendmail.com closing connection 1660Sstevel@tonic-gate 1670Sstevel@tonic-gateIn the above example, the lines beginning with numbers are output by the 1680Sstevel@tonic-gatemail server, and those without are your input. If everything is working 1690Sstevel@tonic-gateproperly, you will find a file in /tmp by the name of msg.XXXXXXXX (where 1700Sstevel@tonic-gatethe Xs represent any combination of letters and numbers). This file should 1710Sstevel@tonic-gatecontain the message body and headers from the test email entered above. 1720Sstevel@tonic-gate 1730Sstevel@tonic-gateIf the sample filter did not log your test email, there are a number of 1740Sstevel@tonic-gatemethods to narrow down the source of the problem. Check your system 1750Sstevel@tonic-gatelogs written by syslogd and see if there are any pertinent lines. You 1760Sstevel@tonic-gatemay need to reconfigure syslogd to capture all relevant data. Additionally, 1770Sstevel@tonic-gatethe logging level of sendmail can be raised with the LogLevel option. 1780Sstevel@tonic-gateSee the sendmail(8) manual page for more information. 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate 181*3544Sjbeck$Revision: 8.42 $, Last updated $Date: 2006/06/29 17:10:16 $ 182