Prereq: "2.10.4" diff -cr --new-file /var/tmp/postfix-2.10.4/src/global/mail_version.h ./src/global/mail_version.h *** /var/tmp/postfix-2.10.4/src/global/mail_version.h 2014-10-13 18:43:38.000000000 -0400 --- ./src/global/mail_version.h 2014-10-19 18:17:32.000000000 -0400 *************** *** 20,27 **** * 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.10.4" #ifdef SNAPSHOT # define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE --- 20,27 ---- * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ ! #define MAIL_RELEASE_DATE "20141019" ! #define MAIL_VERSION_NUMBER "2.10.5" #ifdef SNAPSHOT # define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff -cr --new-file /var/tmp/postfix-2.10.4/HISTORY ./HISTORY *** /var/tmp/postfix-2.10.4/HISTORY 2014-10-13 18:40:34.000000000 -0400 --- ./HISTORY 2014-10-19 18:40:43.000000000 -0400 *************** *** 18377,18379 **** --- 18377,18392 ---- 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. diff -cr --new-file /var/tmp/postfix-2.10.4/src/cleanup/cleanup.h ./src/cleanup/cleanup.h *** /var/tmp/postfix-2.10.4/src/cleanup/cleanup.h 2012-01-09 18:55:14.000000000 -0500 --- ./src/cleanup/cleanup.h 2014-10-18 17:40:07.000000000 -0400 *************** *** 61,66 **** --- 61,67 ---- 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 */ diff -cr --new-file /var/tmp/postfix-2.10.4/src/cleanup/cleanup_message.c ./src/cleanup/cleanup_message.c *** /var/tmp/postfix-2.10.4/src/cleanup/cleanup_message.c 2012-01-10 20:38:50.000000000 -0500 --- ./src/cleanup/cleanup_message.c 2014-10-18 17:40:07.000000000 -0400 *************** *** 479,484 **** --- 479,488 ---- 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) *************** *** 578,586 **** 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) state->errs |= CLEANUP_STAT_HOPS; if (CLEANUP_OUT_OK(state)) { if (hdr_opts->flags & HDR_OPT_RR) state->resent = "Resent-"; --- 582,594 ---- 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) 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-"; diff -cr --new-file /var/tmp/postfix-2.10.4/src/cleanup/cleanup_milter.c ./src/cleanup/cleanup_milter.c *** /var/tmp/postfix-2.10.4/src/cleanup/cleanup_milter.c 2012-02-02 09:35:03.000000000 -0500 --- ./src/cleanup/cleanup_milter.c 2014-10-18 17:40:07.000000000 -0400 *************** *** 1987,1993 **** * filter library. */ if ((resp = milter_message(milters, state->handle->stream, ! state->data_offset)) != 0) cleanup_milter_apply(state, "END-OF-MESSAGE", resp); /* --- 1987,1993 ---- * filter library. */ if ((resp = milter_message(milters, state->handle->stream, ! state->data_offset, state->auto_hdrs)) != 0) cleanup_milter_apply(state, "END-OF-MESSAGE", resp); /* diff -cr --new-file /var/tmp/postfix-2.10.4/src/cleanup/cleanup_state.c ./src/cleanup/cleanup_state.c *** /var/tmp/postfix-2.10.4/src/cleanup/cleanup_state.c 2009-06-06 17:49:55.000000000 -0400 --- ./src/cleanup/cleanup_state.c 2014-10-18 17:40:07.000000000 -0400 *************** *** 78,83 **** --- 78,84 ---- 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,155 **** --- 151,157 ---- 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) diff -cr --new-file /var/tmp/postfix-2.10.4/src/milter/milter.c ./src/milter/milter.c *** /var/tmp/postfix-2.10.4/src/milter/milter.c 2011-10-24 10:28:38.000000000 -0400 --- ./src/milter/milter.c 2014-10-18 17:40:07.000000000 -0400 *************** *** 85,94 **** /* const char *milter_other_event(milters) /* MILTERS *milters; /* ! /* const char *milter_message(milters, qfile, data_offset) /* MILTERS *milters; /* VSTREAM *qfile; /* off_t data_offset; /* /* const char *milter_abort(milters) /* MILTERS *milters; --- 85,95 ---- /* const char *milter_other_event(milters) /* MILTERS *milters; /* ! /* 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,487 **** /* milter_message - inspect message content */ ! const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset) { const char *resp; MILTER *m; --- 482,489 ---- /* milter_message - inspect message content */ ! const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset, ! ARGV *auto_hdrs) { const char *resp; MILTER *m; *************** *** 495,501 **** 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); if (any_eoh_macros != global_eoh_macros) argv_free(any_eoh_macros); if (any_eod_macros != global_eod_macros) --- 497,504 ---- 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, ! auto_hdrs); if (any_eoh_macros != global_eoh_macros) argv_free(any_eoh_macros); if (any_eod_macros != global_eod_macros) diff -cr --new-file /var/tmp/postfix-2.10.4/src/milter/milter.h ./src/milter/milter.h *** /var/tmp/postfix-2.10.4/src/milter/milter.h 2009-04-27 10:53:56.000000000 -0400 --- ./src/milter/milter.h 2014-10-18 17:40:07.000000000 -0400 *************** *** 40,46 **** 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 *(*unknown_event) (struct MILTER *, const char *, ARGV *); const char *(*other_event) (struct MILTER *); void (*abort) (struct MILTER *); --- 40,46 ---- 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 *, ARGV *); const char *(*unknown_event) (struct MILTER *, const char *, ARGV *); const char *(*other_event) (struct MILTER *); void (*abort) (struct MILTER *); *************** *** 136,142 **** 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_unknown_event(MILTERS *, const char *); extern const char *milter_other_event(MILTERS *); extern void milter_abort(MILTERS *); --- 136,142 ---- 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, ARGV *); extern const char *milter_unknown_event(MILTERS *, const char *); extern const char *milter_other_event(MILTERS *); extern void milter_abort(MILTERS *); diff -cr --new-file /var/tmp/postfix-2.10.4/src/milter/milter8.c ./src/milter/milter8.c *** /var/tmp/postfix-2.10.4/src/milter/milter8.c 2011-08-31 09:04:19.000000000 -0400 --- ./src/milter/milter8.c 2014-10-18 17:40:07.000000000 -0400 *************** *** 2270,2275 **** --- 2270,2277 ---- 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,2291 **** --- 2288,2295 ---- 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,2323 **** * 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; ! } /* * Sendmail 8 sends multi-line headers as text separated by newline. --- 2318,2328 ---- * XXX Sendmail compatibility. It eats the first space (not tab) after the * header label and ":". */ ! 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,2498 **** static const char *milter8_message(MILTER *m, VSTREAM *qfile, off_t data_offset, ARGV *eoh_macros, ! ARGV *eod_macros) { const char *myname = "milter8_message"; MILTER8 *milter = (MILTER8 *) m; --- 2497,2504 ---- static const char *milter8_message(MILTER *m, VSTREAM *qfile, off_t data_offset, ARGV *eoh_macros, ! ARGV *eod_macros, ! ARGV *auto_hdrs) { const char *myname = "milter8_message"; MILTER8 *milter = (MILTER8 *) m; *************** *** 2526,2531 **** --- 2532,2539 ---- 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; diff -cr --new-file /var/tmp/postfix-2.10.4/src/smtpd/smtpd.c ./src/smtpd/smtpd.c *** /var/tmp/postfix-2.10.4/src/smtpd/smtpd.c 2014-10-13 18:39:57.000000000 -0400 --- ./src/smtpd/smtpd.c 2014-10-18 17:40:07.000000000 -0400 *************** *** 2981,2986 **** --- 2981,2993 ---- } /* + * 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. */ *************** *** 3070,3086 **** #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 ."); state->where = SMTPD_AFTER_DATA; --- 3077,3082 ----