Loading ...
Sorry, an error occurred while loading the content.
 

PATCH version 2: milter question

Expand Messages
  • Wietse Venema
    ... Updated patch follows. When a milter replies with ACCEPT, Postfix marks it as not active for the remainder of an entire session or just for the duration
    Message 1 of 9 , Jul 30, 2007
      Jukka Salmi:
      > I'm running Postfix 2.4.3 and dkim-milter v2.0.0. Postfix is configured
      > to use the milter as both an SMTP milter (to verify or sign incoming
      > messages) and as a non-SMTP milter (to sign locally generated outgoing
      > messages):
      ...
      > The milter in question uses a peer list: messages from hosts listed
      > in that list should be accepted without being processed by the milter.
      > But this seems not to work: after smtpd(8) has been told by the milter
      > to accept a message from a peer, cleanup(8) seems to pass the message
      > to the milter (where it is processed since `localhost' is not a peer).

      Updated patch follows.

      When a milter replies with ACCEPT, Postfix marks it as "not
      active" for the remainder of an entire session or just for the
      duration of a specific MAIL FROM transaction (this depends
      on the context in which the ACCEPT is received).

      As an optimization, Postfix does not send "not active" milter
      instances from the smtpd server to the cleanup server.

      The problem was that when all milters were marked "not active",
      Postfix would not send any milter information to the cleanup server,
      and thus the cleanup server would assume that mail was received as
      a local submission. This means the cleanup server used the wrong
      SMTP client information (localhost/127.0.0.1 instead of the real
      client).

      Fix:

      - Instead of sending no milter information to the cleanup server,
      Postfix now sends place holder milter information from the smtpd
      server to the cleanup server. This prevents the cleanup server
      from inappropriately applying the non_smtpd_milters setting for
      local submissions.

      - Once the DATA stage is reached, Postfix now sends the actual
      milter list from the smtpd server to the cleanup server, so that
      the cleanup server can send header and body events, this time
      while using the correct SMTP client information.

      To apply, cd into the Postfix 2.3 .. 2.5 source directory and feed
      the content of this message into "patch -p0".

      I'll try to release a Postfix 2.4 release candidate before I have
      to travel to CEAS 2007.

      Wietse

      diff --exclude=man --exclude=html --exclude=README_FILES --exclude=.indent.pro --exclude=Makefile.in -cr /var/tmp/postfix-2.5-20070724/src/smtpd/smtpd.c src/smtpd/smtpd.c
      *** /var/tmp/postfix-2.5-20070724/src/smtpd/smtpd.c Tue Jul 24 20:23:31 2007
      --- src/smtpd/smtpd.c Mon Jul 30 20:26:31 2007
      ***************
      *** 1632,1638 ****
      if (SMTPD_STAND_ALONE(state) == 0) {
      if (smtpd_milters != 0
      && (state->saved_flags & MILTER_SKIP_FLAGS) == 0)
      ! (void) milter_send(smtpd_milters, state->dest->stream);
      rec_fprintf(state->cleanup, REC_TYPE_TIME, REC_TYPE_TIME_FORMAT,
      REC_TYPE_TIME_ARG(state->arrival_time));
      if (*var_filter_xport)
      --- 1634,1641 ----
      if (SMTPD_STAND_ALONE(state) == 0) {
      if (smtpd_milters != 0
      && (state->saved_flags & MILTER_SKIP_FLAGS) == 0)
      ! /* Send place-holder smtpd_milters list. */
      ! (void) milter_dummy(smtpd_milters, state->cleanup);
      rec_fprintf(state->cleanup, REC_TYPE_TIME, REC_TYPE_TIME_FORMAT,
      REC_TYPE_TIME_ARG(state->arrival_time));
      if (*var_filter_xport)
      ***************
      *** 2542,2547 ****
      --- 2545,2554 ----
      */
      if (state->cleanup) {
      if (SMTPD_STAND_ALONE(state) == 0) {
      + if (smtpd_milters != 0
      + && (state->saved_flags & MILTER_SKIP_FLAGS) == 0)
      + /* Send actual smtpd_milters list. */
      + (void) milter_send(smtpd_milters, state->cleanup);
      if (state->saved_flags)
      rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d",
      state->saved_flags);
      diff -cr /var/tmp/postfix-2.5-20070724/src/cleanup/cleanup_envelope.c src/cleanup/cleanup_envelope.c
      *** /var/tmp/postfix-2.5-20070724/src/cleanup/cleanup_envelope.c Tue Jan 16 14:08:07 2007
      --- src/cleanup/cleanup_envelope.c Mon Jul 30 20:41:04 2007
      ***************
      *** 148,160 ****
      #endif
      if (type == REC_TYPE_MILT_COUNT) {
      /* Not part of queue file format. */
      ! if (state->milters != 0) {
      ! msg_warn("%s: message rejected: too many milter instances",
      ! state->queue_id);
      ! state->errs |= CLEANUP_STAT_BAD;
      ! return;
      ! }
      ! if ((milter_count = atoi(buf)) > 0)
      cleanup_milter_receive(state, milter_count);
      return;
      }
      --- 148,154 ----
      #endif
      if (type == REC_TYPE_MILT_COUNT) {
      /* Not part of queue file format. */
      ! if ((milter_count = atoi(buf)) >= 0)
      cleanup_milter_receive(state, milter_count);
      return;
      }
      diff -cr /var/tmp/postfix-2.5-20070724/src/cleanup/cleanup_milter.c src/cleanup/cleanup_milter.c
      *** /var/tmp/postfix-2.5-20070724/src/cleanup/cleanup_milter.c Mon May 7 09:26:44 2007
      --- src/cleanup/cleanup_milter.c Mon Jul 30 20:39:41 2007
      ***************
      *** 1314,1319 ****
      --- 1314,1321 ----

      void cleanup_milter_receive(CLEANUP_STATE *state, int count)
      {
      + if (state->milters)
      + milter_free(state->milters);
      state->milters = milter_receive(state->src, count);
      milter_macro_callback(state->milters, cleanup_milter_eval, (void *) state);
      milter_edit_callback(state->milters,
      diff --exclude=man --exclude=html --exclude=README_FILES --exclude=.indent.pro --exclude=Makefile.in -cr /var/tmp/postfix-2.5-20070724/src/milter/milter.c src/milter/milter.c
      *** /var/tmp/postfix-2.5-20070724/src/milter/milter.c Wed Mar 14 20:46:12 2007
      --- src/milter/milter.c Mon Jul 30 20:30:44 2007
      ***************
      *** 97,102 ****
      --- 97,106 ----
      /* MILTERS *milter_receive(fp, count)
      /* VSTREAM *fp;
      /* int count;
      + /*
      + /* int milter_dummy(milters, fp)
      + /* MILTERS *milters;
      + /* VSTREAM *fp;
      /* DESCRIPTION
      /* The functions in this module manage one or more milter (mail
      /* filter) clients. Currently, only the Sendmail 8 filter
      ***************
      *** 192,197 ****
      --- 196,204 ----
      /* milter_receive() receives the specified number of mail
      /* filters over the specified stream. The result is a null
      /* pointer when no milters were sent, or when an error happened.
      + /*
      + /* milter_dummy() is like milter_send(), except that it sends
      + /* a dummy, but entirely valid, mail filter list.
      /* SEE ALSO
      /* milter8(3) Sendmail 8 Milter protocol
      /* DIAGNOSTICS
      ***************
      *** 587,592 ****
      --- 594,609 ----
      #define MAIL_ATTR_MILT_EOD "eod_macros"
      #define MAIL_ATTR_MILT_UNK "unk_macros"

      + /* milter_dummy - send empty milter list */
      +
      + int milter_dummy(MILTERS *milters, VSTREAM *stream)
      + {
      + MILTERS dummy = *milters;
      +
      + dummy.milter_list = 0;
      + return (milter_send(&dummy, stream));
      + }
      +
      /* milter_send - send Milter instances over stream */

      int milter_send(MILTERS *milters, VSTREAM *stream)
      ***************
      *** 606,613 ****
      for (m = milters->milter_list; m != 0; m = m->next)
      if (m->active(m))
      count++;
      - if (count == 0)
      - return (0);
      (void) rec_fprintf(stream, REC_TYPE_MILT_COUNT, "%d", count);

      /*
      --- 623,628 ----
      ***************
      *** 655,663 ****
      VSTRING *data_macros;
      VSTRING *eod_macros;
      VSTRING *unk_macros;
      -
      - if (count == 0)
      - return (0);

      /*
      * Receive filter macros.
      --- 670,675 ----
      diff --exclude=man --exclude=html --exclude=README_FILES --exclude=.indent.pro --exclude=Makefile.in -cr /var/tmp/postfix-2.5-20070724/src/milter/milter.h src/milter/milter.h
      *** /var/tmp/postfix-2.5-20070724/src/milter/milter.h Tue Jan 9 20:55:23 2007
      --- src/milter/milter.h Mon Jul 30 20:15:27 2007
      ***************
      *** 99,104 ****
      --- 99,105 ----
      extern const char *milter_other_event(MILTERS *);
      extern void milter_abort(MILTERS *);
      extern void milter_disc_event(MILTERS *);
      + extern int milter_dummy(MILTERS *, VSTREAM *);
      extern int milter_send(MILTERS *, VSTREAM *);
      extern MILTERS *milter_receive(VSTREAM *, int);
      extern void milter_free(MILTERS *);
    Your message has been successfully submitted and would be delivered to recipients shortly.