]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.8.19 v2.8.19
authorWietse Venema <wietse@porcupine.org>
Sun, 19 Oct 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 10 Feb 2018 18:59:31 +0000 (13:59 -0500)
postfix/HISTORY
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/cleanup/cleanup_state.c
postfix/src/global/mail_version.h
postfix/src/milter/milter.c
postfix/src/milter/milter.h
postfix/src/milter/milter8.c
postfix/src/smtpd/smtpd.c

index c98975b6682fdf5b85faf1ab00233efdb6df3e8b..1a09e077960c018fd6cc394d4e89b96ef8360519 100644 (file)
@@ -17009,3 +17009,16 @@ Apologies for any names omitted.
        SPF policy plus DKIM Milter.  PREPENDed headers are now
        added BELOW Postfix's own Received: header and remain visible
        to Milters. File: smtpd/smtpd.c.
+
+20141018
+
+       Bugfix (introduced: Postfix 2.3): when a Milter inserted a
+       header ABOVE Postfix's own Received: header, Postfix would
+       expose its own Received: header to Milters (violating
+       protocol) and hide the Milter-inserted header from Milters
+       (wtf).  Files: cleanup/cleanup.h, cleanup/cleanup_message.c,
+       cleanup/cleanup_state.c, milter/milter.[hc], milter/milter8.c.
+
+       Cleanup: revert the workaround that places headers inserted
+       with PREPEND actions or policy requests BELOW Postfix's own
+       Received: message header. File: smtpd/smtpd.c.
index a962f00786b187fd5c81db12a13a1ac505813c78..22beca2b9d008f913f87893ca0eaae4bd6a0d411 100644 (file)
@@ -61,6 +61,7 @@ typedef struct CLEANUP_STATE {
     char   *orig_rcpt;                 /* original recipient address */
     char   *return_receipt;            /* return-receipt address */
     char   *errors_to;                 /* errors-to address */
+    ARGV   *auto_hdrs;                 /* MTA's own header(s) */
     int     flags;                     /* processing options, status flags */
     int     qmgr_opts;                 /* qmgr processing options */
     int     errs;                      /* any badness experienced */
index 4de1aa5309b88b4be4fd8387b9428e7e105b0689..bae16b97e9cd472e55611184f5ad29cf23429d63 100644 (file)
@@ -479,6 +479,10 @@ static void cleanup_header_callback(void *context, int header_class,
     if (hdr_opts && (hdr_opts->flags & HDR_OPT_MIME))
        header_class = MIME_HDR_MULTIPART;
 
+    /* Update the Received: header count before maybe dropping headers below. */
+    if (hdr_opts && hdr_opts->type == HDR_RECEIVED)
+       state->hop_count += 1;
+
     if ((state->flags & CLEANUP_FLAG_FILTER)
        && (CHECK(MIME_HDR_PRIMARY, cleanup_header_checks, VAR_HEADER_CHECKS)
     || CHECK(MIME_HDR_MULTIPART, cleanup_mimehdr_checks, VAR_MIMEHDR_CHECKS)
@@ -574,9 +578,13 @@ static void cleanup_header_callback(void *context, int header_class,
            msg_info("%s: message-id=%s", state->queue_id, hdrval);
        if (hdr_opts->type == HDR_RESENT_MESSAGE_ID)
            msg_info("%s: resent-message-id=%s", state->queue_id, hdrval);
-       if (hdr_opts->type == HDR_RECEIVED)
-           if (++state->hop_count >= var_hopcount_limit)
+       if (hdr_opts->type == HDR_RECEIVED) {
+           if (state->hop_count >= var_hopcount_limit)
                state->errs |= CLEANUP_STAT_HOPS;
+           /* Save our Received: header after maybe updating headers above. */
+           if (state->hop_count == 1)
+               argv_add(state->auto_hdrs, vstring_str(header_buf), ARGV_END);
+       }
        if (CLEANUP_OUT_OK(state)) {
            if (hdr_opts->flags & HDR_OPT_RR)
                state->resent = "Resent-";
index 4877611fe1c20b327ce518a953b9a4d8e3dfd078..4de31a41cc10494150746d5476a47faa517ab74c 100644 (file)
@@ -1982,7 +1982,7 @@ void    cleanup_milter_inspect(CLEANUP_STATE *state, MILTERS *milters)
      * filter library.
      */
     if ((resp = milter_message(milters, state->handle->stream,
-                              state->data_offset)) != 0)
+                              state->data_offset, state->auto_hdrs)) != 0)
        cleanup_milter_apply(state, "END-OF-MESSAGE", resp);
 
     /*
index 8d9085262a68fd490cc794405b121da24b4af63e..87b006182a5ba6da0093188ad9386c37ebe2ff4c 100644 (file)
@@ -78,6 +78,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
     state->orig_rcpt = 0;
     state->return_receipt = 0;
     state->errors_to = 0;
+    state->auto_hdrs = argv_alloc(1);
     state->flags = 0;
     state->qmgr_opts = 0;
     state->errs = 0;
@@ -150,6 +151,7 @@ void    cleanup_state_free(CLEANUP_STATE *state)
        myfree(state->return_receipt);
     if (state->errors_to)
        myfree(state->errors_to);
+    argv_free(state->auto_hdrs);
     if (state->queue_name)
        myfree(state->queue_name);
     if (state->queue_id)
index 6f7098f922664729af9dcd64bac24587505b9875..a2b8edb020a49cd1aba81a7ab02a95228601e1a4 100644 (file)
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20141013"
-#define MAIL_VERSION_NUMBER    "2.8.18"
+#define MAIL_RELEASE_DATE      "20141019"
+#define MAIL_VERSION_NUMBER    "2.8.19"
 
 #ifdef SNAPSHOT
 # define MAIL_VERSION_DATE     "-" MAIL_RELEASE_DATE
index ee38b0f238acf055eb91d16652f14fa5f1e75b03..9cddc6319cea3bab8be891b5536e49c4811a1126 100644 (file)
 /*     const char *milter_other_event(milters)
 /*     MILTERS *milters;
 /*
-/*     const char *milter_message(milters, qfile, data_offset)
+/*     const char *milter_message(milters, qfile, data_offset, auto_hdrs)
 /*     MILTERS *milters;
 /*     VSTREAM *qfile;
 /*     off_t   data_offset;
+/*     ARGV    *auto_hdrs;
 /*
 /*     const char *milter_abort(milters)
 /*     MILTERS *milters;
@@ -481,7 +482,8 @@ const char *milter_other_event(MILTERS *milters)
 
 /* milter_message - inspect message content */
 
-const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset)
+const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset,
+                                  ARGV *auto_hdrs)
 {
     const char *resp;
     MILTER *m;
@@ -495,7 +497,8 @@ const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset)
     for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
        any_eoh_macros = MILTER_MACRO_EVAL(global_eoh_macros, m, milters, eoh_macros);
        any_eod_macros = MILTER_MACRO_EVAL(global_eod_macros, m, milters, eod_macros);
-       resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros);
+       resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros,
+                         auto_hdrs);
        if (any_eoh_macros != global_eoh_macros)
            argv_free(any_eoh_macros);
        if (any_eod_macros != global_eod_macros)
