From d87dc6f21c2df715ab0861411a1537beddc7920b Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sat, 2 Oct 2021 00:00:00 -0500 Subject: [PATCH] postfix-3.7-20211002 --- postfix/HISTORY | 15 + postfix/html/bounce.8.html | 5 + postfix/html/cleanup.8.html | 3 + postfix/html/defer.8.html | 5 + postfix/html/lmtp.8.html | 3 + postfix/html/smtp.8.html | 3 + postfix/html/smtpd.8.html | 3 + postfix/html/trace.8.html | 5 + postfix/man/man8/bounce.8 | 4 + postfix/man/man8/cleanup.8 | 2 + postfix/man/man8/smtp.8 | 2 + postfix/man/man8/smtpd.8 | 2 + postfix/src/bounce/2template_test.in | 16 +- postfix/src/bounce/Makefile.in | 21 +- postfix/src/bounce/bounce.c | 13 + .../src/bounce/bounce_notify_util_tester.c | 8 + postfix/src/bounce/bounce_service.h | 5 + postfix/src/bounce/bounce_template.c | 10 +- postfix/src/bounce/bounce_template.h | 3 +- postfix/src/bounce/bounce_templates.c | 12 +- .../no-msgid-no-eoh-event-no-thread.ref | 2 +- .../no-msgid-no-eoh-event-with-thread.ref | 2 +- .../no-msgid-with-eoh-event-no-thread.ref | 2 +- .../no-msgid-with-eoh-event-with-thread.ref | 2 +- postfix/src/bounce/obs_template_test.ref | 68 +++++ postfix/src/bounce/template_test.ref | 8 +- .../with-msgid-no-eoh-event-no-thread.ref | 2 +- .../with-msgid-no-eoh-event-with-thread.ref | 2 +- .../with-msgid-with-eoh-event-no-thread.ref | 2 +- .../with-msgid-with-eoh-event-with-thread.ref | 2 +- .../with-msgid-with-filter-no-thread.ref | 2 +- .../with-msgid-with-filter-with-thread.ref | 2 +- .../with-msgid-with-long-line-no-thread.ref | 2 +- .../with-msgid-with-long-line-with-thread.ref | 2 +- postfix/src/cleanup/Makefile.in | 2 + postfix/src/cleanup/cleanup.c | 2 + postfix/src/cleanup/cleanup.h | 4 +- postfix/src/cleanup/cleanup_init.c | 13 +- postfix/src/cleanup/cleanup_message.c | 27 +- postfix/src/global/Makefile.in | 29 +- postfix/src/global/hfrom_format.c | 281 ++++++++++++++++++ postfix/src/global/hfrom_format.h | 34 +++ postfix/src/global/hfrom_format.ref | 8 + postfix/src/global/mail_version.h | 2 +- postfix/src/smtp/Makefile.in | 2 + postfix/src/smtp/lmtp_params.c | 5 +- postfix/src/smtp/smtp.c | 13 +- postfix/src/smtp/smtp.h | 5 + postfix/src/smtp/smtp_chat.c | 13 +- postfix/src/smtp/smtp_params.c | 5 +- postfix/src/smtpd/Makefile.in | 2 + postfix/src/smtpd/smtpd.c | 15 + postfix/src/smtpd/smtpd.h | 5 + postfix/src/smtpd/smtpd_chat.c | 13 +- 54 files changed, 643 insertions(+), 77 deletions(-) create mode 100644 postfix/src/bounce/obs_template_test.ref create mode 100644 postfix/src/global/hfrom_format.c create mode 100644 postfix/src/global/hfrom_format.h create mode 100644 postfix/src/global/hfrom_format.ref diff --git a/postfix/HISTORY b/postfix/HISTORY index a77b594c9..0485b328c 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -25780,3 +25780,18 @@ Apologies for any names omitted. Cleanup: don't hyperlink text that is already hyperlinked. File: mantools/postlink. + +20211002 + + Bugfix (introduced: Postfix 3.3): the header_from_format + feature was not implemented for From: headers from the + bounce daemon, and for Postfix SMTP server and client + postmaster notifications. Reported by Vladimir Mishonov. + Files: bounce/bounce.c, bounce/bounce_notify_util_tester.c, + bounce/bounce_service.h, bounce/bounce_template.c, + bounce/bounce_template.h, bounce/bounce_templates.c, + cleanup/cleanup.h, cleanup/cleanup_init.c, + cleanup/cleanup_message.c, smtp/lmtp_params.c, smtp/smtp.c, + smtp/smtp.h, smtp/smtp_chat.c, smtp/smtp_params.c, + smtpd/smtpd.c, smtpd/smtpd.h, smtpd/smtpd_chat.c, and test + data. diff --git a/postfix/html/bounce.8.html b/postfix/html/bounce.8.html index d5caebb1c..077af1668 100644 --- a/postfix/html/bounce.8.html +++ b/postfix/html/bounce.8.html @@ -160,6 +160,11 @@ BOUNCE(8) BOUNCE(8) to the original message by including a References: and In-Reply-To: header with the original Message-ID value. + Available in Postfix 3.7 and later: + + header_from_format (standard) + The format of the Postfix-generated From: header. + FILES /var/spool/postfix/bounce/* non-delivery records /var/spool/postfix/defer/* non-delivery records diff --git a/postfix/html/cleanup.8.html b/postfix/html/cleanup.8.html index 38c0f2baa..c276f6cbf 100644 --- a/postfix/html/cleanup.8.html +++ b/postfix/html/cleanup.8.html @@ -117,6 +117,9 @@ CLEANUP(8) CLEANUP(8) after applying header_checks(5) and before invoking Milter applications. + header_from_format (standard) + The format of the Postfix-generated From: header. + BUILT-IN CONTENT FILTERING CONTROLS Postfix built-in content filtering is meant to stop a flood of worms or viruses. It is not a general content filter. diff --git a/postfix/html/defer.8.html b/postfix/html/defer.8.html index d5caebb1c..077af1668 100644 --- a/postfix/html/defer.8.html +++ b/postfix/html/defer.8.html @@ -160,6 +160,11 @@ BOUNCE(8) BOUNCE(8) to the original message by including a References: and In-Reply-To: header with the original Message-ID value. + Available in Postfix 3.7 and later: + + header_from_format (standard) + The format of the Postfix-generated From: header. + FILES /var/spool/postfix/bounce/* non-delivery records /var/spool/postfix/defer/* non-delivery records diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html index 2f654e0a6..b4420f221 100644 --- a/postfix/html/lmtp.8.html +++ b/postfix/html/lmtp.8.html @@ -392,6 +392,9 @@ SMTP(8) SMTP(8) DATA requests, when deadlines are enabled with smtp_per_request_deadline. + header_from_format (standard) + The format of the Postfix-generated From: header. + MIME PROCESSING CONTROLS Available in Postfix version 2.0 and later: diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index 2f654e0a6..b4420f221 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -392,6 +392,9 @@ SMTP(8) SMTP(8) DATA requests, when deadlines are enabled with smtp_per_request_deadline. + header_from_format (standard) + The format of the Postfix-generated From: header. + MIME PROCESSING CONTROLS Available in Postfix version 2.0 and later: diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index 8d8f6dc6f..db7d76308 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -951,6 +951,9 @@ SMTPD(8) SMTPD(8) DATA and BDAT requests, when deadlines are enabled with smtpd_per_request_deadline. + header_from_format (standard) + The format of the Postfix-generated From: header. + TARPIT CONTROLS When a remote SMTP client makes errors, the Postfix SMTP server can insert delays before responding. This can help to slow down run-away diff --git a/postfix/html/trace.8.html b/postfix/html/trace.8.html index d5caebb1c..077af1668 100644 --- a/postfix/html/trace.8.html +++ b/postfix/html/trace.8.html @@ -160,6 +160,11 @@ BOUNCE(8) BOUNCE(8) to the original message by including a References: and In-Reply-To: header with the original Message-ID value. + Available in Postfix 3.7 and later: + + header_from_format (standard) + The format of the Postfix-generated From: header. + FILES /var/spool/postfix/bounce/* non-delivery records /var/spool/postfix/defer/* non-delivery records diff --git a/postfix/man/man8/bounce.8 b/postfix/man/man8/bounce.8 index 1c5197887..007ffdc0d 100644 --- a/postfix/man/man8/bounce.8 +++ b/postfix/man/man8/bounce.8 @@ -142,6 +142,10 @@ Available in Postfix 3.6 and later: Enable non\-delivery, success, and delay notifications that link to the original message by including a References: and In\-Reply\-To: header with the original Message\-ID value. +.PP +Available in Postfix 3.7 and later: +.IP "\fBheader_from_format (standard)\fR" +The format of the Postfix\-generated \fBFrom:\fR header. .SH "FILES" .na .nf diff --git a/postfix/man/man8/cleanup.8 b/postfix/man/man8/cleanup.8 index 8c07ecac5..8c2cc0b9e 100644 --- a/postfix/man/man8/cleanup.8 +++ b/postfix/man/man8/cleanup.8 @@ -130,6 +130,8 @@ Available in Postfix version 3.0 and later: .IP "\fBmessage_drop_headers (bcc, content\-length, resent\-bcc, return\-path)\fR" Names of message headers that the \fBcleanup\fR(8) daemon will remove after applying \fBheader_checks\fR(5) and before invoking Milter applications. +.IP "\fBheader_from_format (standard)\fR" +The format of the Postfix\-generated \fBFrom:\fR header. .SH "BUILT-IN CONTENT FILTERING CONTROLS" .na .nf diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index 656c6eed8..add4aec34 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -376,6 +376,8 @@ complete SMTP response. .IP "\fBsmtp_min_data_rate (500)\fR" The minimum plaintext data transfer rate in bytes/second for DATA requests, when deadlines are enabled with smtp_per_request_deadline. +.IP "\fBheader_from_format (standard)\fR" +The format of the Postfix\-generated \fBFrom:\fR header. .SH "MIME PROCESSING CONTROLS" .na .nf diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index ea910ae06..44b050327 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -834,6 +834,8 @@ and for sending a complete SMTP response. The minimum plaintext data transfer rate in bytes/second for DATA and BDAT requests, when deadlines are enabled with smtpd_per_request_deadline. +.IP "\fBheader_from_format (standard)\fR" +The format of the Postfix\-generated \fBFrom:\fR header. .SH "TARPIT CONTROLS" .na .nf diff --git a/postfix/src/bounce/2template_test.in b/postfix/src/bounce/2template_test.in index 8afb4cef9..e45fd3266 100644 --- a/postfix/src/bounce/2template_test.in +++ b/postfix/src/bounce/2template_test.in @@ -1,6 +1,6 @@ failure_template = < Subject: Undelivered Mail Returned to Sender Postmaster-Subject: Postmaster Copy: Undelivered Mail @@ -19,7 +19,7 @@ EOF delay_template = < Subject: Delayed Mail (still being retried) Postmaster-Subject: Postmaster Warning: Delayed Mail @@ -42,7 +42,7 @@ EOF success_template = < Subject: Successful Mail Delivery Report This is the mail system at host $myhostname. @@ -57,7 +57,7 @@ EOF verify_template = < Subject: Mail Delivery Status Report This is the mail system at host $myhostname. @@ -68,7 +68,7 @@ Enclosed is the mail delivery report that you requested. EOF failure_template = < Subject: Undelivered Mail Returned to Sender Postmaster-Subject: Postmaster Copy: Undelivered Mail @@ -87,7 +87,7 @@ EOF delay_template = < Subject: Delayed Mail (still being retried) Postmaster-Subject: Postmaster Warning: Delayed Mail @@ -110,7 +110,7 @@ EOF success_template = < Subject: Successful Mail Delivery Report This is the mail system at host $myhostname. @@ -125,7 +125,7 @@ EOF verify_template = < Subject: Mail Delivery Status Report This is the mail system at host $myhostname. diff --git a/postfix/src/bounce/Makefile.in b/postfix/src/bounce/Makefile.in index cd5ed85fd..969413a00 100644 --- a/postfix/src/bounce/Makefile.in +++ b/postfix/src/bounce/Makefile.in @@ -38,7 +38,7 @@ Makefile: Makefile.in test: $(TESTPROG) -tests: update template_test 2template_test \ +tests: update template_test obs_template_test 2template_test \ with-msgid-with-long-line_test \ with-msgid-with-eoh-event_test \ with-msgid-no-eoh-event_test \ @@ -82,6 +82,7 @@ bounce_notify_util_tester: $(BOUNCE_NOTIFY_UTIL_TESTER_OBJS) $(LIBS) template_test: $(PROG) template_test.ref echo queue_directory=. >main.cf echo myhostname=example.com >>main.cf + echo header_from_format=standard >>main.cf touch -t 197101010000 main.cf MAIL_CONFIG=. ./$(PROG) -SVzndump_templates >template_test.tmp diff template_test.ref template_test.tmp @@ -90,6 +91,15 @@ template_test: $(PROG) template_test.ref diff template_test.ref template_test.tmp rm -f template_test.tmp main.cf +obs_template_test: $(PROG) obs_template_test.ref + echo queue_directory=. >main.cf + echo myhostname=example.com >>main.cf + echo header_from_format=obsolete >>main.cf + touch -t 197101010000 main.cf + MAIL_CONFIG=. ./$(PROG) -SVzndump_templates >template_test.tmp + diff obs_template_test.ref template_test.tmp + rm -f template_test.tmp main.cf + 2template_test: $(PROG) template_test.ref 2template_test.in echo queue_directory=. >main.cf echo myhostname=example.com >>main.cf @@ -327,6 +337,7 @@ bounce.o: ../../include/deliver_request.h bounce.o: ../../include/dsb_scan.h bounce.o: ../../include/dsn.h bounce.o: ../../include/dsn_buf.h +bounce.o: ../../include/hfrom_format.h bounce.o: ../../include/htable.h bounce.o: ../../include/iostuff.h bounce.o: ../../include/load_file.h @@ -481,6 +492,7 @@ bounce_notify_util_tester.o: ../../include/check_arg.h bounce_notify_util_tester.o: ../../include/dsn.h bounce_notify_util_tester.o: ../../include/dsn_buf.h bounce_notify_util_tester.o: ../../include/dsn_mask.h +bounce_notify_util_tester.o: ../../include/hfrom_format.h bounce_notify_util_tester.o: ../../include/htable.h bounce_notify_util_tester.o: ../../include/mail_conf.h bounce_notify_util_tester.o: ../../include/mail_params.h @@ -570,7 +582,11 @@ bounce_one_service.o: bounce_one_service.c bounce_one_service.o: bounce_service.h bounce_one_service.o: bounce_template.h bounce_template.o: ../../include/attr.h +bounce_template.o: ../../include/bounce_log.h bounce_template.o: ../../include/check_arg.h +bounce_template.o: ../../include/dsn.h +bounce_template.o: ../../include/dsn_buf.h +bounce_template.o: ../../include/hfrom_format.h bounce_template.o: ../../include/htable.h bounce_template.o: ../../include/iostuff.h bounce_template.o: ../../include/is_header.h @@ -583,12 +599,15 @@ bounce_template.o: ../../include/midna_domain.h bounce_template.o: ../../include/msg.h bounce_template.o: ../../include/mymalloc.h bounce_template.o: ../../include/nvtable.h +bounce_template.o: ../../include/rcpt_buf.h +bounce_template.o: ../../include/recipient_list.h bounce_template.o: ../../include/split_at.h bounce_template.o: ../../include/stringops.h bounce_template.o: ../../include/sys_defs.h bounce_template.o: ../../include/vbuf.h bounce_template.o: ../../include/vstream.h bounce_template.o: ../../include/vstring.h +bounce_template.o: bounce_service.h bounce_template.o: bounce_template.c bounce_template.o: bounce_template.h bounce_templates.o: ../../include/attr.h diff --git a/postfix/src/bounce/bounce.c b/postfix/src/bounce/bounce.c index 6f6643e17..23939299b 100644 --- a/postfix/src/bounce/bounce.c +++ b/postfix/src/bounce/bounce.c @@ -130,6 +130,10 @@ /* Enable non-delivery, success, and delay notifications that link /* to the original message by including a References: and In-Reply-To: /* header with the original Message-ID value. +/* .PP +/* Available in Postfix 3.7 and later: +/* .IP "\fBheader_from_format (standard)\fR" +/* The format of the Postfix-generated \fBFrom:\fR header. /* FILES /* /var/spool/postfix/bounce/* non-delivery records /* /var/spool/postfix/defer/* non-delivery records @@ -183,6 +187,7 @@ #include #include #include +#include /* Single-threaded server skeleton. */ @@ -204,6 +209,7 @@ char *var_2bounce_rcpt; char *var_delay_rcpt; char *var_bounce_tmpl; bool var_threaded_bounce; +char *var_hfrom_format; /* header_from_format */ /* * We're single threaded, so we can avoid some memory allocation overhead. @@ -222,6 +228,11 @@ static DSN_BUF *dsn_buf; */ BOUNCE_TEMPLATES *bounce_templates; + /* + * From: header format. + */ +int bounce_hfrom_format; + #define STR vstring_str #define VS_NEUTER(s) printable(vstring_str(s), '?') @@ -620,6 +631,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv) static void post_jail_init(char *service_name, char **unused_argv) { + bounce_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format); /* * Special case: dump bounce templates. This is not part of the master(5) @@ -673,6 +685,7 @@ int main(int argc, char **argv) VAR_2BOUNCE_RCPT, DEF_2BOUNCE_RCPT, &var_2bounce_rcpt, 1, 0, VAR_DELAY_RCPT, DEF_DELAY_RCPT, &var_delay_rcpt, 1, 0, VAR_BOUNCE_TMPL, DEF_BOUNCE_TMPL, &var_bounce_tmpl, 0, 0, + VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0, 0, }; static const CONFIG_NBOOL_TABLE nbool_table[] = { diff --git a/postfix/src/bounce/bounce_notify_util_tester.c b/postfix/src/bounce/bounce_notify_util_tester.c index b8abdd730..da13f4705 100644 --- a/postfix/src/bounce/bounce_notify_util_tester.c +++ b/postfix/src/bounce/bounce_notify_util_tester.c @@ -19,6 +19,7 @@ #include #include #include +#include /* * Bounce service. @@ -59,6 +60,9 @@ static void test_driver(int argc, char **argv) if (chdir(var_queue_dir) < 0) msg_fatal("chdir %s: %m", var_queue_dir); + bounce_hfrom_format = + hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format); + /* * Write one message to VSTRING. */ @@ -123,6 +127,9 @@ char *var_2bounce_rcpt; char *var_delay_rcpt; char *var_bounce_tmpl; bool var_threaded_bounce; +char *var_hfrom_format; /* header_from_format */ + +int bounce_hfrom_format; int main(int argc, char **argv) { @@ -141,6 +148,7 @@ int main(int argc, char **argv) VAR_2BOUNCE_RCPT, DEF_2BOUNCE_RCPT, &var_2bounce_rcpt, 1, 0, VAR_DELAY_RCPT, DEF_DELAY_RCPT, &var_delay_rcpt, 1, 0, VAR_BOUNCE_TMPL, DEF_BOUNCE_TMPL, &var_bounce_tmpl, 0, 0, + VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0, 0, }; static const CONFIG_NBOOL_TABLE nbool_table[] = { diff --git a/postfix/src/bounce/bounce_service.h b/postfix/src/bounce/bounce_service.h index 40793f2ff..b79542fc9 100644 --- a/postfix/src/bounce/bounce_service.h +++ b/postfix/src/bounce/bounce_service.h @@ -23,6 +23,11 @@ */ #include + /* + * bounce_service.c + */ +extern int bounce_hfrom_format; + /* * bounce_append_service.c */ diff --git a/postfix/src/bounce/bounce_template.c b/postfix/src/bounce/bounce_template.c index 629f83bfe..67a5cf7c6 100644 --- a/postfix/src/bounce/bounce_template.c +++ b/postfix/src/bounce/bounce_template.c @@ -131,10 +131,12 @@ #include #include #include +#include /* Application-specific. */ #include +#include /* * The following tables implement support for bounce template expansions of @@ -334,7 +336,7 @@ static void bounce_template_parse_buffer(BOUNCE_TEMPLATE *tp) if (strcasecmp("charset", cp) == 0) { tp->mime_charset = hval; } else if (strcasecmp("from", cp) == 0) { - tp->from = hval; + tp->std_from = tp->obs_from = hval; } else if (strcasecmp("subject", cp) == 0) { tp->subject = hval; } else if (strcasecmp("postmaster-subject", cp) == 0) { @@ -491,7 +493,8 @@ void bounce_template_headers(BOUNCE_XP_PRN_FN out_fn, VSTREAM *fp, if (tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER) bounce_template_parse_buffer(tp); - out_fn(fp, "From: %s", tp->from); + out_fn(fp, "From: %s", bounce_hfrom_format == HFROM_FORMAT_CODE_STD ? + tp->std_from : tp->obs_from); out_fn(fp, "Subject: %s", tp->postmaster_subject && postmaster_copy ? tp->postmaster_subject : tp->subject); out_fn(fp, "To: %s", rcpt); @@ -533,7 +536,8 @@ void bounce_template_dump(VSTREAM *fp, BOUNCE_TEMPLATE *tp) bounce_template_parse_buffer(tp); vstream_fprintf(fp, "Charset: %s\n", tp->mime_charset); - vstream_fprintf(fp, "From: %s\n", tp->from); + vstream_fprintf(fp, "From: %s\n", bounce_hfrom_format == HFROM_FORMAT_CODE_STD ? + tp->std_from : tp->obs_from); vstream_fprintf(fp, "Subject: %s\n", tp->subject); if (tp->postmaster_subject) vstream_fprintf(fp, "Postmaster-Subject: %s\n", diff --git a/postfix/src/bounce/bounce_template.h b/postfix/src/bounce/bounce_template.h index 5b771e466..87835fcbe 100644 --- a/postfix/src/bounce/bounce_template.h +++ b/postfix/src/bounce/bounce_template.h @@ -27,7 +27,8 @@ typedef struct BOUNCE_TEMPLATE { const char *origin; /* built-in or pathname */ const char *mime_charset; /* character set (configurable) */ const char *mime_encoding; /* 7bit or 8bit (derived) */ - const char *from; /* originator (configurable) */ + const char *obs_from; /* originator (configurable) */ + const char *std_from; /* originator (configurable) */ const char *subject; /* general subject (configurable) */ const char *postmaster_subject; /* postmaster subject (configurable) */ const char **message_text; /* message text (configurable) */ diff --git a/postfix/src/bounce/bounce_templates.c b/postfix/src/bounce/bounce_templates.c index 11daece41..f81dfd4dd 100644 --- a/postfix/src/bounce/bounce_templates.c +++ b/postfix/src/bounce/bounce_templates.c @@ -63,6 +63,11 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ /* System library. */ @@ -114,6 +119,7 @@ static const BOUNCE_TEMPLATE def_bounce_failure_template = { "us-ascii", MAIL_ATTR_ENC_7BIT, MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)", + "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">", "Undelivered Mail Returned to Sender", "Postmaster Copy: Undelivered Mail", def_bounce_failure_body, @@ -130,8 +136,7 @@ static const char *def_bounce_delay_body[] = { "# THIS IS A WARNING ONLY. YOU DO NOT NEED TO RESEND YOUR MESSAGE. #", "####################################################################", "", - "Your message could not be delivered for more than $delay_warning_time_hours hour(s)." - , + "Your message could not be delivered for more than $delay_warning_time_hours hour(s).", "It will be retried until it is $maximal_queue_lifetime_days day(s) old.", "", "For further assistance, please send mail to " MAIL_ADDR_POSTMASTER ".", @@ -150,6 +155,7 @@ static const BOUNCE_TEMPLATE def_bounce_delay_template = { "us-ascii", MAIL_ATTR_ENC_7BIT, MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)", + "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">", "Delayed Mail (still being retried)", "Postmaster Warning: Delayed Mail", def_bounce_delay_body, @@ -179,6 +185,7 @@ static const BOUNCE_TEMPLATE def_bounce_success_template = { "us-ascii", MAIL_ATTR_ENC_7BIT, MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)", + "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">", "Successful Mail Delivery Report", 0, def_bounce_success_body, @@ -205,6 +212,7 @@ static const BOUNCE_TEMPLATE def_bounce_verify_template = { "us-ascii", MAIL_ATTR_ENC_7BIT, MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)", + "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">", "Mail Delivery Status Report", 0, def_bounce_verify_body, diff --git a/postfix/src/bounce/no-msgid-no-eoh-event-no-thread.ref b/postfix/src/bounce/no-msgid-no-eoh-event-no-thread.ref index 0ec87a9aa..630734d2e 100644 --- a/postfix/src/bounce/no-msgid-no-eoh-event-no-thread.ref +++ b/postfix/src/bounce/no-msgid-no-eoh-event-no-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/no-msgid-no-eoh-event-with-thread.ref b/postfix/src/bounce/no-msgid-no-eoh-event-with-thread.ref index 0ec87a9aa..630734d2e 100644 --- a/postfix/src/bounce/no-msgid-no-eoh-event-with-thread.ref +++ b/postfix/src/bounce/no-msgid-no-eoh-event-with-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/no-msgid-with-eoh-event-no-thread.ref b/postfix/src/bounce/no-msgid-with-eoh-event-no-thread.ref index 8741e085f..39b5841d2 100644 --- a/postfix/src/bounce/no-msgid-with-eoh-event-no-thread.ref +++ b/postfix/src/bounce/no-msgid-with-eoh-event-no-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/no-msgid-with-eoh-event-with-thread.ref b/postfix/src/bounce/no-msgid-with-eoh-event-with-thread.ref index 8741e085f..39b5841d2 100644 --- a/postfix/src/bounce/no-msgid-with-eoh-event-with-thread.ref +++ b/postfix/src/bounce/no-msgid-with-eoh-event-with-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/obs_template_test.ref b/postfix/src/bounce/obs_template_test.ref new file mode 100644 index 000000000..e03bb5b8b --- /dev/null +++ b/postfix/src/bounce/obs_template_test.ref @@ -0,0 +1,68 @@ +failure_template = < Subject: Undelivered Mail Returned to Sender Postmaster-Subject: Postmaster Copy: Undelivered Mail @@ -19,7 +19,7 @@ EOF delay_template = < Subject: Delayed Mail (still being retried) Postmaster-Subject: Postmaster Warning: Delayed Mail @@ -42,7 +42,7 @@ EOF success_template = < Subject: Successful Mail Delivery Report This is the mail system at host $myhostname. @@ -57,7 +57,7 @@ EOF verify_template = < Subject: Mail Delivery Status Report This is the mail system at host $myhostname. diff --git a/postfix/src/bounce/with-msgid-no-eoh-event-no-thread.ref b/postfix/src/bounce/with-msgid-no-eoh-event-no-thread.ref index 3798b6f16..020d9a4c1 100644 --- a/postfix/src/bounce/with-msgid-no-eoh-event-no-thread.ref +++ b/postfix/src/bounce/with-msgid-no-eoh-event-no-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/with-msgid-no-eoh-event-with-thread.ref b/postfix/src/bounce/with-msgid-no-eoh-event-with-thread.ref index 30ee63a40..d2aadd088 100644 --- a/postfix/src/bounce/with-msgid-no-eoh-event-with-thread.ref +++ b/postfix/src/bounce/with-msgid-no-eoh-event-with-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient References: <12345@mta-name.example> diff --git a/postfix/src/bounce/with-msgid-with-eoh-event-no-thread.ref b/postfix/src/bounce/with-msgid-with-eoh-event-no-thread.ref index 67bc27d1e..70afb5f33 100644 --- a/postfix/src/bounce/with-msgid-with-eoh-event-no-thread.ref +++ b/postfix/src/bounce/with-msgid-with-eoh-event-no-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/with-msgid-with-eoh-event-with-thread.ref b/postfix/src/bounce/with-msgid-with-eoh-event-with-thread.ref index eb1e126fd..e46afbe9f 100644 --- a/postfix/src/bounce/with-msgid-with-eoh-event-with-thread.ref +++ b/postfix/src/bounce/with-msgid-with-eoh-event-with-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient References: <12345@mta-name.example> diff --git a/postfix/src/bounce/with-msgid-with-filter-no-thread.ref b/postfix/src/bounce/with-msgid-with-filter-no-thread.ref index 0666540af..fa30ddfdb 100644 --- a/postfix/src/bounce/with-msgid-with-filter-no-thread.ref +++ b/postfix/src/bounce/with-msgid-with-filter-no-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/with-msgid-with-filter-with-thread.ref b/postfix/src/bounce/with-msgid-with-filter-with-thread.ref index 520c3b832..14d33730d 100644 --- a/postfix/src/bounce/with-msgid-with-filter-with-thread.ref +++ b/postfix/src/bounce/with-msgid-with-filter-with-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient References: <12345@mta-name.example> diff --git a/postfix/src/bounce/with-msgid-with-long-line-no-thread.ref b/postfix/src/bounce/with-msgid-with-long-line-no-thread.ref index b26a05250..fa5268bb8 100644 --- a/postfix/src/bounce/with-msgid-with-long-line-no-thread.ref +++ b/postfix/src/bounce/with-msgid-with-long-line-no-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient Auto-Submitted: auto-replied diff --git a/postfix/src/bounce/with-msgid-with-long-line-with-thread.ref b/postfix/src/bounce/with-msgid-with-long-line-with-thread.ref index c22838ad2..04e96d68c 100644 --- a/postfix/src/bounce/with-msgid-with-long-line-with-thread.ref +++ b/postfix/src/bounce/with-msgid-with-long-line-with-thread.ref @@ -1,4 +1,4 @@ -From: MAILER-DAEMON (Mail Delivery System) +From: Mail Delivery System Subject: Undelivered Mail Returned to Sender To: test-recipient References: <12345@mta-name.example> diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in index 2b8f11917..8a3c18c95 100644 --- a/postfix/src/cleanup/Makefile.in +++ b/postfix/src/cleanup/Makefile.in @@ -996,6 +996,7 @@ cleanup_init.o: ../../include/ext_prop.h cleanup_init.o: ../../include/flush_clnt.h cleanup_init.o: ../../include/header_body_checks.h cleanup_init.o: ../../include/header_opts.h +cleanup_init.o: ../../include/hfrom_format.h cleanup_init.o: ../../include/htable.h cleanup_init.o: ../../include/iostuff.h cleanup_init.o: ../../include/mail_addr.h @@ -1137,6 +1138,7 @@ cleanup_message.o: ../../include/dsn_util.h cleanup_message.o: ../../include/ext_prop.h cleanup_message.o: ../../include/header_body_checks.h cleanup_message.o: ../../include/header_opts.h +cleanup_message.o: ../../include/hfrom_format.h cleanup_message.o: ../../include/htable.h cleanup_message.o: ../../include/info_log_addr_form.h cleanup_message.o: ../../include/iostuff.h diff --git a/postfix/src/cleanup/cleanup.c b/postfix/src/cleanup/cleanup.c index 6ebe1b0ad..73cc03d57 100644 --- a/postfix/src/cleanup/cleanup.c +++ b/postfix/src/cleanup/cleanup.c @@ -114,6 +114,8 @@ /* .IP "\fBmessage_drop_headers (bcc, content-length, resent-bcc, return-path)\fR" /* Names of message headers that the \fBcleanup\fR(8) daemon will remove /* after applying \fBheader_checks\fR(5) and before invoking Milter applications. +/* .IP "\fBheader_from_format (standard)\fR" +/* The format of the Postfix-generated \fBFrom:\fR header. /* BUILT-IN CONTENT FILTERING CONTROLS /* .ad /* .fi diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h index 50fe6ebd0..43de26f37 100644 --- a/postfix/src/cleanup/cleanup.h +++ b/postfix/src/cleanup/cleanup.h @@ -352,9 +352,7 @@ extern void cleanup_body_edit_free(CLEANUP_STATE *); /* * From: header formatting. */ -#define HFROM_FORMAT_CODE_STD 0 -#define HFROM_FORMAT_CODE_OBS 1 -extern int hfrom_format_code; +extern int cleanup_hfrom_format; /* LICENSE /* .ad diff --git a/postfix/src/cleanup/cleanup_init.c b/postfix/src/cleanup/cleanup_init.c index d0af95477..9ae728607 100644 --- a/postfix/src/cleanup/cleanup_init.c +++ b/postfix/src/cleanup/cleanup_init.c @@ -100,6 +100,7 @@ #include /* milter_macro_v */ #include #include +#include /* Application-specific. */ @@ -282,7 +283,7 @@ MILTERS *cleanup_milters; /* * From: header format. */ -int hfrom_format_code; +int cleanup_hfrom_format; /* cleanup_all - callback for the runtime error handler */ @@ -434,11 +435,6 @@ void cleanup_pre_jail(char *unused_name, char **unused_argv) void cleanup_post_jail(char *unused_name, char **unused_argv) { - static const NAME_CODE hfrom_format_table[] = { - HFROM_FORMAT_NAME_STD, HFROM_FORMAT_CODE_STD, - HFROM_FORMAT_NAME_OBS, HFROM_FORMAT_CODE_OBS, - 0, -1, - }; /* * Optionally set the file size resource limit. XXX This limits the @@ -472,8 +468,5 @@ void cleanup_post_jail(char *unused_name, char **unused_argv) /* * From: header formatting. */ - if ((hfrom_format_code = name_code(hfrom_format_table, - NAME_CODE_FLAG_NONE, var_hfrom_format)) < 0) - msg_fatal("invalid setting: %s = %s", - VAR_HFROM_FORMAT, var_hfrom_format); + cleanup_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format); } diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index 902642f19..8fc0153fe 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -89,6 +89,7 @@ #include #include #include +#include /* Application-specific. */ @@ -760,13 +761,11 @@ static void cleanup_header_done_callback(void *context) || (cp = strchr(state->fullname, '\n')) != 0) *cp = ' '; - switch (hfrom_format_code) { - - /* - * "From: phrase ". Quote the phrase if it - * contains specials or the "%!" legacy address operators. - */ - case HFROM_FORMAT_CODE_STD: + /* + * "From: phrase ". Quote the phrase if it contains + * specials or the "%!" legacy address operators. + */ + if (cleanup_hfrom_format == HFROM_FORMAT_CODE_STD) { vstring_sprintf(state->temp2, "%sFrom: ", state->resent); if (state->fullname[strcspn(state->fullname, "%!" LEX_822_SPECIALS)] == 0) { @@ -783,22 +782,18 @@ static void cleanup_header_done_callback(void *context) } vstring_sprintf_append(state->temp2, "<%s>", vstring_str(state->temp1)); - break; + } - /* - * "From: addr-spec (ctext)". This is the obsolete form. - */ - case HFROM_FORMAT_CODE_OBS: + /* + * "From: addr-spec (ctext)". This is the obsolete form. + */ + else { vstring_sprintf(state->temp2, "%sFrom: %s ", state->resent, vstring_str(state->temp1)); vstring_sprintf(state->temp1, "(%s)", state->fullname); token = tok822_parse(vstring_str(state->temp1)); tok822_externalize(state->temp2, token, TOK822_STR_NONE); tok822_free_tree(token); - break; - default: - msg_panic("%s: unknown header format %d", - myname, hfrom_format_code); } } diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index fc5244175..fb426057a 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -37,7 +37,8 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \ mail_addr_form.c quote_flags.c maillog_client.c \ normalize_mailhost_addr.c map_search.c reject_deliver_request.c \ info_log_addr_form.c sasl_mech_filter.c login_sender_match.c \ - test_main.c compat_level.c config_known_tcp_ports.c + test_main.c compat_level.c config_known_tcp_ports.c \ + hfrom_format.c OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \ canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \ clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \ @@ -76,7 +77,8 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \ $(NON_PLUGIN_MAP_OBJ) mail_addr_form.o quote_flags.o maillog_client.o \ normalize_mailhost_addr.o map_search.o reject_deliver_request.o \ info_log_addr_form.o sasl_mech_filter.o login_sender_match.o \ - test_main.o compat_level.o config_known_tcp_ports.o + test_main.o compat_level.o config_known_tcp_ports.o \ + hfrom_format.o # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf. # When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ), # otherwise it sets the PLUGIN_* macros. @@ -112,7 +114,8 @@ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \ attr_override.h mail_parm_split.h midna_adomain.h mail_addr_form.h \ maillog_client.h normalize_mailhost_addr.h map_search.h \ info_log_addr_form.h sasl_mech_filter.h login_sender_match.h \ - test_main.h compat_level.h config_known_tcp_ports.h + test_main.h compat_level.h config_known_tcp_ports.h \ + hfrom_format.h TESTSRC = rec2stream.c stream2rec.c recdump.c DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) CFLAGS = $(DEBUG) $(OPT) $(DEFS) @@ -129,7 +132,7 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \ mail_version mail_dict server_acl uxtext mail_parm_split \ fold_addr smtp_reply_footer mail_addr_map normalize_mailhost_addr \ haproxy_srvr map_search delivered_hdr login_sender_match \ - compat_level config_known_tcp_ports + compat_level config_known_tcp_ports hfrom_format LIBS = ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX) LIB_DIR = ../../lib @@ -406,6 +409,9 @@ login_sender_match: login_sender_match.c $(LIB) $(LIBS) compat_level: compat_level.c $(LIB) $(LIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) +hfrom_format: hfrom_format.c $(LIB) $(LIBS) + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) + config_known_tcp_ports: config_known_tcp_ports.c $(LIB) $(LIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) @@ -418,7 +424,7 @@ tests: tok822_test mime_tests strip_addr_test tok822_limit_test \ mail_addr_find_test mail_addr_map_test quote_822_local_test \ normalize_mailhost_addr_test haproxy_srvr_test map_search_test \ delivered_hdr_test login_sender_match_test compat_level_test \ - config_known_tcp_ports_test + config_known_tcp_ports_test hfrom_format_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 mime_garb4 @@ -777,6 +783,13 @@ config_known_tcp_ports_test: update config_known_tcp_ports \ diff config_known_tcp_ports.ref config_known_tcp_ports.tmp rm -f config_known_tcp_ports.tmp +hfrom_format_test: update hfrom_format \ + hfrom_format.ref + -$(SHLIB_ENV) $(VALGRIND) ./hfrom_format \ + >hfrom_format.tmp 2>&1 + diff hfrom_format.ref hfrom_format.tmp + rm -f hfrom_format.tmp + printfck: $(OBJS) $(PROG) rm -rf printfck mkdir printfck @@ -1520,6 +1533,12 @@ header_token.o: ../../include/vstring.h header_token.o: header_token.c header_token.o: header_token.h header_token.o: lex_822.h +hfrom_format.o: ../../include/msg.h +hfrom_format.o: ../../include/name_code.h +hfrom_format.o: ../../include/sys_defs.h +hfrom_format.o: hfrom_format.c +hfrom_format.o: hfrom_format.h +hfrom_format.o: mail_params.h info_log_addr_form.o: ../../include/check_arg.h info_log_addr_form.o: ../../include/msg.h info_log_addr_form.o: ../../include/name_code.h diff --git a/postfix/src/global/hfrom_format.c b/postfix/src/global/hfrom_format.c new file mode 100644 index 000000000..f0f850a3e --- /dev/null +++ b/postfix/src/global/hfrom_format.c @@ -0,0 +1,281 @@ +/*++ +/* NAME +/* hfrom_format 3 +/* SUMMARY +/* Parse a header_from_format setting +/* SYNOPSIS +/* #include +/* +/* int hfrom_format_parse( +/* const char *name, +/* const char *value) +/* +/* const char *str_hfrom_format_code(int code) +/* DESCRIPTION +/* hfrom_format_parse() takes a parameter name (used for +/* diagnostics) and value, and maps it to the corresponding +/* code: HFROM_FORMAT_NAME_STD maps to HFROM_FORMAT_CODE_STD, +/* and HFROM_FORMAT_NAME_OBS maps to HFROM_FORMAT_CODE_OBS. +/* +/* str_hfrom_format_code() does the reverse mapping. +/* DIAGNOSTICS +/* All input errors are fatal. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + + /* + * System library. + */ +#include + + /* + * Utility library. + */ +#include +#include + + /* + * Global library. + */ +#include + + /* + * Application-specific. + */ +#include + + /* + * Primitive dependency injection. + */ +#ifdef TEST +extern NORETURN PRINTFLIKE(1, 2) test_msg_fatal(const char *,...); + +#define msg_fatal test_msg_fatal +#endif + + /* + * The name-to-code mapping. + */ +static const NAME_CODE hfrom_format_table[] = { + HFROM_FORMAT_NAME_STD, HFROM_FORMAT_CODE_STD, + HFROM_FORMAT_NAME_OBS, HFROM_FORMAT_CODE_OBS, + 0, -1, +}; + +/* hfrom_format_parse - parse header_from_format setting */ + +int hfrom_format_parse(const char *name, const char *value) +{ + int code; + + if ((code = name_code(hfrom_format_table, NAME_CODE_FLAG_NONE, value)) < 0) + msg_fatal("invalid setting: \"%s = %s\"", name, value); + return (code); +} + +/* str_hfrom_format_code - convert code to string */ + +const char *str_hfrom_format_code(int code) +{ + const char *name; + + if ((name = str_name_code(hfrom_format_table, code)) == 0) + msg_fatal("invalid header format code: %d", code); + return (name); +} + +#ifdef TEST +#include +#include +#include + +#include +#include +#include + +#define STR(x) vstring_str(x) + + /* + * TODO(wietse) make this a proper VSTREAM interface. Instead of temporarily + * swapping streams, we could temporarily swap the stream's write function. + */ + +/* vstream_swap - kludge to capture output for testing */ + +static void vstream_swap(VSTREAM *one, VSTREAM *two) +{ + VSTREAM save; + + save = *one; + *one = *two; + *two = save; +} + +jmp_buf test_fatal_jbuf; + +#undef msg_fatal + +/* test_msg_fatal - does not return, and does not terminate */ + +void test_msg_fatal(const char *fmt,...) +{ + va_list ap; + + va_start(ap, fmt); + vmsg_warn(fmt, ap); + va_end(ap); + longjmp(test_fatal_jbuf, 1); +} + +struct name_test_case { + const char *label; /* identifies test case */ + const char *config; /* configuration under test */ + const char *exp_warning; /* expected warning or empty */ + const int exp_code; /* expected code */ +}; + +static struct name_test_case name_test_cases[] = { + {"hfrom_format_parse good-standard", + /* config */ HFROM_FORMAT_NAME_STD, + /* warning */ "", + /* exp_code */ HFROM_FORMAT_CODE_STD + }, + {"hfrom_format_parse good-obsolete", + /* config */ HFROM_FORMAT_NAME_OBS, + /* warning */ "", + /* exp_code */ HFROM_FORMAT_CODE_OBS + }, + {"hfrom_format_parse bad", + /* config */ "does-not-exist", + /* warning */ "hfrom_format: warning: invalid setting: \"hfrom_format_parse bad = does-not-exist\"\n", + /* code */ 0, + }, + {"hfrom_format_parse empty", + /* config */ "", + /* warning */ "hfrom_format: warning: invalid setting: \"hfrom_format_parse empty = \"\n", + /* code */ 0, + }, + 0, +}; + +struct code_test_case { + const char *label; /* identifies test case */ + int code; /* code under test */ + const char *exp_warning; /* expected warning or empty */ + const char *exp_name; /* expected namme */ +}; + +static struct code_test_case code_test_cases[] = { + {"str_hfrom_format_code good-standard", + /* code */ HFROM_FORMAT_CODE_STD, + /* warning */ "", + /* exp_name */ HFROM_FORMAT_NAME_STD + }, + {"str_hfrom_format_code good-obsolete", + /* code */ HFROM_FORMAT_CODE_OBS, + /* warning */ "", + /* exp_name */ HFROM_FORMAT_NAME_OBS + }, + {"str_hfrom_format_code bad", + /* config */ 12345, + /* warning */ "hfrom_format: warning: invalid header format code: 12345\n", + /* exp_name */ 0 + }, + 0, +}; + +int main(int argc, char **argv) +{ + struct name_test_case *np; + int code; + struct code_test_case *cp; + const char *name; + int pass = 0; + int fail = 0; + int test_failed; + VSTRING *msg_buf; + VSTREAM *memory_stream; + + msg_vstream_init("hfrom_format", VSTREAM_ERR); + msg_buf = vstring_alloc(100); + + for (np = name_test_cases; np->label != 0; np++) { + VSTRING_RESET(msg_buf); + VSTRING_TERMINATE(msg_buf); + test_failed = 0; + if ((memory_stream = vstream_memopen(msg_buf, O_WRONLY)) == 0) + msg_fatal("open memory stream: %m"); + vstream_swap(VSTREAM_ERR, memory_stream); + if (setjmp(test_fatal_jbuf) == 0) + code = hfrom_format_parse(np->label, np->config); + vstream_swap(memory_stream, VSTREAM_ERR); + if (vstream_fclose(memory_stream)) + msg_fatal("close memory stream: %m"); + if (strcmp(STR(msg_buf), np->exp_warning) != 0) { + msg_warn("test case %s: got error: \"%s\", want: \"%s\"", + np->label, STR(msg_buf), np->exp_warning); + test_failed = 1; + } + if (*np->exp_warning == 0) { + if (code != np->exp_code) { + msg_warn("test case %s: got code: \"%d\", want: \"%d\"(%s)", + np->label, code, np->exp_code, + str_hfrom_format_code(np->exp_code)); + test_failed = 1; + } + } + if (test_failed) { + msg_info("%s: FAIL", np->label); + fail++; + } else { + msg_info("%s: PASS", np->label); + pass++; + } + } + + for (cp = code_test_cases; cp->label != 0; cp++) { + VSTRING_RESET(msg_buf); + VSTRING_TERMINATE(msg_buf); + test_failed = 0; + if ((memory_stream = vstream_memopen(msg_buf, O_WRONLY)) == 0) + msg_fatal("open memory stream: %m"); + vstream_swap(VSTREAM_ERR, memory_stream); + if (setjmp(test_fatal_jbuf) == 0) + name = str_hfrom_format_code(cp->code); + vstream_swap(memory_stream, VSTREAM_ERR); + if (vstream_fclose(memory_stream)) + msg_fatal("close memory stream: %m"); + if (strcmp(STR(msg_buf), cp->exp_warning) != 0) { + msg_warn("test case %s: got error: \"%s\", want: \"%s\"", + cp->label, STR(msg_buf), cp->exp_warning); + test_failed = 1; + } else if (*cp->exp_warning == 0) { + if (strcmp(name, cp->exp_name)) { + msg_warn("test case %s: got name: \"%s\", want: \"%s\"", + cp->label, name, cp->exp_name); + test_failed = 1; + } + } + if (test_failed) { + msg_info("%s: FAIL", cp->label); + fail++; + } else { + msg_info("%s: PASS", cp->label); + pass++; + } + } + + msg_info("PASS=%d FAIL=%d", pass, fail); + vstring_free(msg_buf); + exit(fail != 0); +} + +#endif diff --git a/postfix/src/global/hfrom_format.h b/postfix/src/global/hfrom_format.h new file mode 100644 index 000000000..98d3ddd8a --- /dev/null +++ b/postfix/src/global/hfrom_format.h @@ -0,0 +1,34 @@ +#ifndef _HFROM_FORMAT_INCLUDED_ +#define _HFROM_FORMAT_INCLUDED_ + +/*++ +/* NAME +/* hfrom_format 3h +/* SUMMARY +/* Parse a header_from_format setting +/* SYNOPSIS +/* #include +/* DESCRIPTION +/* .nf + + /* + * External interface. + */ +#define HFROM_FORMAT_CODE_OBS 0 /* Obsolete */ +#define HFROM_FORMAT_CODE_STD 1 /* Standard */ + +extern int hfrom_format_parse(const char *, const char *); +extern const char *str_hfrom_format_code(int); + +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + +#endif diff --git a/postfix/src/global/hfrom_format.ref b/postfix/src/global/hfrom_format.ref new file mode 100644 index 000000000..28ba8708a --- /dev/null +++ b/postfix/src/global/hfrom_format.ref @@ -0,0 +1,8 @@ +hfrom_format: hfrom_format_parse good-standard: PASS +hfrom_format: hfrom_format_parse good-obsolete: PASS +hfrom_format: hfrom_format_parse bad: PASS +hfrom_format: hfrom_format_parse empty: PASS +hfrom_format: str_hfrom_format_code good-standard: PASS +hfrom_format: str_hfrom_format_code good-obsolete: PASS +hfrom_format: str_hfrom_format_code bad: PASS +hfrom_format: PASS=7 FAIL=0 diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index c85f9e648..5649b58d8 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 "20210926" +#define MAIL_RELEASE_DATE "20211002" #define MAIL_VERSION_NUMBER "3.7" #ifdef SNAPSHOT diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in index 2d0982af3..65f41982f 100644 --- a/postfix/src/smtp/Makefile.in +++ b/postfix/src/smtp/Makefile.in @@ -103,6 +103,7 @@ smtp.o: ../../include/flush_clnt.h smtp.o: ../../include/fold_addr.h smtp.o: ../../include/header_body_checks.h smtp.o: ../../include/header_opts.h +smtp.o: ../../include/hfrom_format.h smtp.o: ../../include/htable.h smtp.o: ../../include/iostuff.h smtp.o: ../../include/mail_conf.h @@ -194,6 +195,7 @@ smtp_chat.o: ../../include/dsn_buf.h smtp_chat.o: ../../include/dsn_util.h smtp_chat.o: ../../include/header_body_checks.h smtp_chat.o: ../../include/header_opts.h +smtp_chat.o: ../../include/hfrom_format.h smtp_chat.o: ../../include/htable.h smtp_chat.o: ../../include/int_filt.h smtp_chat.o: ../../include/iostuff.h diff --git a/postfix/src/smtp/lmtp_params.c b/postfix/src/smtp/lmtp_params.c index 192d1bd21..d4ddfdb65 100644 --- a/postfix/src/smtp/lmtp_params.c +++ b/postfix/src/smtp/lmtp_params.c @@ -64,6 +64,7 @@ VAR_LMTP_DSN_FILTER, DEF_LMTP_DSN_FILTER, &var_smtp_dsn_filter, 0, 0, VAR_LMTP_DNS_RE_FILTER, DEF_LMTP_DNS_RE_FILTER, &var_smtp_dns_re_filter, 0, 0, VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0, + VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0, 0, }; static const CONFIG_TIME_TABLE lmtp_time_table[] = { @@ -128,7 +129,7 @@ VAR_LMTP_BALANCE_INET_PROTO, DEF_LMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto, 0, }; - static const CONFIG_NBOOL_TABLE lmtp_nbool_table[] = { + static const CONFIG_NBOOL_TABLE lmtp_nbool_table[] = { VAR_LMTP_REQ_DEADLINE, DEF_LMTP_REQ_DEADLINE, &var_smtp_req_deadline, 0, - }; + }; diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index c5088798c..60c8fe95e 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -350,6 +350,8 @@ /* .IP "\fBsmtp_min_data_rate (500)\fR" /* The minimum plaintext data transfer rate in bytes/second for /* DATA requests, when deadlines are enabled with smtp_per_request_deadline. +/* .IP "\fBheader_from_format (standard)\fR" +/* The format of the Postfix-generated \fBFrom:\fR header. /* MIME PROCESSING CONTROLS /* .ad /* .fi @@ -941,6 +943,7 @@ #include #include #include +#include /* DNS library. */ @@ -1083,6 +1086,8 @@ char *var_smtp_sasl_auth_cache_name; int var_smtp_sasl_auth_cache_time; bool var_smtp_sasl_auth_soft_bounce; +char *var_hfrom_format; + /* * Global variables. */ @@ -1099,6 +1104,7 @@ MAPS *smtp_pix_bug_maps; HBC_CHECKS *smtp_header_checks; /* limited header checks */ HBC_CHECKS *smtp_body_checks; /* limited body checks */ SMTP_CLI_ATTR smtp_cli_attr; /* parsed command-line */ +int smtp_hfrom_format; /* postmaster notifications */ #ifdef USE_TLS @@ -1384,6 +1390,11 @@ static void post_init(char *unused_name, char **argv) * the process lifetime. */ get_cli_attr(&smtp_cli_attr, argv); + + /* + * header_from format, for postmaster notifications. + */ + smtp_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format); } /* pre_init - pre-jail initialization */ @@ -1618,7 +1629,7 @@ int main(int argc, char **argv) CA_MAIL_SERVER_BOOL_TABLE(smtp_mode ? smtp_bool_table : lmtp_bool_table), CA_MAIL_SERVER_NBOOL_TABLE(smtp_mode ? - smtp_nbool_table : lmtp_nbool_table), + smtp_nbool_table : lmtp_nbool_table), CA_MAIL_SERVER_PRE_INIT(pre_init), CA_MAIL_SERVER_POST_INIT(post_init), CA_MAIL_SERVER_PRE_ACCEPT(pre_accept), diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h index e8c994fbf..07b3b3a81 100644 --- a/postfix/src/smtp/smtp.h +++ b/postfix/src/smtp/smtp.h @@ -731,6 +731,11 @@ extern void smtp_rewrite_generic_internal(VSTRING *, const char *); extern void smtp_quote_822_address_flags(VSTRING *, const char *, int); extern void smtp_quote_821_address(VSTRING *, const char *); + /* + * header_from_format support, for postmaster notifications. + */ +extern int smtp_hfrom_format; + /* LICENSE /* .ad /* .fi diff --git a/postfix/src/smtp/smtp_chat.c b/postfix/src/smtp/smtp_chat.c index bff5986ed..81c63e478 100644 --- a/postfix/src/smtp/smtp_chat.c +++ b/postfix/src/smtp/smtp_chat.c @@ -140,6 +140,7 @@ #include #include #include +#include /* Application-specific. */ @@ -474,9 +475,15 @@ void smtp_chat_notify(SMTP_SESSION *session) msg_warn("postmaster notify: %m"); return; } - post_mail_fprintf(notice, "From: %s (Mail Delivery System)", - mail_addr_mail_daemon()); - post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt); + if (smtp_hfrom_format == HFROM_FORMAT_CODE_STD) { + post_mail_fprintf(notice, "From: Mail Delivery System <%s>", + mail_addr_mail_daemon()); + post_mail_fprintf(notice, "To: Postmaster <%s>", var_error_rcpt); + } else { + post_mail_fprintf(notice, "From: %s (Mail Delivery System)", + mail_addr_mail_daemon()); + post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt); + } post_mail_fprintf(notice, "Subject: %s %s client: errors from %s", var_mail_name, smtp_mode ? "SMTP" : "LMTP", session->namaddrport); diff --git a/postfix/src/smtp/smtp_params.c b/postfix/src/smtp/smtp_params.c index 493bfada1..ef65bc547 100644 --- a/postfix/src/smtp/smtp_params.c +++ b/postfix/src/smtp/smtp_params.c @@ -65,6 +65,7 @@ VAR_SMTP_DSN_FILTER, DEF_SMTP_DSN_FILTER, &var_smtp_dsn_filter, 0, 0, VAR_SMTP_DNS_RE_FILTER, DEF_SMTP_DNS_RE_FILTER, &var_smtp_dns_re_filter, 0, 0, VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0, + VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0, 0, }; static const CONFIG_TIME_TABLE smtp_time_table[] = { @@ -132,7 +133,7 @@ VAR_SMTP_BALANCE_INET_PROTO, DEF_SMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto, 0, }; - static const CONFIG_NBOOL_TABLE smtp_nbool_table[] = { + static const CONFIG_NBOOL_TABLE smtp_nbool_table[] = { VAR_SMTP_REQ_DEADLINE, DEF_SMTP_REQ_DEADLINE, &var_smtp_req_deadline, 0, - }; + }; diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index 332d10f8c..8c4132a30 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -193,6 +193,7 @@ smtpd.o: ../../include/dsn_mask.h smtpd.o: ../../include/ehlo_mask.h smtpd.o: ../../include/events.h smtpd.o: ../../include/flush_clnt.h +smtpd.o: ../../include/hfrom_format.h smtpd.o: ../../include/htable.h smtpd.o: ../../include/inet_proto.h smtpd.o: ../../include/info_log_addr_form.h @@ -268,6 +269,7 @@ smtpd_chat.o: ../../include/check_arg.h smtpd_chat.o: ../../include/cleanup_user.h smtpd_chat.o: ../../include/dict.h smtpd_chat.o: ../../include/dns.h +smtpd_chat.o: ../../include/hfrom_format.h smtpd_chat.o: ../../include/htable.h smtpd_chat.o: ../../include/int_filt.h smtpd_chat.o: ../../include/iostuff.h diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 7a51de674..4f59dcae0 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -788,6 +788,8 @@ /* The minimum plaintext data transfer rate in bytes/second for /* DATA and BDAT requests, when deadlines are enabled with /* smtpd_per_request_deadline. +/* .IP "\fBheader_from_format (standard)\fR" +/* The format of the Postfix-generated \fBFrom:\fR header. /* TARPIT CONTROLS /* .ad /* .fi @@ -1264,6 +1266,7 @@ #include #include #include +#include /* Single-threaded server skeleton. */ @@ -1493,6 +1496,7 @@ int var_smtpd_uproxy_tmout; bool var_relay_before_rcpt_checks; bool var_smtpd_req_deadline; int var_smtpd_min_data_rate; +char *var_hfrom_format; /* * Silly little macros. @@ -1586,6 +1590,11 @@ static int ask_client_cert; */ static DICT *smtpd_cmd_filter; + /* + * Parsed header_from_format setting. + */ +int smtpd_hfrom_format; + #ifdef USE_SASL_AUTH /* @@ -6362,6 +6371,11 @@ static void post_jail_init(char *unused_name, char **unused_argv) || var_smtpd_cmail_limit || var_smtpd_crcpt_limit || var_smtpd_cntls_limit || var_smtpd_cauth_limit) anvil_clnt = anvil_clnt_create(); + + /* + * header_from_format support, for postmaster notifications. + */ + smtpd_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format); } MAIL_VERSION_STAMP_DECLARE; @@ -6580,6 +6594,7 @@ int main(int argc, char **argv) VAR_SMTPD_POLICY_CONTEXT, DEF_SMTPD_POLICY_CONTEXT, &var_smtpd_policy_context, 0, 0, VAR_SMTPD_DNS_RE_FILTER, DEF_SMTPD_DNS_RE_FILTER, &var_smtpd_dns_re_filter, 0, 0, VAR_SMTPD_REJ_FTR_MAPS, DEF_SMTPD_REJ_FTR_MAPS, &var_smtpd_rej_ftr_maps, 0, 0, + VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0, 0, }; static const CONFIG_RAW_TABLE raw_table[] = { diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 490cda2fa..0bb5bbbce 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -417,6 +417,11 @@ extern MILTERS *smtpd_milters; */ extern double smtpd_space_multf; + /* + * header_from_format support. + */ +extern int smtpd_hfrom_format; + /* LICENSE /* .ad /* .fi diff --git a/postfix/src/smtpd/smtpd_chat.c b/postfix/src/smtpd/smtpd_chat.c index c172ab3d1..278e5362a 100644 --- a/postfix/src/smtpd/smtpd_chat.c +++ b/postfix/src/smtpd/smtpd_chat.c @@ -103,6 +103,7 @@ #include #include #include +#include /* Application-specific. */ @@ -324,9 +325,15 @@ void smtpd_chat_notify(SMTPD_STATE *state) msg_warn("postmaster notify: %m"); return; } - post_mail_fprintf(notice, "From: %s (Mail Delivery System)", - mail_addr_mail_daemon()); - post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt); + if (smtpd_hfrom_format == HFROM_FORMAT_CODE_STD) { + post_mail_fprintf(notice, "From: Mail Delivery System <%s>", + mail_addr_mail_daemon()); + post_mail_fprintf(notice, "To: Postmaster <%s>", var_error_rcpt); + } else { + post_mail_fprintf(notice, "From: %s (Mail Delivery System)", + mail_addr_mail_daemon()); + post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt); + } post_mail_fprintf(notice, "Subject: %s SMTP server: errors from %s", var_mail_name, state->namaddr); post_mail_fputs(notice, "");