On Tue, Sep 28, 2010 at 03:46:17PM -0700, Murray S. Kucherawy wrote:
> No, I didn't test it, because I don't have postfix installed anywhere
> here. But even testing it doesn't mean my experiment nailed down the
> actual source code logic or the background for it, hence the question.
>
The second comment paragraph may be a bit unclear. It says that inserting
a blank line after primary headers does not break anything, not that we
don't insert a blank line. Either way, the Postfix MIME parser ends up
in the BODY state, but the BODY_OUT(state, REC_TYPE_NORM, "", 0) code
to add blank line is only called at the end of the primary header.
/*
* Invalid input. Force output of one blank line and jump to the
* body state, leaving all other state alone.
*
* We don't break legitimate mail by inserting a blank line
* separator between primary headers and a non-empty body. Many
* MTA's don't even record the presence or absence of this
* separator, nor does the Milter protocol pass it on to Milter
* applications.
*
* XXX We don't insert a blank line separator into attachments, to
* avoid breaking digital signatures. Postfix shall not do a
* worse mail delivery job than MTAs that can't even parse MIME.
* We switch to body state anyway, to avoid treating body text as
* header text, and mis-interpreting or truncating it. The code
* below for initial From_ lines is for educational purposes.
*
* Sites concerned about MIME evasion can use a MIME normalizer.
* Postfix has a different mission.
*/
else {
if (msg_verbose)
msg_info("garbage in %s header",
state->curr_state == MIME_STATE_MULTIPART ? "multipart" :
state->curr_state == MIME_STATE_PRIMARY ? "primary" :
state->curr_state == MIME_STATE_NESTED ? "nested" :
"other");
switch (state->curr_state) {
case MIME_STATE_PRIMARY:
BODY_OUT(state, REC_TYPE_NORM, "", 0);
SET_CURR_STATE(state, MIME_STATE_BODY);
break;
#if 0
case MIME_STATE_NESTED:
if (state->body_offset <= 1
&& rec_type == REC_TYPE_NORM
&& len > 7
&& (strncmp(text + (*text == '>'), "From ", 5) == 0
|| strncmp(text, "=46rom ", 7) == 0))
break;
/* FALLTHROUGH */
#endif
default:
SET_CURR_STATE(state, MIME_STATE_BODY);
break;
}
}
--
Viktor.