back to 2.0.27 (that's more than 10 years ago). Files:
*qmgr/qmgr_transport.c.
+20070112
+
+ Bugfix (introduced 20011008): with nested access restrictions,
+ possible longjump into exited stack frame after configuration
+ 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.
+
Wish list:
Update BACKSCATTER_README to use PCRE because that's what I
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 \
xtext_test scache_multi_test ehlo_mask_test \
- namadr_list_test mail_conf_time_test
+ namadr_list_test mail_conf_time_test mime_garb1 mime_garb2
root_tests: rewrite_clnt_test resolve_clnt_test
diff mime_cvt.ref3 mime_cvt.tmp
rm -f mime_cvt.tmp
+mime_garb1: mime_state mime_garb1.in mime_garb1.ref
+ ./mime_state <mime_garb1.in >mime_cvt.tmp
+ diff mime_garb1.ref mime_cvt.tmp
+ rm -f mime_cvt.tmp
+
+mime_garb2: mime_state mime_garb2.in mime_garb2.ref
+ ./mime_state <mime_garb2.in >mime_cvt.tmp
+ diff mime_garb2.ref mime_cvt.tmp
+ rm -f mime_cvt.tmp
+
tok822_limit_test: tok822_parse tok822_limit.in tok822_limit.ref
./tok822_parse <tok822_limit.in >tok822_limit.tmp
diff tok822_limit.ref tok822_limit.tmp
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20070107"
+#define MAIL_RELEASE_DATE "20070112"
#define MAIL_VERSION_NUMBER "2.4"
#ifdef SNAPSHOT
--- /dev/null
+From: Some One <user@example.com>
+To: Some One <user@example.com>
+Subject: Test
+MIME-Version: 1.0
+Content-Type: Multipart/Mixed;
+ boundary="Boundary-00=_mvhpFky0yqNhsa4"
+
+--Boundary-00=_mvhpFky0yqNhsa4
+Content-Type: text/plain;
+ charset="utf-8"
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+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 <user@example.com>
+Subject: Forwarded Test
+
+Blah
+
--- /dev/null
+MAIN 0 |From: Some One <user@example.com>
+MAIN 32 |To: Some One <user@example.com>
+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
+BODY N 0 |
+BODY N 1 |--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
+BODY N 0 |
+BODY N 1 |This is a test
+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 |=46rom user@example.com Thu Jan 11 13:08:21 CET 2007
+NEST 0 |To: user@example.com
+NEST 36 |=46rom: Some One <user@example.com>
+NEST 60 |Subject: Forwarded Test
+BODY N 0 |
+BODY N 1 |Blah
+BODY N 6 |
+BODY END
+mime_state: warning: improper message/* or multipart/* encoding domain
+mime_state: POP boundary Boundary-00=_mvhpFky0yqNhsa4
--- /dev/null
+From: Some One <user@example.com>
+To: Some One <user@example.com>
+Subject: Test
+MIME-Version: 1.0
+Content-Type: Multipart/Mixed;
+ boundary="Boundary-00=_mvhpFky0yqNhsa4"
+
+--Boundary-00=_mvhpFky0yqNhsa4
+Content-Type: text/plain;
+ charset="utf-8"
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+This is a test
+--Boundary-00=_mvhpFky0yqNhsa4
+Content-Type: message/rfc822;
+ name="forwarded message"
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+From user@example.com Thu Jan 11 13:08:21 CET 2007
+To: user@example.com
+From: Some One <user@example.com>
+Subject: Forwarded Test
+
+Blah
+
--- /dev/null
+MAIN 0 |From: Some One <user@example.com>
+MAIN 32 |To: Some One <user@example.com>
+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
+BODY N 0 |
+BODY N 1 |--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
+BODY N 0 |
+BODY N 1 |This is a test
+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 <user@example.com>
+NEST 58 |Subject: Forwarded Test
+BODY N 0 |
+BODY N 1 |Blah
+BODY N 6 |
+BODY END
+mime_state: warning: improper message/* or multipart/* encoding domain
+mime_state: POP boundary Boundary-00=_mvhpFky0yqNhsa4
/*
* 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.
+ *
+ * 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 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.
*/
else {
- SET_CURR_STATE(state, MIME_STATE_BODY);
- BODY_OUT(state, REC_TYPE_NORM, "", 0);
+ 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);
+ BODY_OUT(state, REC_TYPE_NORM, "", 0);
+ }
}
}
* caching; the idea is that such "thinking time" is affordable only after
* the output channels are maxed out.
*/
+#ifndef QMGR_TRANSPORT_MAX_PEND
#define QMGR_TRANSPORT_MAX_PEND 2
+#endif
/* qmgr_transport_unthrottle_wrapper - in case (char *) != (struct *) */
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
-/*
-/* Scheduler enhancements:
-/* Patrik Rak
-/* Modra 6
-/* 155 00, Prague, Czech Republic
/*--*/
/* System library. */
* caching; the idea is that such "thinking time" is affordable only after
* the output channels are maxed out.
*/
+#ifndef QMGR_TRANSPORT_MAX_PEND
#define QMGR_TRANSPORT_MAX_PEND 2
+#endif
/* qmgr_transport_unthrottle_wrapper - in case (char *) != (struct *) */
reply_class, def_acl);
}
argv_free(restrictions);
+ memcpy(ADDROF(smtpd_check_buf), ADDROF(savebuf), sizeof(smtpd_check_buf));
return (status);
}
{
if (msg_vprintf_lock == 0) {
msg_vprintf_lock = 1;
+ /* On-the-fly initialization for debugging test programs only. */
+ if (msg_output_fn_count == 0)
+ msg_vstream_init("unknown", VSTREAM_ERR);
/* OK if terminating signal handler hijacks control before next stmt. */
vstring_vsprintf(msg_buffer, percentm(format, errno), ap);
msg_text(level, vstring_str(msg_buffer));
if ((fifo = open(path, O_WRONLY | O_NONBLOCK, 0)) < 0)
return (-1);
+ /*
+ * This is for {unix,inet}_connect() compatibility.
+ */
+ if (block_mode == BLOCKING)
+ non_blocking(fifo, BLOCKING);
+
/*
* Create a pipe, and send one pipe end to the server.
*/
#ifdef STREAM_CONNECTIONS
if (ioctl(fd, I_SENDFD, sendfd) < 0)
- msg_fatal("%s: send file descriptor: %m", myname);
+ msg_fatal("%s: send file descriptor %d: %m", sendfd, myname);
return (0);
#else
msg_fatal("stream connections are not implemented");