index 17d163dc42a3d0c42bea40736e5c087b6b0d56d5..bf25fccc040ef9b08832f9be6c98a5c02e1926cd 100644 (file)
@@ -40,7 +40,7 @@ typedef struct MILTER {
     const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
     const char *(*rcpt_event) (struct MILTER *, const char **, ARGV *);
     const char *(*data_event) (struct MILTER *, ARGV *);
-    const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *);
+    const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *, ARGV *);
     const char *(*unknown_event) (struct MILTER *, const char *, ARGV *);
     const char *(*other_event) (struct MILTER *);
     void    (*abort) (struct MILTER *);
@@ -136,7 +136,7 @@ extern const char *milter_helo_event(MILTERS *, const char *, int);
 extern const char *milter_mail_event(MILTERS *, const char **);
 extern const char *milter_rcpt_event(MILTERS *, int, const char **);
 extern const char *milter_data_event(MILTERS *);
-extern const char *milter_message(MILTERS *, VSTREAM *, off_t);
+extern const char *milter_message(MILTERS *, VSTREAM *, off_t, ARGV *);
 extern const char *milter_unknown_event(MILTERS *, const char *);
 extern const char *milter_other_event(MILTERS *);
 extern void milter_abort(MILTERS *);
index 22d4c419fb7ad528e1c1552a5bde5d47fcb650a1..7e1a5da028ca6d6fa884b8434178e395f31fe6bc 100644 (file)
@@ -2270,6 +2270,8 @@ typedef struct {
     MILTER8 *milter;                   /* milter client */
     ARGV   *eoh_macros;                        /* end-of-header macros */
     ARGV   *eod_macros;                        /* end-of-body macros */
+    ARGV   *auto_hdrs;                 /* auto-generated headers */
+    int     auto_done;                 /* good enough for now */
     int     first_header;              /* first header */
     int     first_body;                        /* first body line */
     const char *resp;                  /* milter application response */
@@ -2286,6 +2288,8 @@ static void milter8_header(void *ptr, int unused_header_class,
     MILTER8 *milter = msg_ctx->milter;
     char   *cp;
     int     skip_reply;
+    char  **cpp;
+    unsigned done;
 
     /*
      * XXX Workaround: mime_state_update() may invoke multiple call-backs
@@ -2314,10 +2318,11 @@ static void milter8_header(void *ptr, int unused_header_class,
      * XXX Sendmail compatibility. It eats the first space (not tab) after the
      * header label and ":".
      */
-    if (msg_ctx->first_header) {
-       msg_ctx->first_header = 0;
-       return;
-    }
+    for (cpp = msg_ctx->auto_hdrs->argv, done = 1; *cpp; cpp++, done <<= 1)
+       if ((msg_ctx->auto_done & done) == 0 && strcmp(*cpp, STR(buf)) == 0) {
+           msg_ctx->auto_done |= done;
+           return;
+       }
 
     /*
      * Sendmail 8 sends multi-line headers as text separated by newline.
@@ -2492,7 +2497,8 @@ static void milter8_eob(void *ptr)
 static const char *milter8_message(MILTER *m, VSTREAM *qfile,
                                           off_t data_offset,
                                           ARGV *eoh_macros,
-                                          ARGV *eod_macros)
+                                          ARGV *eod_macros,
+                                          ARGV *auto_hdrs)
 {
     const char *myname = "milter8_message";
     MILTER8 *milter = (MILTER8 *) m;
@@ -2526,6 +2532,8 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
        msg_ctx.milter = milter;
        msg_ctx.eoh_macros = eoh_macros;
        msg_ctx.eod_macros = eod_macros;
+       msg_ctx.auto_hdrs = auto_hdrs;
+       msg_ctx.auto_done = 0;
        msg_ctx.first_header = 1;
        msg_ctx.first_body = 1;
        msg_ctx.resp = 0;
index 294986c235d8e070dd174f4e2b6829ec9455ca0e..b367580be00a6510db21cb5e2f201612d3e7e9f4 100644 (file)
@@ -2829,6 +2829,13 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
        rec_fputs(state->cleanup, REC_TYPE_MESG, "");
     }
 
+    /*
+     * PREPEND message headers above our own Received: header.
+     */
+    if (state->prepend)
+       for (cpp = state->prepend->argv; *cpp; cpp++)
+           out_fprintf(out_stream, REC_TYPE_NORM, "%s", *cpp);
+
     /*
      * Suppress our own Received: header in the unlikely case that we are an
      * intermediate proxy.
@@ -2920,17 +2927,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
 #endif
     }
 
-    /*
-     * PREPEND message headers below our own Received: header. According
-     * https://www.milter.org/developers/api/smfi_insheader, Milters see only
-     * headers that have been sent by the SMTP client and those header
-     * modifications by earlier filters. Based on this we allow Milters to
-     * see headers added by access map or by policy service.
-     */
-    if (state->prepend)
-       for (cpp = state->prepend->argv; *cpp; cpp++)
-           out_fprintf(out_stream, REC_TYPE_NORM, "%s", *cpp);
-
     smtpd_chat_reply(state, "354 End data with <CR><LF>.<CR><LF>");
     state->where = SMTPD_AFTER_DATA;