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) {