Wietse Venema:
> Kouhei Sutou:
> > Hi,
> >
> > Postfix 2.7.0 supports milter protocol 2, 3, 4 and
> > 6. Postfix with milter_protocol=6 accepts a connection from
> > a milter that uses milter protocol 2. But its milter session
> > is broken because Postfix sends SMFIC_DATA event to the
> > milter. In milter protocol 2, SMFIC_DATA isn't supported. So
>
> As documented, the Postfix Milter protocol version must match the
> application Milter protocol version.
>
> You can patch glitches as you discover them, but that is not the
> same as making sure that different versions will always inter-operate.
I have looked into this further, and it appears that at least recent
libmilter versions allow this.
This is, however, a change from documented Postfix behavior, so it
needs some further testing. I have added some extra sanity checks,
for example, the code won't break for future protocol versions > 9,
it warns when it can't figure out what protocol elements to turn
off, and it only executes when the remote application uses a lower
protocol version than Postfix.
Wietse
*** /var/tmp/postfix-2.8-20100306/src/milter/milter8.c Fri Sep 18 16:38:11 2009
--- ./milter8.c Sat Mar 20 21:03:12 2010
***************
*** 1776,1781 ****
--- 1776,1810 ----
milter->m.flags |= MILTER_FLAG_WANT_RCPT_REJ;
/*
+ * Allow the remote application to run an older protocol version, but
+ * don't send events that aren't defined for their protocol version.
+ * Based on a suggestion by Kouhei Sutou.
+ */
+ if (milter->version < my_version) {
+ int version;
+ const NAME_CODE *np;
+
+ for (np = milter8_event_masks; /* see below */ ; np++) {
+ if (np->name == 0) {
+ msg_warn("milter %s: unexpected protocol version %d",
+ milter->m.name, milter->version);
+ break;
+ }
+ if ((version = atoi(np->name)) > 0 && version == milter->version) {
+ milter->np_mask |= (SMFIP_NOSEND_MASK & ~np->code);
+ if (msg_verbose)
+ msg_info("%s: non-protocol events for milter %s"
+ " protocol version %d: %s",
+ myname, milter->m.name, milter->version,
+ str_name_mask_opt(milter->buf,
+ "non-protocol event mask",
+ smfip_table, milter->np_mask, NAME_MASK_NUMBER));
+ break;
+ }
+ }
+ }
+
+ /*
* Initial negotiations completed.
*/
if (msg_verbose) {