From: Wietse Venema Date: Sun, 26 May 2002 05:00:00 +0000 (-0500) Subject: postfix-1.1.10-20020526 X-Git-Tag: v2.0.0~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0fdef374f4df2547981fc1ce6a4106a0234f1eca;p=thirdparty%2Fpostfix.git postfix-1.1.10-20020526 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 038af233c..3eef83492 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -6458,6 +6458,11 @@ Apologies for any names omitted. at the time that the SMTP client could suffer from a similar problem. +20020516 + + Updated the FILTER_README file to turn off DNS lookups in + the SMTP client that feeds mail into a content filter. + 20020517 Cleanup: Mailbox-Line: message header labels should be @@ -6465,12 +6470,15 @@ Apologies for any names omitted. 20020515-21 - Feature: new MIME parser, written from scratch, that recognizes - the structure of MIME encapsulated mail. MIME header scanning - now happens in header_checks, and are is faster than - body_checks could ever be. Thus also eliminates the problem - with multi-line MIME headers being matched one line at a - time. Files: global/mime_state.[hc], cleanup/cleanup_message.c. + Feature: new MIME parser, written from scratch, that + recognizes the structure of MIME encapsulated mail. Influenced + by comments from Victor Duchovny. This code can detect but + will not fix illegal MIME encapsulations that Liviu Daia + expresses concern about. MIME header scanning now happens + in header_checks, and is faster than body_checks could ever + be. Thus also eliminates the problem with multi-line MIME + headers being matched one line at a time. Files: + global/mime_state.[hc], cleanup/cleanup_message.c. 20020521-22 @@ -6478,22 +6486,54 @@ Apologies for any names omitted. the Postfix SMTP client. File: smtp/smtp_proto.c. Logging: the Postfix SMTP and LMTP clients now report the - stage of the protocol when it reports a server reply. + stage of the protocol when they report a server reply. File: smtp/smtp_proto.c, lmtp/lmtp_proto.c. - Bugfix: the SMTP server complained about ignored client - attributes in mail submitted with "sendmail -bs". - File: smtpd/smtpd.c. + Bugfix: the SMTP server warned about ignored client + attributes (introduced in 20020510) in mail submitted with + "sendmail -bs". File: smtpd/smtpd.c. 20020525 + Feature: separation of header checks into header_checks + (all primary headers except MIME related headers), + mime_header_checks (all MIME headers including MIME headers + at the start of messages) and nested_header_checks (headers + of attached messages, except MIME related headers). + Cleanup: broke out the header value parser from the MIME - processor so it can be used elsewhere. File: + processor so that the code can be reused elsewhere. File: global/header_token.c. - Cleanup needs an option to revert to old non-MIME - aware behavior - this must override the MIME header - match override. + Compatibility: Postfix now recognizes "name :" as a valid + message header, but normalizes it to "name:" form or else + lots of things would break all over the place. Files: + global/is_header.c, global/mime_state.c. + +20020526 + + Bugfix: the SMTP server now disallows RCPT TO:<"">, just + like it disallows RCPT TO:<>. File: smtpd/smtpd.c. + + Feature: disable_mime_input_processing=yes/no controls + whether Postfix recognizes (and optionally enforces) MIME + formats while receiving mail. Default is NO. + + Feature: disable_mime_output_conversion=yes/no controls + whether Postfix will convert 8BITMIME to 7BIT mail when + delivering to an SMTP server that does not announce 8BITMIME. + Default is NO. + + Feature: strict_8bitmime=yes/no controls whether Postfix + rejects 8-bit characters in headers and 7-bit body parts. + This blocks mail from poorly written software, as well as + mail that is piped into ancient /bin/mail implementations + that do not MIME format 8-bit content. Default is NO. + + Feature: strict_mime_encoding_domain=yes/no controls whether + Postfix rejects illegal content transfer encodings for + multipart/* and message/*. This blocks mail from poorly + written software. Default is NO. Open problems: diff --git a/postfix/README_FILES/FILTER_README b/postfix/README_FILES/FILTER_README index 20c71cb30..ff062e8b7 100644 --- a/postfix/README_FILES/FILTER_README +++ b/postfix/README_FILES/FILTER_README @@ -130,9 +130,10 @@ machine runs into a resource problem. This approach uses content filtering software that can receive and deliver mail via SMTP. You can expect to lose about a factor of two in Postfix performance -for transit mail (not delivered on the same machine) that arrives -and leaves via SMTP; and each temporary file created by the content -filter adds another factor to the performance loss. +for transit mail that arrives and leaves via SMTP, provided that +the content filter creates no temporary files. Each temporary file +created by the content filter adds another factor to the performance +loss. We will set up a content filtering program that receives SMTP mail via localhost port 10025, and that submits SMTP mail back into @@ -386,6 +387,8 @@ localhost:10026 inet n - n - - smtpd # cleanup2 unix n - n - 0 cleanup -o header_checks= + -o mime_header_checks= + -o nested_header_checks= -o body_checks= # # The normal "smtp" delivery agent for contrast with "scan". diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index afeb1fc9a..6c7fe2a1b 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -12,12 +12,47 @@ snapshot release). Patches change the patchlevel and the release date. Snapshots change only the release date, unless they include the same bugfixes as a patch release. -Incompatible changes with Postfix snapshot 1.1.10-200205XX +Incompatible changes with Postfix snapshot 1.1.10-20020526 ========================================================== -Message headers in MIME attachments etc. are now matched by -header_checks instead of body_checks. Multi-line headers in MIME -attachments are now properly recognized. +Message headers in MIME attachments etc. are no longer matched by +body_checks, one input line at a time. They are now by default +matched by header_checks, one multi-line header at a time. To get +the old behavior, specify "disable_mime_input_processing = yes". + +Postfix rejects mail if the MIME multipart structure is nested more +than mime_nesting_limit levels (default: 20) while receiving mail, +or when Postfix is performing 8BITMIME to 7BIT conversion while +delivering mail. + +Postfix now recognizes "name :" as a valid message header, but +normalizes it to "name:" for consistency (actually, there is so +much code in Postfix that would break with "name :" that there +is little choice, except to not recognize "name :" headers). + +Major changes with Postfix snapshot 1.1.10-20020526 +=================================================== + +Postfix now properly recognizes MIME headers in attachments, which +is much more efficient than recognizing them via body_checks. In +fact, Postfix now has three classes of header patterns: header_checks +(for primary message headers except MIME headers), mime_header_checks +(for MIME headers), and nested_header_checks (for headers of attached +email messages except MIME headers). By default, all headers are +matched with header_checks. To revert to the the old behavior, +specify "disable_mime_input_processing = yes". More details in +conf/sample-filter.cf. + +The Postfix SMTP client will now convert 8BITMIME mail to 7BIT when +delivering to an SMTP server that does not announce 8BITMIME support. +To disable, specify "disable_mime_output_conversion = yes". However, +this conversion is required by RFC standards. + +Postfix can enforce some aspects of the MIME standards while +receiving mail. Specify "strict_8bitmime = yes" to disallow 8-bit +characters except where allowed by the MIME standard, and specify +"strict_mime_encoding_domain = yes" to block mail from poorly +written mail software. More details in conf/sample-mime.cf. Incompatible changes with Postfix snapshot 1.1.10-20020514 ========================================================== diff --git a/postfix/conf/main.cf b/postfix/conf/main.cf index ed330c676..9ac147d56 100644 --- a/postfix/conf/main.cf +++ b/postfix/conf/main.cf @@ -419,7 +419,9 @@ mail_owner = postfix # WARN the header is logged (not rejected) with a warning message. # WARN text... as above, and the text is logged, too. # -# These patterns do not apply to MIME headers in the message body. +# By default, these patterns also apply to MIME headers and to the +# headers of attached messages. With older Postfix versions, MIME and +# attached message headers were treated as body text. # # See also the body_checks example in the sample-filter.cf file. # diff --git a/postfix/conf/postfix-files b/postfix/conf/postfix-files index 095d61654..4bc0d72fe 100644 --- a/postfix/conf/postfix-files +++ b/postfix/conf/postfix-files @@ -151,6 +151,7 @@ $sample_directory/sample-flush.cf:f:root:-:644 $sample_directory/sample-ldap.cf:f:root:-:644 $sample_directory/sample-lmtp.cf:f:root:-:644 $sample_directory/sample-local.cf:f:root:-:644 +$sample_directory/sample-mime.cf:f:root:-:644 $sample_directory/sample-misc.cf:f:root:-:644 $sample_directory/sample-pcre-access.cf:f:root:-:644 $sample_directory/sample-pcre-body.cf:f:root:-:644 diff --git a/postfix/conf/sample-filter.cf b/postfix/conf/sample-filter.cf index ce154d2f7..ded983fd6 100644 --- a/postfix/conf/sample-filter.cf +++ b/postfix/conf/sample-filter.cf @@ -17,10 +17,50 @@ # WARN the header is logged (not rejected) with a warning message. # WARN text... as above, and the text is logged, too. # -# These patterns do not apply to MIME headers in the message body. +# By default, these patterns apply the primary message headers, to +# MIME headers, and to the headers of attached messages. With older +# Postfix versions, MIME and attached message headers were treated +# as body text. # header_checks = regexp:/etc/postfix/header_checks +# The mime_header_checks specifies an optional table with patterns +# that each MIME header is matched against. This applies to MIME +# related headers in message headers, and to the headers that follow +# multipart boundary strings. Headers may span multiple physical lines. +# Patterns are matched in the specified order, and the search stops +# upon the first match. When a pattern matches, what happens next +# depends on the associated action that is specified in the right-hand +# side of the table: +# +# REJECT the entire message is rejected. +# REJECT text.... The text is sent to the originator. +# IGNORE the header line is silently discarded. +# WARN the header is logged (not rejected) with a warning message. +# WARN text... as above, and the text is logged, too. +# +# By default, the same patterns are applied as for header_checks. +# +mime_header_checks = $header_checks + +# The nested_header_checks specifies an optional table with patterns +# that each attached message header is matched against (except for +# MIME related headers). Headers may span multiple physical lines. +# Patterns are matched in the specified order, and the search stops +# upon the first match. When a pattern matches, what happens next +# depends on the associated action that is specified in the right-hand +# side of the table: +# +# REJECT the entire message is rejected. +# REJECT text.... The text is sent to the originator. +# IGNORE the header line is silently discarded. +# WARN the header is logged (not rejected) with a warning message. +# WARN text... as above, and the text is logged, too. +# +# By default, the same patterns are applied as for header_checks. +# +nested_header_checks = $header_checks + # The body_checks parameter specifies an optional table with patterns # that each physical line in the message body is matched against # (including MIME headers inside the message body - Postfix does not diff --git a/postfix/conf/sample-mime.cf b/postfix/conf/sample-mime.cf new file mode 100644 index 000000000..b8c59291d --- /dev/null +++ b/postfix/conf/sample-mime.cf @@ -0,0 +1,57 @@ +# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF +# HERE JUST SERVES AS AN EXAMPLE. +# +# This file contains example settings of Postfix configuration +# parameters that control MIME processing. + +# Specify "yes" to disable special processing of Content-Type: headers +# while receiving mail. This treats all text after the primary mail +# headers as message body text, and disables the optional features +# below that enforce some aspects of MIME standards. +# +disable_mime_input_processing = no + +# Specify "yes" to disable special processing of Content-Type: headers +# while delivering mail. This treats all text after the primary mail +# headers as message body text, and disables 8BITMIME to 7BIT conversion +# when delivering mail to an SMTP server that does not announce +# 8BITMIME support. +# +disable_mime_output_conversion = no + +# Specify the amount of space that will be allocated for MIME multipart +# boundary strings. The MIME processor is unable to distinguish +# between boundary strings that are identical in the first +# $mime_boundary_length_limit characters. The default limit is the +# input line length limit. +# +mime_boundary_length_limit = 2048 + +# Specify the maximal nesting level of multipart mail that the MIME +# processor can handle. Refuse mail that is nested deeper while +# receiving mail, or when converting 8BITMIME to 7BIT while delivering +# mail. +# +mime_nesting_limit = 20 + +# Specify "yes" to reject mail with 8-bit text in message headers, +# and with 8-bit text in message bodies that either claim to be 7-bit +# format or that default to 7-bit format. This optional restriction +# is enforced while receiving mail. +# +# This blocks mail from poorly written mail software. Unfortunately, +# this also blocks approval requests from Majordomo when the included +# request contains valid 8-bit MIME mail, and it may block 8-bit mail +# that is piped into /bin/mail or other MIME challenged software. +# +strict_8bitmime = no + +# Specify "yes" to reject mail with invalid Content-Transfer-Encoding: +# information for multipart/* or message/* content (in general, only +# the unity transformations 7bin, 8bit or binary are allowed at those +# levels in the message structure). This optional restriction is +# enforced while receiving mail. +# +# This blocks mail from poorly written mail software. +# +strict_mime_domain_encoding = no diff --git a/postfix/html/cleanup.8.html b/postfix/html/cleanup.8.html index 4cd6c253b..ba7f6eb63 100644 --- a/postfix/html/cleanup.8.html +++ b/postfix/html/cleanup.8.html @@ -90,9 +90,42 @@ CLEANUP(8) CLEANUP(8) sages. These filters see logical headers one at a time, including headers that span multiple lines. +MIME Processing + disable_mime_input_processing + While receiving, give no special treatment to Con- + tent-Type: message headers; all text after the ini- + tial message headers is considered to be part of + the message body. + + mime_boundary_length_limit + The amount of space that will be allocated for MIME + multipart boundary strings. The MIME processor is + unable to distinguish between boundary strings that + do not differ in the first $mime_bound- + ary_length_limit characters. + + mime_nesting_limit + The maximal nesting level of multipart mail that + the MIME processor can handle. Refuse mail that is + nested deeper. + + strict_8bitmime + Reject mail with 8-bit text in message headers, and + with 8-bit text in content that claims to be 7-bit, + or that has no explicit content encoding informa- + tion. This blocks mail mail poorly written mail + software. Unfortunately, this also breaks majordomo + approval requests when the included request con- + tains valid 8-bit MIME mail. + + strict_mime_domain_encoding + Reject mail with invalid Content-Transfer-Encoding: + information for message/* or multipart/*. This + blocks mail from poorly written software. + Miscellaneous always_bcc - Address to send a copy of each message that enters + Address to send a copy of each message that enters the system. hopcount_limit @@ -105,8 +138,8 @@ CLEANUP(8) CLEANUP(8) Address transformations empty_address_recipient - The destination for undeliverable mail from <>. - This substitution is done before all other address + The destination for undeliverable mail from <>. + This substitution is done before all other address rewriting. canonical_maps @@ -122,16 +155,16 @@ CLEANUP(8) CLEANUP(8) header sender addresses. masquerade_classes - List of address classes subject to masquerading: - zero or more of envelope_sender, envelope_recipi- + List of address classes subject to masquerading: + zero or more of envelope_sender, envelope_recipi- ent, header_sender, header_recipient. masquerade_domains - List of domains that hide their subdomain struc- + List of domains that hide their subdomain struc- ture. masquerade_exceptions - List of user names that are not subject to address + List of user names that are not subject to address masquerading. virtual_maps @@ -140,7 +173,7 @@ CLEANUP(8) CLEANUP(8) Resource controls duplicate_filter_limit - Limit the number of envelope recipients that are + Limit the number of envelope recipients that are remembered. header_size_limit @@ -149,11 +182,11 @@ CLEANUP(8) CLEANUP(8) in_flow_delay Amount of time to pause before accepting a message, - when the message arrival rate exceeds the message + when the message arrival rate exceeds the message delivery rate. extract_recipient_limit - Limit the amount of recipients extracted from mes- + Limit the amount of recipients extracted from mes- sage headers. SEE ALSO @@ -168,7 +201,7 @@ CLEANUP(8) CLEANUP(8) /etc/postfix/virtual*, virtual mapping table LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index f0be0c1da..ff460841c 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -152,15 +152,34 @@ SMTP(8) SMTP(8) PIX firewall <CR><LF>.<CR><LF> bug workaround is turned on. +MIME Conversion + disable_mime_output_conversion + Disable the conversion of 8BITMIME format to 7BIT + format when the remote system does not advertise + 8BITMIME support. + + mime_boundary_length_limit + The amount of space that will be allocated for MIME + multipart boundary strings. The MIME processor is + unable to distinguish between boundary strings that + do not differ in the first $mime_bound- + ary_length_limit characters. + + mime_nesting_limit + The maximal nesting level of multipart mail that + the MIME processor can handle. Refuse mail that is + nested deeper, when converting from 8BITMIME format + to 7BIT format. + Authentication controls smtp_sasl_auth_enable - Enable per-session authentication as per RFC 2554 - (SASL). By default, Postfix is built without SASL + Enable per-session authentication as per RFC 2554 + (SASL). By default, Postfix is built without SASL support. smtp_sasl_password_maps Lookup tables with per-host or domain name:password - entries. No entry for a host means no attempt to + entries. No entry for a host means no attempt to authenticate. smtp_sasl_security_options @@ -184,47 +203,47 @@ SMTP(8) SMTP(8) Resource controls smtp_destination_concurrency_limit Limit the number of parallel deliveries to the same - destination. The default limit is taken from the + destination. The default limit is taken from the default_destination_concurrency_limit parameter. smtp_destination_recipient_limit - Limit the number of recipients per message deliv- - ery. The default limit is taken from the + Limit the number of recipients per message deliv- + ery. The default limit is taken from the default_destination_recipient_limit parameter. Timeout controls - The default time unit is seconds; an explicit time unit - can be specified by appending a one-letter suffix to the - value: s (seconds), m (minutes), h (hours), d (days) or w + The default time unit is seconds; an explicit time unit + can be specified by appending a one-letter suffix to the + value: s (seconds), m (minutes), h (hours), d (days) or w (weeks). smtp_connect_timeout - Timeout for completing a TCP connection. When no - connection can be made within the deadline, the - SMTP client tries the next address on the mail + Timeout for completing a TCP connection. When no + connection can be made within the deadline, the + SMTP client tries the next address on the mail exchanger list. smtp_helo_timeout - Timeout for receiving the SMTP greeting banner. - When the server drops the connection without send- + Timeout for receiving the SMTP greeting banner. + When the server drops the connection without send- ing a greeting banner, or when it sends no greeting - banner within the deadline, the SMTP client tries + banner within the deadline, the SMTP client tries the next address on the mail exchanger list. smtp_helo_timeout - Timeout for sending the HELO command, and for + Timeout for sending the HELO command, and for receiving the server response. smtp_mail_timeout - Timeout for sending the MAIL FROM command, and for + Timeout for sending the MAIL FROM command, and for receiving the server response. smtp_rcpt_timeout - Timeout for sending the RCPT TO command, and for + Timeout for sending the RCPT TO command, and for receiving the server response. smtp_data_init_timeout - Timeout for sending the DATA command, and for + Timeout for sending the DATA command, and for receiving the server response. smtp_data_xfer_timeout @@ -232,12 +251,12 @@ SMTP(8) SMTP(8) smtp_data_done_timeout Timeout for sending the "." command, and for - receiving the server response. When no response is - received, a warning is logged that the mail may be + receiving the server response. When no response is + received, a warning is logged that the mail may be delivered multiple times. smtp_quit_timeout - Timeout for sending the QUIT command, and for + Timeout for sending the QUIT command, and for receiving the server response. SEE ALSO @@ -247,7 +266,7 @@ SMTP(8) SMTP(8) syslogd(8) system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/uce.html b/postfix/html/uce.html index 47c5f44f0..9792e885d 100644 --- a/postfix/html/uce.html +++ b/postfix/html/uce.html @@ -99,7 +99,14 @@ restrictions The header_checks parameter restricts what is allowed in message headers. Patterns are applied to entire logical message -headers, even when a header spans multiple lines of text. +headers, even when a header spans multiple lines of text. + +

+ +By default, the same header_checks patterns are used for +primary message headers, for MIME headers (including headers at +the start of multipart body parts), and for the headers at the +beginning of attached email messages.

@@ -163,8 +170,7 @@ mail still to be rejected.

Body filtering

The body_checks parameter restricts what text is -is allowed in message body lines (including MIME headers -within the message body). +is allowed in message body lines.

diff --git a/postfix/man/man8/cleanup.8 b/postfix/man/man8/cleanup.8 index 826372d94..835335451 100644 --- a/postfix/man/man8/cleanup.8 +++ b/postfix/man/man8/cleanup.8 @@ -90,6 +90,32 @@ respectively, these are applied to the primary message headers the message, and to the initial headers of attached messages. These filters see logical headers one at a time, including headers that span multiple lines. +.SH MIME Processing +.ad +.fi +.IP \fBdisable_mime_input_processing\fR +While receiving, give no special treatment to \fBContent-Type:\fR +message headers; all text after the initial message headers is +considered to be part of the message body. +.IP \fBmime_boundary_length_limit\fR +The amount of space that will be allocated for MIME multipart +boundary strings. The MIME processor is unable to distinguish +between boundary strings that do not differ in the first +\fB$mime_boundary_length_limit\fR characters. +.IP \fBmime_nesting_limit\fR +The maximal nesting level of multipart mail that the MIME +processor can handle. Refuse mail that is nested deeper. +.IP \fBstrict_8bitmime\fR +Reject mail with 8-bit text in message headers, and with +8-bit text in content that claims to be 7-bit, or that has +no explicit content encoding information. This blocks mail +mail poorly written mail software. Unfortunately, this also +breaks majordomo approval requests when the included request +contains valid 8-bit MIME mail. +.IP \fBstrict_mime_domain_encoding\fR +Reject mail with invalid \fBContent-Transfer-Encoding:\fR +information for message/* or multipart/*. This blocks mail +from poorly written software. .SH Miscellaneous .ad .fi diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index 2e5f87ef8..a17ba48f7 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -134,6 +134,19 @@ around the CISCO PIX firewall . bug. .IP \fBsmtp_pix_workaround_threshold_time\fR The time a message must be queued before the CISCO PIX firewall . bug workaround is turned on. +.SH "MIME Conversion" +.IP \fBdisable_mime_output_conversion\fR +Disable the conversion of 8BITMIME format to 7BIT format when +the remote system does not advertise 8BITMIME support. +.IP \fBmime_boundary_length_limit\fR +The amount of space that will be allocated for MIME multipart +boundary strings. The MIME processor is unable to distinguish +between boundary strings that do not differ in the first +\fB$mime_boundary_length_limit\fR characters. +.IP \fBmime_nesting_limit\fR +The maximal nesting level of multipart mail that the MIME +processor can handle. Refuse mail that is nested deeper, +when converting from 8BITMIME format to 7BIT format. .SH "Authentication controls" .IP \fBsmtp_sasl_auth_enable\fR Enable per-session authentication as per RFC 2554 (SASL). diff --git a/postfix/src/cleanup/cleanup.c b/postfix/src/cleanup/cleanup.c index b82782cd6..cdc395568 100644 --- a/postfix/src/cleanup/cleanup.c +++ b/postfix/src/cleanup/cleanup.c @@ -76,6 +76,32 @@ /* the message, and to the initial headers of attached messages. /* These filters see logical headers one at a time, including headers /* that span multiple lines. +/* .SH MIME Processing +/* .ad +/* .fi +/* .IP \fBdisable_mime_input_processing\fR +/* While receiving, give no special treatment to \fBContent-Type:\fR +/* message headers; all text after the initial message headers is +/* considered to be part of the message body. +/* .IP \fBmime_boundary_length_limit\fR +/* The amount of space that will be allocated for MIME multipart +/* boundary strings. The MIME processor is unable to distinguish +/* between boundary strings that do not differ in the first +/* \fB$mime_boundary_length_limit\fR characters. +/* .IP \fBmime_nesting_limit\fR +/* The maximal nesting level of multipart mail that the MIME +/* processor can handle. Refuse mail that is nested deeper. +/* .IP \fBstrict_8bitmime\fR +/* Reject mail with 8-bit text in message headers, and with +/* 8-bit text in content that claims to be 7-bit, or that has +/* no explicit content encoding information. This blocks mail +/* mail poorly written mail software. Unfortunately, this also +/* breaks majordomo approval requests when the included request +/* contains valid 8-bit MIME mail. +/* .IP \fBstrict_mime_domain_encoding\fR +/* Reject mail with invalid \fBContent-Transfer-Encoding:\fR +/* information for message/* or multipart/*. This blocks mail +/* from poorly written software. /* .SH Miscellaneous /* .ad /* .fi diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h index a0e3b1df6..7e20ce46a 100644 --- a/postfix/src/cleanup/cleanup.h +++ b/postfix/src/cleanup/cleanup.h @@ -66,8 +66,6 @@ typedef struct CLEANUP_STATE { int mime_errs; /* MIME error flags */ } CLEANUP_STATE; -#define CLEANUP_CURR_HEADERS (1<<0) /* in main headers section */ - /* * Mappings. */ diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index c2d1eeed6..dab5373d1 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -160,7 +160,6 @@ static void cleanup_rewrite_sender(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts, TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; - char *addr; if (msg_verbose) msg_info("rewrite_sender: %s", hdr_opts->name); @@ -170,11 +169,8 @@ static void cleanup_rewrite_sender(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts, * sender addresses, and regenerate the header line. Finally, pipe the * result through the header line folding routine. */ -#define SKIP_HEADER_THRASH(cp) { while (ISSPACE(*cp)) cp++; cp++; } - - addr = vstring_str(header_buf) + strlen(hdr_opts->name); - SKIP_HEADER_THRASH(addr); - tree = tok822_parse(addr); + tree = tok822_parse(vstring_str(header_buf) + + strlen(hdr_opts->name) + 1); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { cleanup_rewrite_tree(*tpp); @@ -216,7 +212,6 @@ static void cleanup_rewrite_recip(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts, TOK822 **addr_list; TOK822 **tpp; ARGV *rcpt; - char *addr; if (msg_verbose) msg_info("rewrite_recip: %s", hdr_opts->name); @@ -226,9 +221,8 @@ static void cleanup_rewrite_recip(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts, * recipient addresses, and regenerate the header line. Finally, pipe the * result through the header line folding routine. */ - addr = vstring_str(header_buf) + strlen(hdr_opts->name); - SKIP_HEADER_THRASH(addr); - tree = tok822_parse(addr); + tree = tok822_parse(vstring_str(header_buf) + + strlen(hdr_opts->name) + 1); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { cleanup_rewrite_tree(*tpp); @@ -352,7 +346,7 @@ static void cleanup_header_callback(void *context, int header_class, header_class = MIME_HDR_MULTIPART; if ((state->flags & CLEANUP_FLAG_FILTER) - && (CHECK(MIME_HDR_PRIMARY, cleanup_header_checks, VAR_HEADER_CHECKS) + && (CHECK(MIME_HDR_PRIMARY, cleanup_header_checks, VAR_HEADER_CHECKS) || CHECK(MIME_HDR_MULTIPART, cleanup_mimehdr_checks, VAR_MIMEHDR_CHECKS) || CHECK(MIME_HDR_NESTED, cleanup_nesthdr_checks, VAR_NESTHDR_CHECKS))) { char *header = vstring_str(header_buf); @@ -379,14 +373,14 @@ static void cleanup_header_callback(void *context, int header_class, * Allow 8-bit type info to override 7-bit type info. XXX Should reuse * the effort that went into MIME header parsing. */ - hdrval = vstring_str(header_buf) + strlen(hdr_opts->name); - SKIP_HEADER_THRASH(hdrval); + hdrval = vstring_str(header_buf) + strlen(hdr_opts->name) + 1; + while (ISSPACE(*hdrval)) + hdrval++; /* trimblanks(hdrval, 0)[0] = 0; */ if (hdr_opts->type == HDR_CONTENT_TRANSFER_ENCODING) { for (cmp = code_map; cmp->name != 0; cmp++) { if (strcasecmp(hdrval, cmp->name) == 0) { - if (nvtable_find(state->attr, MAIL_ATTR_ENCODING) == 0 - || strcmp(cmp->encoding, MAIL_ATTR_ENC_8BIT) == 0) + if (strcmp(cmp->encoding, MAIL_ATTR_ENC_8BIT) == 0) nvtable_update(state->attr, MAIL_ATTR_ENCODING, cmp->encoding); break; @@ -591,13 +585,21 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type, } /* - * To avoid complications elsewhere, text must not end in REC_TYPE_CONT. - * * If we have reached the end of the message content segment, record the * current file position so we can compute the message size lateron. */ else if (type == REC_TYPE_XTRA) { state->mime_errs = mime_state_update(state->mime_state, type, buf, len); + /* Ignore header truncation after primary message headers. */ + state->mime_errs &= ~MIME_ERR_TRUNC_HEADER; + /* Ignore MIME nesting error if bouncing or forwarding mail. */ + /* XXX Also: ignore if not header checking. */ + if ((state->flags & CLEANUP_FLAG_FILTER) == 0) + state->mime_errs &= ~MIME_ERR_NESTING; + if (state->mime_errs && state->reason == 0) { + state->errs |= CLEANUP_STAT_CONT; + state->reason = mystrdup(mime_state_error(state->mime_errs)); + } state->mime_state = mime_state_free(state->mime_state); if ((state->xtra_offset = vstream_ftell(state->dst)) < 0) msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path); @@ -618,6 +620,7 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type, void cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len) { char *myname = "cleanup_message"; + int mime_options; /* * Write a dummy start-of-content segment marker. We'll update it with @@ -631,14 +634,33 @@ void cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len) msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path); /* - * Pass control to the header processing routine. + * Set up MIME processing options, if any. MIME_OPT_DISABLE_MIME disables + * special processing of Content-Type: headers, and thus, causes all text + * after the primary headers to be treated as the message body. */ - state->mime_state = mime_state_alloc(MIME_OPT_REPORT_TRUNC_HEADER, + mime_options = MIME_OPT_REPORT_TRUNC_HEADER; + if (var_disable_mime_input) { + mime_options |= MIME_OPT_DISABLE_MIME; + } else { + /* Turn off strict MIME checks if bouncing or forwarding mail. */ + if (state->flags & CLEANUP_FLAG_FILTER) { + if (var_strict_8bitmime) + mime_options |= (MIME_OPT_REPORT_8BIT_IN_HEADER + | MIME_OPT_REPORT_8BIT_IN_7BIT_BODY); + if (var_strict_encoding) + mime_options |= MIME_OPT_REPORT_ENCODING_DOMAIN; + } + } + state->mime_state = mime_state_alloc(mime_options, cleanup_header_callback, cleanup_header_done_callback, cleanup_body_callback, (MIME_STATE_ANY_END) 0, (void *) state); + + /* + * Pass control to the header processing routine. + */ state->action = cleanup_message_headerbody; cleanup_message_headerbody(state, type, buf, len); } diff --git a/postfix/src/global/foobar b/postfix/src/global/foobar deleted file mode 100644 index 7fd848638..000000000 --- a/postfix/src/global/foobar +++ /dev/null @@ -1,32 +0,0 @@ -Delivered-To: wietse@porcupine.watson.ibm.com -Received: from mailhub.watson.ibm.com (mailhub.watson.ibm.com [9.2.250.97]) - by porcupine.watson.ibm.com (Postfix) with ESMTP for - id 2F0FC188CE; Tue, 12 Jan 1999 15:08:46 -0500 (EST) -Received: from wzv.watson.ibm.com (wzv.watson.ibm.com [9.2.84.53]) by mailhub.watson.ibm.com (8.8.7/Feb-20-98) with ESMTP id PAA07748 for ; Tue, 12 Jan 1999 15:08:45 -0500 -Received: by wzv.watson.ibm.com (Postfix, from userid 309) - id 9AC44827; Tue, 12 Jan 1999 15:08:45 -0500 (EST) -Delivered-To: wietse@[9.2.84.53] -From: wietse -To: wietse -Subject: testje -MIME-Version: 1.0 -Content-Type: "multipart" ; boundary = "abcdef" foobar -Status: RO - -prolog - ---abcdef - -part01 - ---abcdef - -part02 - ---abcdef - -part03 - ---abcdef-- - -epilog diff --git a/postfix/src/global/header_token.c b/postfix/src/global/header_token.c index 475745805..04ab7f2e9 100644 --- a/postfix/src/global/header_token.c +++ b/postfix/src/global/header_token.c @@ -28,7 +28,7 @@ /* quoted-string, comment, control characters, and a set of /* user-specified special characters. /* -/* A token type is one of the following: +/* A result token type is one of the following: /* .IP HEADER_TOK_QSTRING /* Quoted string as per RFC 822. /* .IP HEADER_TOK_TOKEN @@ -46,11 +46,12 @@ /* /* Arguments: /* .IP token -/* Result array of HEADER_TOKEN structures. +/* Result array of HEADER_TOKEN structures. Token string values +/* are pointers to null-terminated substrings in the token_buffer. /* .IP token_len /* Length of the array of HEADER_TOKEN structures. /* .IP token_buffer -/* Storage for result token values. +/* Storage for result token string values. /* .IP ptr /* Input/output read position. The input is a null-terminated string. /* .IP specials diff --git a/postfix/src/global/is_header.c+ b/postfix/src/global/is_header.c+ deleted file mode 100644 index 9cd61440d..000000000 --- a/postfix/src/global/is_header.c+ +++ /dev/null @@ -1,73 +0,0 @@ -/*++ -/* NAME -/* is_header 3 -/* SUMMARY -/* message header classification -/* SYNOPSIS -/* #include -/* -/* int is_header(string) -/* const char *string; -/* DESCRIPTION -/* is_header() examines the given string and returns non-zero (true) -/* when it begins with a mail header name + colon. This routine -/* permits 8-bit data in header labels. -/* STANDARDS -/* RFC 822 (ARPA Internet Text Messages) -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include "sys_defs.h" -#include - -/* Global library. */ - -#include "is_header.h" - -/* is_header - determine if this can be a header line */ - -int is_header(const char *str) -{ - const char *cp; - int state; - int c; - -#define INITIAL 0 -#define IN_CHAR 1 -#define IN_CHAR_SPACE 2 - - /* - * XXX RFC 2822 Section 4.5, Obsolete header fields: whitespace may - * appear between header label and ":" (see: RFC 822, Section 3.4.2.). - * - * The code below allows no such whitespace. This has never been a problem, - * and therefore we're not inclined to add code for it. - * - * XXX It may, however, present another ambiguity with respect to finding - * attachment message headers. Sendmail rewrites obsolete forms. - */ - for (state = INITIAL, cp = str; (c = *(unsigned char *) cp) != 0; cp++) { - if (c == ':') - return (state == IN_CHAR || state == IN_CHAR_SPACE); - if (c == ' ') { - if (state == IN_CHAR) - state = IN_CHAR_SPACE; - if (state != IN_CHAR_SPACE) - break; - } - if (!ISASCII(c) || ISCNTRL(c)) - break; - if (state == INITIAL) state = IN_CHAR - } - return (0); -} diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index e67c98a6e..1350f5eab 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -90,6 +90,10 @@ /* int var_mime_maxdepth; /* int var_mime_bound_len; /* int var_header_limit; +/* int var_disable_mime_input; +/* int var_disable_mime_oconv; +/* int var_strict_8bitmime; +/* int var_strict_encoding; /* /* void mail_params_init() /* DESCRIPTION @@ -236,6 +240,10 @@ int var_db_read_buf; int var_mime_maxdepth; int var_mime_bound_len; int var_header_limit; +int var_disable_mime_input; +int var_disable_mime_oconv; +int var_strict_8bitmime; +int var_strict_encoding; #define MAIN_CONF_FILE "main.cf" @@ -492,6 +500,10 @@ void mail_params_init() VAR_DISABLE_DNS, DEF_DISABLE_DNS, &var_disable_dns, VAR_SOFT_BOUNCE, DEF_SOFT_BOUNCE, &var_soft_bounce, VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special, + VAR_STRICT_8BITMIME, DEF_STRICT_8BITMIME, &var_strict_8bitmime, + VAR_STRICT_ENCODING, DEF_STRICT_ENCODING, &var_strict_encoding, + VAR_DISABLE_MIME_INPUT, DEF_DISABLE_MIME_INPUT, &var_disable_mime_input, + VAR_DISABLE_MIME_OCONV, DEF_DISABLE_MIME_OCONV, &var_disable_mime_oconv, 0, }; const char *cp; diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index be7c352b5..d700e409b 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -780,7 +780,7 @@ extern int var_smtpd_soft_erlim; extern int var_smtpd_hard_erlim; #define VAR_SMTPD_ERR_SLEEP "smtpd_error_sleep_time" -#define DEF_SMTPD_ERR_SLEEP "5s" +#define DEF_SMTPD_ERR_SLEEP "1s" extern int var_smtpd_err_sleep; #define VAR_SMTPD_JUNK_CMD "smtpd_junk_command_limit" @@ -1516,13 +1516,29 @@ extern int var_qattr_count_limit; * MIME support. */ #define VAR_MIME_MAXDEPTH "mime_nesting_limit" -#define DEF_MIME_MAXDEPTH 100 +#define DEF_MIME_MAXDEPTH 20 extern int var_mime_maxdepth; #define VAR_MIME_BOUND_LEN "mime_boundary_length_limit" -#define DEF_MIME_BOUND_LEN 100 +#define DEF_MIME_BOUND_LEN 2048 extern int var_mime_bound_len; +#define VAR_DISABLE_MIME_INPUT "disable_mime_input_processing" +#define DEF_DISABLE_MIME_INPUT 0 +extern bool var_disable_mime_input; + +#define VAR_DISABLE_MIME_OCONV "disable_mime_output_conversion" +#define DEF_DISABLE_MIME_OCONV 0 +extern bool var_disable_mime_oconv; + +#define VAR_STRICT_8BITMIME "strict_8bitmime" +#define DEF_STRICT_8BITMIME 0 +extern bool var_strict_8bitmime; + +#define VAR_STRICT_ENCODING "strict_mime_encoding_domain" +#define DEF_STRICT_ENCODING 0 +extern bool var_strict_encoding; + /* LICENSE /* .ad /* .fi diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 38286b9e3..64eee5b0d 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ -#define MAIL_RELEASE_DATE "20020524" +#define MAIL_RELEASE_DATE "20020526" #define VAR_MAIL_VERSION "mail_version" #define DEF_MAIL_VERSION "1.1.10-" MAIL_RELEASE_DATE diff --git a/postfix/src/global/mime_state.c b/postfix/src/global/mime_state.c index e0b223b1c..b895b9f55 100644 --- a/postfix/src/global/mime_state.c +++ b/postfix/src/global/mime_state.c @@ -33,7 +33,7 @@ /* /* In order to fend off denial of service attacks, message headers /* are truncated at or above var_header_limit bytes, message boundary -/* strings are truncated at var_boundary_len bytes, and the message +/* strings are truncated at var_boundary_len bytes, and the multipart /* nesting level is limited to var_mime_maxdepth levels. /* /* mime_state_alloc() creates a MIME state machine. The machine @@ -52,7 +52,7 @@ /* .IP MIME_ERR_8BIT_IN_7BIT_BODY /* A MIME header specifies (or defaults to) 7-bit content, but the /* correspnding message body or body parts contain 8-bit content. -/* .IP MIME_ERR_DOMAIN_ENCODING +/* .IP MIME_ERR_ENCODING_DOMAIN /* An entity of type "message" or "multipart" specifies the wrong /* content transfer encoding domain, or specifies a transformation /* (quoted-printable, base64) instead of a domain (7bit, 8bit, @@ -80,8 +80,8 @@ /* .IP enc_type /* The content encoding: MIME_ENC_7BIT or MIME_ENC_8BIT. /* .IP flags -/* Processing options. Specify the bit-wise OR of zero or more -/* of the following: +/* Special processing options. Specify the bit-wise OR of zero or +/* more of the following: /* .RS /* .IP MIME_OPT_DISABLE_MIME /* Pay no attention to Content-* message headers, and switch to @@ -98,8 +98,8 @@ /* forwarded for approval, because Majordomo does not propagate /* MIME type information from the enclosed message to the message /* headers of the request for approval. -/* .IP MIME_OPT_REPORT_DOMAIN_ENCODING -/* Report errors that set the MIME_ERR_DOMAIN_ENCODING error +/* .IP MIME_OPT_REPORT_ENCODING_DOMAIN +/* Report errors that set the MIME_ERR_ENCODING_DOMAIN error /* flag (see above). /* .IP MIME_OPT_RECURSE_ALL_MESSAGE /* Recurse into message/anything types other than message/rfc822. @@ -160,13 +160,20 @@ /* /* This module will not glue together RFC 2231 formatted (boundary) /* parameter values. RFC 2231 says claims compatibility with existing -/* MIME processors. +/* MIME processors. Splitting boundary strings is not backwards +/* compatible. /* /* The "8-bit data inside 7-bit body" test is myopic. It is not aware -/* of the enclosing message or multipart encoding information. +/* of any enclosing (message or multipart) encoding information. /* /* If the input ends in data other than a hard line break, this module -/* will add a hard line break. No line break is added to empty input. +/* will add a hard line break of its own. No line break is added to +/* empty input. +/* +/* This code recognizes the obsolete form "headername :" but will +/* normalize it to the canonical form "headername:". Leaving the +/* obsolete form alone would cause too much trouble with existing code +/* that expects only the normalized form. /* SEE ALSO /* msg(3) diagnostics interface /* header_opts(3) header information lookup @@ -438,16 +445,13 @@ static void mime_state_content_type(MIME_STATE *state, #define TOKEN_MATCH(tok, text) \ ((tok).type == HEADER_TOK_TOKEN && strcasecmp((tok).u.value, (text)) == 0) -#define SKIP_HEADER_THRASH(cp) { while (ISSPACE(*cp)) cp++; cp++; } - #define RFC2045_TSPECIALS "()<>@,;:\\\"/[]?=" #define PARSE_CONTENT_TYPE_HEADER(state, ptr) \ header_token(state->token, MIME_MAX_TOKEN, \ state->token_buffer, ptr, RFC2045_TSPECIALS, ';') - cp = STR(state->output_buffer) + strlen(header_info->name); - SKIP_HEADER_THRASH(cp); + cp = STR(state->output_buffer) + strlen(header_info->name) + 1; if ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) > 0) { /* @@ -556,8 +560,7 @@ static void mime_state_content_encoding(MIME_STATE *state, * something other than 7bit, 8bit or binary, even if we don't recognize * the input. */ - cp = STR(state->output_buffer) + strlen(header_info->name); - SKIP_HEADER_THRASH(cp); + cp = STR(state->output_buffer) + strlen(header_info->name) + 1; if (PARSE_CONTENT_ENCODING_HEADER(state, &cp) > 0 && state->token[0].type == HEADER_TOK_TOKEN) { for (cmp = code_map; cmp->name != 0; cmp++) { @@ -651,7 +654,7 @@ int mime_state_update(MIME_STATE *state, int rec_type, /* * This message state machine is kept simple for the sake of robustness. * Standards evolve over time, and we want to be able to correctly - * processes messages that are not yet defined. This state machine knows + * process messages that are not yet defined. This state machine knows * about headers and bodies, understands that multipart/whatever has * multiple body parts with a header and body, and that message/whatever * has message headers at the start of a body part. @@ -735,15 +738,16 @@ int mime_state_update(MIME_STATE *state, int rec_type, * clean slate. */ if (input_is_text) { + int header_len; /* * See if this input is (the beginning of) a message header. * Normalize obsolete "name space colon" syntax to "name colon". * Things would be too confusing otherwise. */ - if ((len = is_header(text)) > 0) { - vstring_strncpy(state->output_buffer, text, len); - for (text += len; ISSPACE(*text); text++) + if ((header_len = is_header(text)) > 0) { + vstring_strncpy(state->output_buffer, text, header_len); + for (text += header_len; ISSPACE(*text); text++) /* void */ ; vstring_strcat(state->output_buffer, text); SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type); diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index d0d184dfb..86071fad9 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -118,6 +118,19 @@ /* .IP \fBsmtp_pix_workaround_threshold_time\fR /* The time a message must be queued before the CISCO PIX firewall /* . bug workaround is turned on. +/* .SH "MIME Conversion" +/* .IP \fBdisable_mime_output_conversion\fR +/* Disable the conversion of 8BITMIME format to 7BIT format when +/* the remote system does not advertise 8BITMIME support. +/* .IP \fBmime_boundary_length_limit\fR +/* The amount of space that will be allocated for MIME multipart +/* boundary strings. The MIME processor is unable to distinguish +/* between boundary strings that do not differ in the first +/* \fB$mime_boundary_length_limit\fR characters. +/* .IP \fBmime_nesting_limit\fR +/* The maximal nesting level of multipart mail that the MIME +/* processor can handle. Refuse mail that is nested deeper, +/* when converting from 8BITMIME format to 7BIT format. /* .SH "Authentication controls" /* .IP \fBsmtp_sasl_auth_enable\fR /* Enable per-session authentication as per RFC 2554 (SASL). diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index df089ee17..d24127c6b 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -389,7 +389,12 @@ int smtp_xfer(SMTP_STATE *state) } \ } while (0) -#define RETURN(x) do { vstring_free(next_command); return (x); } while (0) +#define RETURN(x) do { \ + vstring_free(next_command); \ + if (state->mime_state) \ + state->mime_state = mime_state_free(state->mime_state); \ + return (x); \ + } while (0) #define SENDER_IS_AHEAD \ (recv_state < send_state || recv_rcpt != send_rcpt) @@ -761,12 +766,12 @@ int smtp_xfer(SMTP_STATE *state) * transaction in progress. */ if (send_state == SMTP_STATE_DOT && nrcpt > 0) { - downgrading = ((state->features & SMTP_FEATURE_8BITMIME) == 0 - && strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) != 0); + downgrading = + (var_disable_mime_oconv == 0 + && (state->features & SMTP_FEATURE_8BITMIME) == 0 + && strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) != 0); if (downgrading) - state->mime_state = mime_state_alloc(MIME_OPT_DOWNGRADE - | MIME_OPT_REPORT_8BIT_IN_7BIT_BODY - | MIME_OPT_REPORT_8BIT_IN_HEADER, + state->mime_state = mime_state_alloc(MIME_OPT_DOWNGRADE, smtp_header_out, (MIME_STATE_ANY_END) 0, smtp_text_out, diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 8677f2379..ac0f79f6e 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -617,11 +617,8 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg, /* * Report trouble. Log a warning only if we are going to sleep+reject so * that attackers can't flood our logfiles. - * - * XXX !allow_empty_addr should also reject <"">. */ - if ((naddr < 1 && !allow_empty_addr) - || naddr > 1 + if (naddr > 1 || (strict_rfc821 && (non_addr || *STR(arg->vstrval) != '<'))) { msg_warn("Illegal address syntax from %s in %s command: %s", state->namaddr, state->where, STR(arg->vstrval)); @@ -640,6 +637,16 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg, vstring_strcpy(arg->vstrval, ""); arg->strval = STR(arg->vstrval); + /* + * Report trouble. Log a warning only if we are going to sleep+reject so + * that attackers can't flood our logfiles. + */ + if (arg->strval[0] == 0 && !allow_empty_addr) { + msg_warn("Illegal address syntax from %s in %s command: %s", + state->namaddr, state->where, STR(arg->vstrval)); + err = "501 Bad address syntax"; + } + /* * Cleanup. */