Postfix Milter client created a queue file that caused
delivery agents to loop. File: cleanup/cleanup_milter.c.
+20060725
+
+ Bugfix: damaged queue file record after a Milter request
+ to modify a message header when 1) it was the last header
+ in the unmodified message, and 2) the old header was less
+ than 15 characters long. File: cleanup/cleanup_milter.c.
+
+ Bugfix: don't panic in smtp_rcpt_cleanup() after detecting
+ a damaged queue file record. File: smtp/smtp_proto.c.
+
Wish list:
Add M flag (enable multi-recipient delivery) to pipe daemon.
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(CLEANUP_MILTER_OBJS) $(LIBS) $(SYSLIBS)
mv junk cleanup_milter.o
-tests: cleanup_masquerade_test cleanup_milter_test
+tests: cleanup_masquerade_test cleanup_milter_test cleanup_milter_test2
root_tests:
diff cleanup_milter.ref1 cleanup_milter.tmp
rm -f test-queue-file.tmp cleanup_milter.tmp
+cleanup_milter_test2: cleanup_milter cleanup_milter.in2 cleanup_milter.ref2 \
+ test-queue-file2 ../postcat/postcat
+ cp test-queue-file2 test-queue-file2.tmp
+ chmod u+w test-queue-file2.tmp
+ ./cleanup_milter <cleanup_milter.in2
+ ../postcat/postcat -ov test-queue-file2.tmp 2>/dev/null >cleanup_milter.tmp
+ diff cleanup_milter.ref2 cleanup_milter.tmp
+ rm -f test-queue-file2.tmp cleanup_milter.tmp
+
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
msg_warn("%s: seek file %s: %m", myname, cleanup_path);
CLEANUP_PATCH_HEADER_RETURN(cleanup_milter_error(state, errno));
}
- CLEANUP_OUT_BUF(state, rec_type, buf);
+ /* The saved "append header" pointer record may still contain "0". */
+ if (saved_read_offset == state->append_hdr_pt_offset)
+ cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
+ (long) state->append_hdr_pt_target);
+ else
+ CLEANUP_OUT_BUF(state, rec_type, buf);
if (msg_verbose > 1)
msg_info("%s: %ld: write %.*s", myname, (long) write_offset,
LEN(buf) > 30 ? 30 : (int) LEN(buf), STR(buf));
CLEANUP_UPD_HEADER_RETURN(cleanup_milter_error(state, errno));
}
if (rec_type == REC_TYPE_PTR) {
+ /* The "append header" pointer record content must be saved. */
+ if (saved_read_offset == state->append_hdr_pt_offset)
+ break;
if (jumped == 0) {
/* Enough contiguous space for writing a PTR record. */
avail_space += read_offset - saved_read_offset;
--- /dev/null
+#verbose on
+open test-queue-file2.tmp
+upd_header 1 Subject hey!
+upd_header 1 Subject hey!
+upd_header 1 Subject hey!
+add_header foo foobar
+upd_header 1 foo foobar
+upd_header 1 foo foobar
+upd_header 1 foo foobar
+close
--- /dev/null
+*** ENVELOPE RECORDS test-queue-file2.tmp ***
+ 0 message_size: 329 181 1 0
+ 65 message_arrival_time: Tue Jul 25 15:37:06 2006
+ 82 create_time: Tue Jul 25 15:37:06 2006
+ 106 named_attribute: rewrite_context=local
+ 129 sender_fullname: Wietse Venema
+ 144 sender: me@porcupine.org
+ 162 pointer_record: 0
+ 179 *** MESSAGE CONTENTS test-queue-file2.tmp ***
+ 181 regular_text: Received: by bristle.watson.ibm.com (Postfix, from userid 0)
+ 243 regular_text: id 034B229013F; Tue, 25 Jul 2006 15:37:06 -0400 (EDT)
+ 299 regular_text: From: me@porcupine.org
+ 323 regular_text: To: you@porcupine.org
+ 346 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org>
+ 408 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT)
+ 453 pointer_record: 552
+ 552 pointer_record: 584
+ 584 pointer_record: 616
+ 616 regular_text: Subject: hey!
+ 631 pointer_record: 648
+ 648 pointer_record: 678
+ 678 pointer_record: 708
+ 708 pointer_record: 738
+ 738 regular_text: foo: foobar
+ 751 pointer_record: 485
+ 485 regular_text:
+ 487 regular_text: text
+ 493 pointer_record: 0
+ 510 *** HEADER EXTRACTED test-queue-file2.tmp ***
+ 512 original_recipient: you@porcupine.org
+ 531 recipient: you@porcupine.org
+ 550 *** MESSAGE FILE END test-queue-file2.tmp ***
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20060724"
+#define MAIL_RELEASE_DATE "20060725"
#define MAIL_VERSION_NUMBER "2.4"
#ifdef SNAPSHOT
NOCLOBBER int mail_from_rejected;
NOCLOBBER int downgrading;
int mime_errs;
+ SMTP_RESP fake;
+ int fail_status;
/*
* Macros for readability.
if (rec_type != REC_TYPE_XTRA) {
msg_warn("%s: bad record type: %d in message content",
request->queue_id, rec_type);
- RETURN(mark_corrupt(state->src));
+ fail_status = smtp_mesg_fail(state, DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "5.3.0"),
+ "unreadable mail queue entry");
+ if (fail_status == 0)
+ (void) mark_corrupt(state->src);
+ RETURN(fail_status);
}
}