From: Wietse Venema Date: Sat, 13 Jan 2007 05:00:00 +0000 (-0500) Subject: postfix-2.4-20070113 X-Git-Tag: v2.4.0-RC1~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3eb0ee42510f54199c133dafc2775f0999c95cef;p=thirdparty%2Fpostfix.git postfix-2.4-20070113 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 3fac5658c..f72f6cc80 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -13101,10 +13101,11 @@ Apologies for any names omitted. error or table lookup error. Victor Duchovni. Files: smtpd/smtpd_check.c. - Horrible workaround: don't insert blank line before message/* - starting with a mailbox From_ or =46rom_ line, and output - this garbage as body content, without actually switching - to message body state. File: global/mime_state.c. + Horrible workaround: don't insert header/body blank line + separator in malformed attachments. This breaks digital + signatures. People concerned about MIME evasion can use a + MIME normalizer to corrupt their user's legitimate email. + File: global/mime_state.c. Wish list: diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index fa8e16a2e..f3097f91a 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -268,10 +268,12 @@ valid_mailhost_addr: valid_mailhost_addr.c $(LIB) $(LIBS) own_inet_addr: own_inet_addr.c $(LIB) $(LIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) -tests: tok822_test mime_test mime_nest mime_8bit mime_dom mime_trunc \ - mime_cvt mime_cvt2 mime_cvt3 strip_addr_test tok822_limit_test \ +tests: tok822_test mime_tests strip_addr_test tok822_limit_test \ xtext_test scache_multi_test ehlo_mask_test \ - namadr_list_test mail_conf_time_test mime_garb1 mime_garb2 + namadr_list_test mail_conf_time_test + +mime_tests: mime_test mime_nest mime_8bit mime_dom mime_trunc mime_cvt \ + mime_cvt2 mime_cvt3 mime_garb1 mime_garb2 mime_garb3 root_tests: rewrite_clnt_test resolve_clnt_test @@ -330,6 +332,11 @@ mime_garb2: mime_state mime_garb2.in mime_garb2.ref diff mime_garb2.ref mime_cvt.tmp rm -f mime_cvt.tmp +mime_garb3: mime_state mime_garb3.in mime_garb3.ref + ./mime_state mime_cvt.tmp + diff mime_garb3.ref mime_cvt.tmp + rm -f mime_cvt.tmp + tok822_limit_test: tok822_parse tok822_limit.in tok822_limit.ref ./tok822_parse tok822_limit.tmp diff tok822_limit.ref tok822_limit.tmp diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 7da926c96..1bce4ac68 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20070112" +#define MAIL_RELEASE_DATE "20070113" #define MAIL_VERSION_NUMBER "2.4" #ifdef SNAPSHOT diff --git a/postfix/src/global/mime_garb1.ref b/postfix/src/global/mime_garb1.ref index 9c2c7b4db..8d9beb84b 100644 --- a/postfix/src/global/mime_garb1.ref +++ b/postfix/src/global/mime_garb1.ref @@ -27,13 +27,14 @@ MULT 44 |Content-Transfer-Encoding: quoted-printable MULT 72 |Content-Disposition: inline mime_state: warning: invalid message/* or multipart/* encoding domain: quoted-printable BODY N 0 | -BODY N 1 |=46rom user@example.com Thu Jan 11 13:08:21 CET 2007 -NEST 0 |To: user@example.com -NEST 36 |=46rom: Some One -NEST 60 |Subject: Forwarded Test -BODY N 0 | -BODY N 1 |Blah -BODY N 6 | +mime_state: garbage in nested header +BODY N 0 |=46rom user@example.com Thu Jan 11 13:08:21 CET 2007 +BODY N 53 |To: user@example.com +BODY N 74 |=46rom: Some One +BODY N 110 |Subject: Forwarded Test +BODY N 134 | +BODY N 135 |Blah +BODY N 140 | BODY END mime_state: warning: improper message/* or multipart/* encoding domain mime_state: POP boundary Boundary-00=_mvhpFky0yqNhsa4 diff --git a/postfix/src/global/mime_garb2.in b/postfix/src/global/mime_garb2.in index 6ca1e2304..9add72084 100644 --- a/postfix/src/global/mime_garb2.in +++ b/postfix/src/global/mime_garb2.in @@ -15,7 +15,7 @@ This is a test --Boundary-00=_mvhpFky0yqNhsa4 Content-Type: message/rfc822; name="forwarded message" -Content-Transfer-Encoding: quoted-printable +Content-Transfer-Encoding: 7bit Content-Disposition: inline From user@example.com Thu Jan 11 13:08:21 CET 2007 diff --git a/postfix/src/global/mime_garb2.ref b/postfix/src/global/mime_garb2.ref index fa5003237..22671385c 100644 --- a/postfix/src/global/mime_garb2.ref +++ b/postfix/src/global/mime_garb2.ref @@ -22,18 +22,17 @@ BODY N 16 |--Boundary-00=_mvhpFky0yqNhsa4 mime_state: header_token: message / rfc822 MULT 0 |Content-Type: message/rfc822; name="forwarded message" -mime_state: header_token: quoted-printable -MULT 44 |Content-Transfer-Encoding: quoted-printable -MULT 72 |Content-Disposition: inline -mime_state: warning: invalid message/* or multipart/* encoding domain: quoted-printable -BODY N 0 | -BODY N 1 |From user@example.com Thu Jan 11 13:08:21 CET 2007 -NEST 0 |To: user@example.com -NEST 34 |From: Some One -NEST 58 |Subject: Forwarded Test +mime_state: header_token: 7bit +MULT 32 |Content-Transfer-Encoding: 7bit +MULT 60 |Content-Disposition: inline BODY N 0 | -BODY N 1 |Blah -BODY N 6 | +mime_state: garbage in nested header +BODY N 0 |From user@example.com Thu Jan 11 13:08:21 CET 2007 +BODY N 51 |To: user@example.com +BODY N 72 |From: Some One +BODY N 106 |Subject: Forwarded Test +BODY N 130 | +BODY N 131 |Blah +BODY N 136 | BODY END -mime_state: warning: improper message/* or multipart/* encoding domain mime_state: POP boundary Boundary-00=_mvhpFky0yqNhsa4 diff --git a/postfix/src/global/mime_garb3.in b/postfix/src/global/mime_garb3.in new file mode 100644 index 000000000..54d129ae9 --- /dev/null +++ b/postfix/src/global/mime_garb3.in @@ -0,0 +1,29 @@ +From: Some One +To: Some One +Subject: Test +MIME-Version: 1.0 +Content-Type: Multipart/Mixed; + boundary="Boundary-00=_mvhpFky0yqNhsa4" +junk in primary header + +--Boundary-00=_mvhpFky0yqNhsa4 +Content-Type: text/plain; + charset="utf-8" +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline +junk in multipart header + +This is a test +--Boundary-00=_mvhpFky0yqNhsa4 +Content-Type: message/rfc822; + name="forwarded message" +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + +=46rom user@example.com Thu Jan 11 13:08:21 CET 2007 +To: user@example.com +=46rom: Some One +Subject: Forwarded Test + +Blah + diff --git a/postfix/src/global/mime_garb3.ref b/postfix/src/global/mime_garb3.ref new file mode 100644 index 000000000..873ef91fa --- /dev/null +++ b/postfix/src/global/mime_garb3.ref @@ -0,0 +1,45 @@ +MAIN 0 |From: Some One +MAIN 32 |To: Some One +MAIN 46 |Subject: Test +MAIN 64 |MIME-Version: 1.0 +mime_state: header_token: Multipart / Mixed +mime_state: header_token: boundary = Boundary-00=_mvhpFky0yqNhsa4 +mime_state: PUSH boundary Boundary-00=_mvhpFky0yqNhsa4 +MAIN 95 |Content-Type: Multipart/Mixed; + boundary="Boundary-00=_mvhpFky0yqNhsa4" +HEADER END +mime_state: garbage in primary header +BODY N -1 | +BODY N 0 |junk in primary header +BODY N 23 | +BODY N 24 |--Boundary-00=_mvhpFky0yqNhsa4 +mime_state: header_token: text / plain +MULT 0 |Content-Type: text/plain; + charset="utf-8" +mime_state: header_token: quoted-printable +MULT 44 |Content-Transfer-Encoding: quoted-printable +MULT 72 |Content-Disposition: inline +mime_state: garbage in multipart header +BODY N 0 |junk in multipart header +BODY N 25 | +BODY N 26 |This is a test +BODY N 41 |--Boundary-00=_mvhpFky0yqNhsa4 +mime_state: header_token: message / rfc822 +MULT 0 |Content-Type: message/rfc822; + name="forwarded message" +mime_state: header_token: quoted-printable +MULT 44 |Content-Transfer-Encoding: quoted-printable +MULT 72 |Content-Disposition: inline +mime_state: warning: invalid message/* or multipart/* encoding domain: quoted-printable +BODY N 0 | +mime_state: garbage in nested header +BODY N 0 |=46rom user@example.com Thu Jan 11 13:08:21 CET 2007 +BODY N 53 |To: user@example.com +BODY N 74 |=46rom: Some One +BODY N 110 |Subject: Forwarded Test +BODY N 134 | +BODY N 135 |Blah +BODY N 140 | +BODY END +mime_state: warning: improper message/* or multipart/* encoding domain +mime_state: POP boundary Boundary-00=_mvhpFky0yqNhsa4 diff --git a/postfix/src/global/mime_state.c b/postfix/src/global/mime_state.c index 8bb4e816d..b81fc1f90 100644 --- a/postfix/src/global/mime_state.c +++ b/postfix/src/global/mime_state.c @@ -967,40 +967,31 @@ int mime_state_update(MIME_STATE *state, int rec_type, * Invalid input. Force output of one blank line and jump to the * body state, leaving all other state alone. * - * XXX Some broken software sends a From_ line at the start of - * Message/rfc822 content, and some doubly brain-damaged software - * even encodes Message/rfc822 content as quoted-printable. If we - * force output of a blank line after such garbage then we are - * safe: all headers that follow are permanently neutralized, but - * of course the message is modified. + * 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 If we don't force output of a blank line before garbage, we - * must still inspect the text that follows garbage as message - * headers. Otherwise we would introduce a trivial security hole - * to slip forbidden content past Postfix header_checks. + * XXX We don't insert a blank line separator with attachments, as + * this breaks digital signatures. Postfix shall not do a worse + * mail delivery job than crappy MTAs that can't even parse MIME. + * But we switch to the body state anyway. * - * XXX Because the garbage is not a valid header, we must not feed - * it into call-back routines that expect valid header lines. - * This code therefore falls through into the code that emits - * body lines, which we already use anyway to emit the empty line - * between a header and body block, and between MIME headers and - * message/* headers. Using body output code for garbage output - * is safe provided that rec_type is REC_TYPE_NORM and that - * state->curr_domain is MIME_ENC_7BIT, so that we don't have to - * worry about MIME downgrading. If any of this changes then we - * have a problem. + * People who worry about MIME evasion can use a MIME normalizer, + * and knowlingly corrupt legitimate email for their users. + * Postfix has a different mission. */ else { - if (state->curr_state == MIME_STATE_NESTED - && rec_type == REC_TYPE_NORM - && len > 7 - && (strncmp(text + (*text == '>'), "From ", 5) == 0 - || strncmp(text, "=46rom ", 7) == 0)) { - /* Output as body, but don't change state just yet. */ ; - } else { - SET_CURR_STATE(state, MIME_STATE_BODY); + 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"); + if (state->curr_state == MIME_STATE_PRIMARY) BODY_OUT(state, REC_TYPE_NORM, "", 0); - } + SET_CURR_STATE(state, MIME_STATE_BODY); } }