CHANGES ------- The major number changes for such things as code rewrites, changes in syntax, and/or dramatic changes in functionality. The minor number changes for corrections, enhancements, etc. made to the code. There is no set schedule for releases. --TODO-- + Add a common intra-milter communication cache used to pass information and results between milters. Milters that work on content can pass info via the headers to downstream milters, but those that work only on the pre-DATA info have no method. + Consider adding option XMilterSenderPass to control addition of an X-Milter-Sender-Pass header. This is more for consistency with all my other milters, though Leon Kos did request something similar. + Similar to the request from Leon Kos, Vincent Aniello would like the ability to tag a message and pass through instead of rejecting. Current milter design to validate and reject before the DATA command is entwined as a design principle throughout the code. To support this request would require many structural changes and/or hack to the code that I'm not willing to address until after the release of 1.0. + Back port milter-gris -I option to here. + Back port milter-gris use of fitlerData() for grey-list temp. fail point. + Consider permanently enabling the behaviour of DeferHeloReject and DeferMailReject and removing these options. + Rieder Dietmar wrote: > Hi Anthony, > > I have a question regarding milter-sender and the > sender address: > As I have seen from the source code the milter is rejecting any message > from a sender at the SMTP DATA stage. I think I also > got the reason for this behavior. My question now is, could we not just > switch to greylisting instead of completely rejecting here? ? Requested by Thomas Börnert. A "policy" option that a) perform the call-back, b) based on policy either reject or simply add a header for down stream filtering, configurable per recipient domain/user. --1.17-- ! sample.mc.in: Removed from define(`_FFR_MILTER', `1')dnl --1.16-- + The call-ahead-db option now supports sendmail mailertable formatted database. This allows the call-ahead-db to be replaced by a mailertable directly without modification if desired. The actual mailer portion of the right-hand-side is ignored, except for error: and local:, which have special meaning in sendmail. This facility will also work for postfix's transport file, which has a similar format. Requested by Alex Broens for milter-ahead and back-ported. ! mxCallAhead(): changed handling of rcpt_host / call-ahead-db entries to NOT parse off the square brackets. The socket2 API's socketAddressCreate() has for at least a year supported IPv4 and IPv6 address domain literals in order to support RFC 2732 in addition hostnames within square brackets. The previous stripping of square brackets could sometime lead to a port specifier (from a call-ahead-db entry being lost). Reported by antennex.com. The following formats should all work Historical ---------- hostname hostname:8025 192.0.2.1 192.0.2.1:8025 2001:0DB8::1234 Common IP-domain-literals ------------------------- [192.0.2.1] [2001:0DB8::1234] [hostname] supported for consistency, Square brackets have meaning in sendmail to disable MX lookups in mailertable (and possibly rulesets). RFC 2732 -------- [2001:0DB8::1234]:8025 [192.0.2.1]:8025 supported for consistency [hostname]:8025 supported for consistency Unusal variants --------------- [hostname:8025] [192.0.2.1:8025] [2001:0DB8::1234,8025] any punctuation but colon before port 2001:0DB8::1234,8025 any punctuation but colon before port Currently colon delimiter immediately before a port specifier can be any punctuation character, though colon is recommended for historical reasons. Most of the unusal variants are supported for consistency and simply an artifact of the code in socketAddressCreate(). In the case of the bare IPv6 address without square brackets, the use of colon to separate the port is ambiguous, so any other punctuation other the colon must be used. Generally the unusal variants should no longer be used in light of RFC 2732. --1.15-- ! Corrections of compiler warning for gcc version 4.1.0 20060304 and 64-bit CPU, which is rather pedantic about char * vs unsigned char * issues. --1.14-- + Recommend LibSnert 1.64 !! In some instances when a server refuses the call-back connection a mysterious NULL error message was being passed to setReply(), which would result in a segmetation fault. Added missing commas separating error strings; without the commas, the two messages merged into one causing the array of pointers to be one shorter than expected, so that indexing the last message fell off the end. Reported by Andrew Druda. ! Mxcallbackipblocked: fixed mxipblocked() when publicip is set to an empty string would result in true being returned and the wrong connection related error reported. --1.13-- + Requires LibSnert 1.63 ! If PrimaryMxAliveReject triggers, then do NOT cache any result. milter-sender behaved incorrectly compared to milter- ahead version. Reported by Dave Hines. ! atExitCleanUp(): added NULL guard around cache cleanup code in case its the cache was not initialised. !! mxCallback() now returns a 450 response instead of the original 550 response when there is no answer after trying mutiple MX records for a domain. Requested by Volker Stolz, Bobby Rose, and Ugo Bellavance. ! Hardcode exclusion for LAN and localhost from +primary-up-reject. Reported by Dave Hines. + access-db and MxCallAheadDb now support socket-map, flat- file, and SQLite3 lookups in addition to Berkeley DB. The SQLite3 behaviour can be disabled via LibSnert's ./configure script. --1.12-- + Requires LibSnert 1.62 + Added support to bind outbound SMTP client connection to a particular interface address. Requested by Thomas Bornert. ! Removed smdbOptTable from options, since these have been moved into the common set specified in smf.c. !! License 1.4 which provides additional details with regards to possible license controls used, the possibility of "phone home code" and its general contents, and related privacy statement. + Add check for filterOpen() got NULL socket address pointer passed to filterOpen() which inidicates an unsupported address type. The connection is simply accepted to bypass the milter. --1.11-- + Requires LibSnert 1.61 !! Replace old option parsing with newer libsnert option API, which standardises option handling and many common options across all Snert milters. As a result some options have been renamed or dropped: -d -> -help or +help -f -> file= -x -> -quit or +quit -X -> -daemon -Z -> many options MailLogDetail -> verbose= MilterSocket -> milter-socket= MilterSocketTimeout -> milter-timeout= SendmailCf -> access-db= SpecialFlags -> many options As a result of this change many new options come into play that were previously undocumented or compile-only options. ! mxCallAhead(): There can occur an instance in Sendmail where a RCPT TO: is known and rcpt_addr, rcpt_host, and rcpt_mailer are all NULL, which might cause a segmentation fault due to a careless redefinition of confMILTER_MACROS_ENVRCPT in sendmail.mc. ! mxHelo() incorrectly generates "appears to be blocking our IP" error instead of a broken connection error. While the former might be actually true and the cause of the broken connection, the response buffer should actually be empty in light of the broken connection. --1.10-- ! mxCallBack(): if MX_ERROR_BROKEN is returned by mxConnect(), then the next MX in the list should be tried. Reported by Kevin Brooks. ! mxWelcome(), mxConnect(): A timeout or unexpected EOF is no longer treated the same as a bad welcome message (eg. a welcome message that responds with something other than 220, 421, or 554). This results in the next MX being tried instead of just giving an immediate error. Reported by Kevin Brooks. ! mxCommand(): cleaned up error handling. ! Changed default value of MilterSocketTimeout to correspond with libmilter's default (7210s). This should silence many of the reported sendmail to milter timeout errors and/or broken connections caused by the milter timing out sooner than sendmail does with the client. The sendmail defaults for each SMTP command and receiving the message content is 1h each and so libmilter allows for 2h 10s. But in theory you could be DoS for between 5 and 104 hours per connection. If you want to change this then set in sendmail.mc: define(`confTO_DATABLOCK', `30m') define(`confTO_COMMAND', `5m') ! Changed the implied status code for MX_ERROR_CONNECT from 554 to 421. Requested by Volker Stolz. This changes the assumption that failure to answer could happen for legit reasons. - GreyListRejectCount has been removed completely. It was disabled in 1.4. --1.9-- ! filterRcpt(): Must check return code from smfAcceesRcpt() is not SMDB_ACCESS_ERROR before trying to check for a postmaster address. A SMDB_ACCESS_ERROR indicates a parse error and that the contents of data->work.rcpt will be undefined. Reported by Andrew Lyon. ! Added experimental code to implment milter specific SMTP commands using the libmilter xxfi_unknown handler. This requires BOTH sendmail and libmilter be built with APPENDDEF(`confENVDEF', `-DSMFI_VERSION=4') specified in your devtools/Site/site.config.m4 file. This would allow for an administrator to get and/or remove individual cache entries without having to stop the milter. Command processing is restricted only to hosts that have either: milter-sender-command:ip OK milter-sender-command:hostname OK defined in the access.db. Also if you use FEATURE(`great_pause') you will require either: GreatPause:ip 0 GreatPause:hostname 0 For example you should have this at a minimum: milter-sender-command:127.0.0.1 OK GreetPause:127.0.0.1 0 The extra SMTP commands are: milter-sender cache-get $KEY milter-sender cache-remove $KEY Where $KEY is the cache key to get or remove. Due to design limitations in the libmilter API, a successful command is returned as 500 5.0.0 and unsuccessful command will be 500 5.y.z and a textual response. See contrib/milter-cmd.sh for an example shell script using nc(1) to provide a simple command line interface. --1.8-- !! Fixed bus error/seg.fault caused by the MxCallBackAsPostmaster which added an extra error message taking the server's response as an argument string to include. During the call-back sequence if the 2nd MAIL FROM: failed, MX_ERROR_MAIL is returned and the preparation if the response message would crash the milter, because the server's response was missing from the printf() list. ! isLocalHost(): added NULL pointer check before comparing host IP address with that of the interface if_addr. ! mxListPrune(): added NULL pointer check of MX IP address before logging details. Suspect some implementations of syslog() / printf() do not handle NULL pointers gracefully (Solaris 9). ! Some MX servers for domains like sappi.com who use a 3rd party filtering service, mxlogic.net, break the connection after the 2nd MAIL FROM: command is sent. If the first test for the false address indicates a blind-MX, then skip the reconnect attempt and second test and go straight to grey-listing. Reported by Didi Rieder. --1.7-- + Requires LibSnert 1.57 + Added support for milter-length-auth:auth_authen RHS milter-length-auth: RHS ! Consider milter-sender vs a grey-listing server. A 4xx error for the RCPT TO: might be returned, in which case we fall back on grey listing. !! Fixed bug in MX list pruning code that could cause the milter to crash. ! Improved performance by removing repeated calls to formatIP() for results returned by the Dns code. Now the Dns code provides all the needed information. + Added MxCallAheadNotRcptHost option to disable {rcpt_host} call-ahead if there is no entry in the MxCallAheadDb table. Requested by Geoff Steer. ! Switched over to using socket2 API, brings IPv6 support. + mxConnect(): disable Nagle and lingering for the call-back. ! cacheGarbageCollect() simplified to use the milter connection ID for the GC frequency counter. This removes the need for a separate variable and only applies the mutex lock when an actual GC should be done. ! mxIsRejected(): renamed to mxListPrune; removed MX white listing that would short circuit the rest of the MX list pruning. A suspect domain might try to add a white listed MX they don't own to their MX list just to by-pass the milter. + Added option MxCallAheadImplicitMx to try the implicit MX of {rcpt_host} when no other MX answers. Used in special cases where for example departmental subdomain MXes point to gateway MX and rely on the implicit MX rule with an A record to route the mail internally. Requested by Panagiotis Christias. ! mxListPrune(): Changed code that finds this host's MX preference to match against the interface's {if_addr} instead of {if_name}, just in case interface name is different from the MX host name. ! Have disabled the pruning of blacklisted MX hosts just prior to the call-back and call-ahead. Its my feeling that this "feature" is redundant, overkill, not utilised, and just a waste of CPU. To enable use the compile time flag -DENABLE_PRUNE_BLACKLIST_MX. This code will eventually be removed unless strong arguments to keep it are made. + Experimental option MxCallBackAsPostmaster which uses an alternative address in place of the DSN address. This is to address the increasing number of RFC clueless sites that choose to block the DSN address. This option requires the following two changes: + MAIL FROM: always accepted now and no call-back made to validate it. However, a message from a postmaster address will be blocked at the DATA command if sendmail and libmilter extensions have been enabled. This prevents abuse by spammers. - AlwaysAcceptPostmaster option removed in favour of always accepting RCPT TO: --1.6-- + Requires LibSnert 1.56 ! SpecialFlags option now support optional +/- prefixes for special option flags. ! Added documentation for new NEXT action used in B/W listings. See LibSnert 1.54 change log. ! Changed install.sh.in to create /var/run/milter/ directory owned by milter:milter and change the default PID_FILE and SOCKET_FILE paths. This provides better privilege/security separation since the milters run as milter:milter. --1.5-- + Requires LibSnert 1.53 ! filterRcpt() move white-list by-pass after call-ahead check. The allows MAIL FROM:<> to be checked and filtered. Requested by Mike Kercher. ! filterRcpt() now proper handles per RCPT white listing such that a single white listed recipient does NOT white list the whole message for all other RCPTs. Requested by Sergey Stepanov. --1.4-- + Requires LibSnert 1.50 + Add MxCallAdheadDb option to permit domain / next-hop-host lookups from a Berkeley DB file (use makemap(1) to create it). Requested by Chris Wilson. If no mapping is found, then use the value of {rcpt_host}. In some instances ForceCallAheadHost option and mailertable cannot be used because all mail passes through an intermediate filtering server or appliance that has no knowledge of the recipients when there is more than one internal mail store. Consider: MX gateway -> Anti-Virus appliance -> POP domain1.com -> POP domain2.com -> ... The anti-virus appliance is a closed 3rd party service or system that has no knowledge of the valid recipient email addresses. In such cases you would like to jump over the appliance in order to query the final destination host. The MxCallAdheadDb option provides an alternate mailertable like database, since the sendmail mailertable may be disabled or used to direct mail an intermediate filtering machine. + Added MxCallAheadMx option to enable MX lookups of {rcpt_host} or MxCallAdheadDb entries. Note that MxReject is used to prune the list of valid MXes. ! Renamed ForceCallAheadHost to MxCallAheadHost so as to group related options. + Command-line version of this milter. Suggested by Andrey Chernov. Only does the call-back test itself. ! Fix problem where an MX chooses to break the connection on the next MAIL command after a RSET. The MX for stacey.ca (in1.magma.ca) is an example. Reported by Chris Wilson. ! Touch the timestamp of successful grey-list cache entries that continue to remain active so as to avoid grey-listing a second time. Requested by Arne Handtmann. The original design was to always expire entries, even successful ones, in order to retest on occasion. But this negatively impacts legit senders more that the value of retesting. milter-sender made a similar policy change concerning call-back a while back and so precedent has been set. - GreyListRejectCount has been removed (code #ifdef and to be removed next release). This option has proven to be troublesome and its continued presence would just allow those class of users who turn on all the knobs without understanding to shoot themselves in the foot. ! Cleaned up a lot of the grey listing code so that its all handled from within filterRcpt(). ! A previously inconclusive call-back result that invokes grey listing does not cause redundant call-backs during the grey list block time. --1.3-- + Requires LibSnert 1.46 ! DnsGet() would return a name not found error for an MX lookup if any of the MX in the list did not resolve. Now we return the partial list. Reported by Didi Rieder. + Add new option UpstreamMxList. --1.2-- !! License updated to allow for private individual/single machine license. --1.1-- ! install.sh: fix use of id -u, which doesn't work on SunOS ! install.sh: fix use of bang (!) logical-NOT operator, which is not available in real Bourne shells or csh. ! install.sh: SunOS grep does not have a -q option ! install.sh: fixed "if which command ; then" tests with a function. which(1) always returns success (0) on SunOS. ! install.sh: SunOS has two different install(1) tools with different options (-o vs. -u) to set the file owner. ! Fixed log message "trying MX %d '%s' [%s] for <%s>" to once again report the MX's IP address in square brackets. This was a regression caused by the change in Dns lookup code and return structures. ! manual.shtml.in: Updated the documentation to better reflect the access database lookups, supported tags, and values, see MxCallBackMaxAttempts and SendmailCf. This is a result of using the smfAccessHost(), smfAccessMail(), and smfAccessRcpt() functions from LibSnert and standard behaviour in all Snert milters. --1.0-- * Thank you to Claudio Eichenberger again for several CDs from the wishlist. + Requires LibSnert 1.41 ! Fixed configure.in script to better handle Berkeley DB library and header searches. All these cases should now work. ./configure ./configure --with-db ./configure --with-db=/usr/local/BerkeleyDB-4.2 ./configure --without-db + Added option to disable the %-hack for routed addresses. RcptRejectPercentHack=1 This is roughly equivalent to the following Sendmail rule: SLocal_check_rcpt R$* % $* @ $+ $#error $@ 5.7.1 $: "550 routed address relaying denied" ! Fixed time stamp variables to use the time_t instead of assuming a long. + configure.in: now expects a user and group milter (instead of smmsp/smmsp). The old behaviour can be obtained with: ./configure --enable-run-user=smmsp --enable-run-group=smmsp + filterHelo(), filterMail(): added test for and rejection of reserved RFC 2606 domains. Suggested by Andrey Chernov. ! mxCallAhead(): When the ForceCallAheadHost option is used, ignore the test that generates the "is not a defined route, skipping" message. Reported by Andreas Thienemann. ! filterHelo(): When if_addr was set to a printable undefined string (smfUndefined), then further down the test for the local loop back fails to work properly, because it was still testing for NULL instead of smfUndefined. Reported by Robin Rainton. ! Fixed the start-up script unalias of shell function names before defining the function so as to ignore any errors if the function name is not defined. Also fixed parens around the function arguments, which is not support by many shells. - configure.in: Removed gcc option -fvolatile, which is no longer supported in as of gcc 3.4. ! configure.in: cleaned up handling of compiler options and removed old no longer used macros. ! The need for a state directory has been dropped. The pid file and unix domain socket are now kept in /var/run by default. Similarly, the cache file is now kept in /var/db or /var/cache depending on whether the system is a *BSD or Linux system. Use the ./configure options --enable-pid, --enable-socket, --enable-cache-file to change these filepaths. + The milter now starts as a background process and can kill a previous instance of itself using a command-line option. - MilterCf and Help options has been removed from the .cf file. ! Command-line options have been changed. + Added option to reject a message when the primary MX answers a call-ahead: PrimaryMxAliveReject=0 When the primary MX is reachable and accepting messages, then reject the mail. This does not conform with RFC 974 section "Interpreting the List of MX RRs", paragraph 7, sentence 2 and 3, which only requires mail clients to attempt delivery to the primary first, before trying other MXes. This option essentially demands that a client only deliver to the primary MX when its available. Suggested by Erik Hensema. + Any access.db keys that are found are reported in syslog as part of the info level logging. This reduces the need to enable -v database, which is very volumnous. Useful for finding troublesome B/W entries without having to change settings and restart the milter. + Added option to reject mail on any DNS error instead of temp. failing them as recommended: DnsRejectOnError Some intermediate MX servers blindly accept mail from non- existant domains and then proceed to relay the message. Subsequent DNS lookups by a milter-sender server report a DNS error of some kind and temporary fail the message (see RFC 974). The blind MX host then requeues the message and keeps making attempts to send it, constantly being temp. failed. This can create something resembling a Denial of Service if the blind MX has queued a sufficent number of bogus domain messages and has short rety times. Suggested by Bobby Rose. - MxAcceptsAllAction=7 (send probe) and the FullCallback: tag have been removed. The potential for abuse and the ability to shoot one's self in the foot by using this option make this a bad idea to even bother keeping. + MxAcceptsAllAction renamed to MxAcceptsAll. It now specifies a comma separated list of words the as to what the grey-list key is composed of: ip, helo, mail, rcpt. The special key word "reject" will reject mail when the MX accepts all recipients regardless such as yahoo.com. - ClientReject*, HeloReject*, MxReject* family of options concerning reserved IP addresses have been merged into single options that take a bit-vector. These functions now use isReservedIP(), which now supports IPv6. + Added an option to fall back on grey-listing if the null address <> is rejected by MX. Suggested by Chris Wilson. MxCallBackDsnBlocked This avoids heated debates about RFC conformance. ! Replaced code to do access database lookups with smfAccessHost(), smfAccessMail(), and smfAccessRcpt(). Use smfFlags() to control some tests performed by these routines. - Removed SkipLoopbackInterface. I think this option should always be true and therefore redundant. Also the potential to shoot yourself in the foot by setting it false is just too great. - Removed SkipAuthenticatedSender. Its redundant. If a sender authenticates, then you obviously wanted them to be able to do something special like relay through your machine. If now you don't want them to authenticate, change their password. - Removed WhiteListFutureSender. I think this option is always true and thus is considered redundant. I could not think of a reason why you wouldn't want to auto white list replies. ! RcptRejectPercentHack moved to, SpecialFlags which is used to control libsnert internals. Sendmail by default prevents the %-hack relay, so this test is normally redundant *except* when you have broken custom rule sets. ! Lowered default CacheGcFrequency from 1000 to 250. ! When calling ahead to the next machine, the RCPT address as given should be used and not parsed for sendmail's plus detail support. Reported by Kevin Spicer. This was an issue in milter-ahead and does not appear to be an issue in milter-sender, but is noted here for future reference. !! Updated LICENSE.TXT.