built with tinycdb. Michael Tokarev. Wietse added a test
and documentation. Files: util/dict_cdb.c proto/CDB_README.html,
postmap/Makefile.in.
+
+20250114
+
+ Bugfix (defect introduced: Postfix 3.0): the flag "SMTPUTF8
+ was requested" was random after a message was re-queued,
+ for example with the command "postsuper -r". The result was
+ be that some messages that need to be sent using SMTPUTF8
+ would be sent without using SMTPUTF8 and might be bounced.
+ Found during code maintenance. File: cleanup/cleanup_envelope.c.
+
+20250115
+
+ Bugfix (defect introduced: Postfix 3.0): the bounce daemon
+ mangled a non-ASCII address localpart in the "X-Postfix-Sender:"
+ field of a delivery status notification. It backslash-escaped
+ each byte in a multi-byte character. This behavior was
+ implemented in Postfix 2.1 (no support for UTF8 local-parts),
+ but it became incorrect after SMTPUTF8 support was implemented
+ in Postfix 3.0. File: bounce/bounce_notify_util.c.
+
+20250116
+
+ Bugfix (defect introduced: 20250104): a 'fix' not only
+ eliminated a Postfix TLSRPT client warning message, it also
+ eliminated all the TLSRPT client functionality. Reported
+ by Andreas Schulze. File: smtp/smtp_connect.c.
+
+ Infrastructure: completed an overhaul of the infrastructure
+ for passing around SMTPUTF8 related flag bits. This
+ infrastructure can now be reused to implement the "TLS-Required:
+ no" header and the REQUIRETLS ESMTP verb with very little
+ additional code.
+
+ This change requires "postfix reload" after upgrade, because
+ of an intentional change in the delivery agent protocol.
+ If this step is skipped, Postfix delivery agents will log
+ a warning: "unexpected attribute smtputf8 from xxx socket
+ (expecting: sendopts)" where xxx is the delivery agent
+ service name.
+
+ Most changes are for renaming parameters, variables, structure
+ fields, and protocol fields, without changing their type.
+ Files: bounce/bounce.c, bounce/bounce_notify_service.c,
+ bounce/bounce_notify_util.c, bounce/bounce_notify_verp.c,
+ bounce/bounce_one_service.c, bounce/bounce_service.h,
+ bounce/bounce_trace_service.c, bounce/bounce_warn_service.c,
+ cleanup/cleanup.h, cleanup/cleanup_addr.c, cleanup/cleanup_api.c,
+ cleanup/cleanup_bounce.c, cleanup/cleanup_envelope.c,
+ cleanup/cleanup_envelope_test.c, cleanup/cleanup_final.c,
+ cleanup/cleanup_out.c, cleanup/cleanup_state.c, global/abounce.c,
+ global/bounce.c, global/defer.c, global/deliver_pass.c,
+ global/deliver_request.c, global/deliver_request.h,
+ global/mail_proto.h, global/mail_version.h, global/post_mail.c,
+ global/sendopts.c, global/sendopts.h, global/smtputf8.h,
+ local/forward.c, local/local.c, local/local.h, oqmgr/qmgr.h,
+ oqmgr/qmgr_active.c, oqmgr/qmgr_deliver.c, oqmgr/qmgr_message.c,
+ pickup/pickup.c, qmgr/qmgr.h, qmgr/qmgr_active.c,
+ qmgr/qmgr_deliver.c, qmgr/qmgr_message.c, qmqpd/qmqpd.c,
+ smtp/smtp_proto.c, smtpd/smtpd.c, verify/verify.c,
license of their choice. Those who are more comfortable with the
IPL can continue with that license.
+[Incompat 20250116]
+
+Postfix needs "postfix reload" after upgrade, because of a change in
+the delivery agent protocol. If this step is skipped, Postfix delivery
+agents will log a warning:
+
+ unexpected attribute smtputf8 from xxx socket (expecting: sendopts)
+
+where xxx is the delivery agent service name.
+
[Incompat 20250106]
The logging of the Milter 'quarantine' action has changed. Instead
111 8th Avenue
New York, NY 10011, USA
+ Wietse Venema
+ porcupine.org
+
BOUNCE(8)
</pre> </body> </html>
111 8th Avenue
New York, NY 10011, USA
+ Wietse Venema
+ porcupine.org
+
BOUNCE(8)
</pre> </body> </html>
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
The maximal number of digits after the decimal point when log-
- ging sub-second delay values.
+ ging delay values.
<b><a href="postconf.5.html#export_environment">export_environment</a> (see 'postconf -d' output)</b>
The list of environment variables that a Postfix process will
111 8th Avenue
New York, NY 10011, USA
+ Wietse Venema
+ porcupine.org
+
LOCAL(8)
</pre> </body> </html>
111 8th Avenue
New York, NY 10011, USA
+ Wietse Venema
+ porcupine.org
+
BOUNCE(8)
</pre> </body> </html>
Google, Inc.
111 8th Avenue
New York, NY 10011, USA
+
+Wietse Venema
+porcupine.org
request before it is terminated by a built\-in watchdog timer.
.IP "\fBdelay_logging_resolution_limit (2)\fR"
The maximal number of digits after the decimal point when logging
-sub\-second delay values.
+delay values.
.IP "\fBexport_environment (see 'postconf -d' output)\fR"
The list of environment variables that a Postfix process will export
to non\-Postfix processes.
Google, Inc.
111 8th Avenue
New York, NY 10011, USA
+
+Wietse Venema
+porcupine.org
ORCPT
RET
ILP
+REQUIRETLS
+RequireTLS
+requiretls
+sendopts
many errors I O timeout lost connection File smtpd smtpd c
that is unknown or known but disabled File smtpd smtpd c
proto proto socketmap_table
+ Files bounce bounce c bounce bounce_notify_service c
+ cleanup cleanup h cleanup cleanup_addr c cleanup cleanup_api c
+ local forward c local local c local local h oqmgr qmgr h
+ pickup pickup c qmgr qmgr h qmgr qmgr_active c
+ qmgr qmgr_deliver c qmgr qmgr_message c qmqpd qmqpd c
+ smtp smtp_proto c smtpd smtpd c verify verify c
cntrl
TINYCDB
getdata
+XXXSENDOPTS
diffs
CLOSEFROM
Roessner
+bitflags
bounce_notify_service.o: ../../include/rcpt_buf.h
bounce_notify_service.o: ../../include/rec_type.h
bounce_notify_service.o: ../../include/recipient_list.h
+bounce_notify_service.o: ../../include/sendopts.h
bounce_notify_service.o: ../../include/smtputf8.h
bounce_notify_service.o: ../../include/stringops.h
bounce_notify_service.o: ../../include/sys_defs.h
bounce_notify_util.o: ../../include/rec_type.h
bounce_notify_util.o: ../../include/recipient_list.h
bounce_notify_util.o: ../../include/record.h
+bounce_notify_util.o: ../../include/sendopts.h
bounce_notify_util.o: ../../include/smtputf8.h
bounce_notify_util.o: ../../include/stringops.h
bounce_notify_util.o: ../../include/sys_defs.h
bounce_notify_verp.o: ../../include/rcpt_buf.h
bounce_notify_verp.o: ../../include/rec_type.h
bounce_notify_verp.o: ../../include/recipient_list.h
+bounce_notify_verp.o: ../../include/sendopts.h
bounce_notify_verp.o: ../../include/smtputf8.h
bounce_notify_verp.o: ../../include/stringops.h
bounce_notify_verp.o: ../../include/sys_defs.h
bounce_one_service.o: ../../include/rcpt_buf.h
bounce_one_service.o: ../../include/rec_type.h
bounce_one_service.o: ../../include/recipient_list.h
+bounce_one_service.o: ../../include/sendopts.h
bounce_one_service.o: ../../include/smtputf8.h
bounce_one_service.o: ../../include/stringops.h
bounce_one_service.o: ../../include/sys_defs.h
bounce_trace_service.o: ../../include/rcpt_buf.h
bounce_trace_service.o: ../../include/rec_type.h
bounce_trace_service.o: ../../include/recipient_list.h
+bounce_trace_service.o: ../../include/sendopts.h
bounce_trace_service.o: ../../include/smtputf8.h
bounce_trace_service.o: ../../include/stringops.h
bounce_trace_service.o: ../../include/sys_defs.h
bounce_warn_service.o: ../../include/rcpt_buf.h
bounce_warn_service.o: ../../include/rec_type.h
bounce_warn_service.o: ../../include/recipient_list.h
+bounce_warn_service.o: ../../include/sendopts.h
bounce_warn_service.o: ../../include/smtputf8.h
bounce_warn_service.o: ../../include/stringops.h
bounce_warn_service.o: ../../include/sys_defs.h
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
{
const char *myname = "bounce_notify_proto";
int flags;
- int smtputf8;
+ int sendopts;
int dsn_ret;
/*
RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
RECV_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- RECV_ATTR_INT(MAIL_ATTR_SMTPUTF8, &smtputf8),
+ RECV_ATTR_INT(MAIL_ATTR_SENDOPTS, &sendopts),
RECV_ATTR_STR(MAIL_ATTR_SENDER, sender),
RECV_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
RECV_ATTR_INT(MAIL_ATTR_DSN_RET, &dsn_ret),
VS_NEUTER(sender);
VS_NEUTER(dsn_envid);
if (msg_verbose)
- msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s ret=0x%x",
+ msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sendopts=%d sender=%s envid=%s ret=0x%x",
myname, flags, service_name, STR(queue_name), STR(queue_id),
- STR(encoding), smtputf8, STR(sender), STR(dsn_envid),
+ STR(encoding), sendopts, STR(sender), STR(dsn_envid),
dsn_ret);
/*
* Execute the request.
*/
return (service(flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding), smtputf8,
+ STR(queue_id), STR(encoding), sendopts,
STR(sender), STR(dsn_envid), dsn_ret,
bounce_templates));
}
{
const char *myname = "bounce_verp_proto";
int flags;
- int smtputf8;
+ int sendopts;
int dsn_ret;
/*
RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
RECV_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- RECV_ATTR_INT(MAIL_ATTR_SMTPUTF8, &smtputf8),
+ RECV_ATTR_INT(MAIL_ATTR_SENDOPTS, &sendopts),
RECV_ATTR_STR(MAIL_ATTR_SENDER, sender),
RECV_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
RECV_ATTR_INT(MAIL_ATTR_DSN_RET, &dsn_ret),
return (-1);
}
if (msg_verbose)
- msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s ret=0x%x delim=%s",
+ msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sendopts=%d sender=%s envid=%s ret=0x%x delim=%s",
myname, flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding), smtputf8, STR(sender),
+ STR(queue_id), STR(encoding), sendopts, STR(sender),
STR(dsn_envid), dsn_ret, STR(verp_delims));
/*
mail_addr_double_bounce())) {
msg_warn("request to send VERP-style notification of bounced mail");
return (bounce_notify_service(flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding), smtputf8,
+ STR(queue_id), STR(encoding), sendopts,
STR(sender), STR(dsn_envid), dsn_ret,
bounce_templates));
} else
return (bounce_notify_verp(flags, service_name, STR(queue_name),
- STR(queue_id), STR(encoding), smtputf8,
+ STR(queue_id), STR(encoding), sendopts,
STR(sender), STR(dsn_envid), dsn_ret,
STR(verp_delims), bounce_templates));
}
{
const char *myname = "bounce_one_proto";
int flags;
- int smtputf8;
+ int sendopts;
int dsn_ret;
/*
RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
RECV_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- RECV_ATTR_INT(MAIL_ATTR_SMTPUTF8, &smtputf8),
+ RECV_ATTR_INT(MAIL_ATTR_SENDOPTS, &sendopts),
RECV_ATTR_STR(MAIL_ATTR_SENDER, sender),
RECV_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
RECV_ATTR_INT(MAIL_ATTR_DSN_RET, &dsn_ret),
* RECIPIENT_FROM_RCPT_BUF().
*/
if (msg_verbose)
- msg_info("%s: flags=0x%x queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s dsn_ret=0x%x orig_to=%s to=%s off=%ld dsn_orig=%s notif=0x%x stat=%s act=%s why=%s",
+ msg_info("%s: flags=0x%x queue=%s id=%s encoding=%s sendopts=%d sender=%s envid=%s dsn_ret=0x%x orig_to=%s to=%s off=%ld dsn_orig=%s notif=0x%x stat=%s act=%s why=%s",
myname, flags, STR(queue_name), STR(queue_id),
- STR(encoding), smtputf8, STR(sender), STR(dsn_envid),
+ STR(encoding), sendopts, STR(sender), STR(dsn_envid),
dsn_ret, STR(rcpt_buf->orig_addr), STR(rcpt_buf->address),
rcpt_buf->offset, STR(rcpt_buf->dsn_orcpt),
rcpt_buf->dsn_notify, STR(dsn_buf->status),
* Execute the request.
*/
return (bounce_one_service(flags, STR(queue_name), STR(queue_id),
- STR(encoding), smtputf8, STR(sender),
+ STR(encoding), sendopts, STR(sender),
STR(dsn_envid), dsn_ret, rcpt_buf,
dsn_buf, bounce_templates));
}
/* #include "bounce_service.h"
/*
/* int bounce_notify_service(flags, service, queue_name, queue_id,
-/* encoding, smtputf8, sender, dsn_envid,
+/* encoding, sendopts, sender, dsn_envid,
/* dsn_ret, templates)
/* int flags;
/* char *service;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* char *sender;
/* char *dsn_envid;
/* int dsn_ret;
int bounce_notify_service(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
- int smtputf8, char *recipient,
+ int sendopts, char *recipient,
char *dsn_envid, int dsn_ret,
BOUNCE_TEMPLATES *ts)
{
* notification is enabled.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, smtputf8, dsn_envid,
+ encoding, sendopts, dsn_envid,
ts->failure);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
postmaster,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
/*
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
/*
postmaster,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
count = -1;
if (bounce_header(bounce, bounce_info, postmaster,
/* } BOUNCE_INFO;
/*
/* BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id, encoding,
-/* smtputf8, dsn_envid, template)
+/* sendopts, dsn_envid, template)
/* const char *service;
/* const char *queue_name;
/* const char *queue_id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *dsn_envid;
/* const BOUNCE_TEMPLATE *template;
/*
/* BOUNCE_INFO *bounce_mail_one_init(queue_name, queue_id, encoding,
-/* smtputf8, dsn_envid, dsn_notify,
+/* sendopts, dsn_envid, dsn_notify,
/* rcpt_buf, dsn_buf, template)
/* const char *queue_name;
/* const char *queue_id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* int dsn_notify;
/* const char *dsn_envid;
/* RCPT_BUF *rcpt_buf;
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
const char *queue_name,
const char *queue_id,
const char *encoding,
- int smtputf8,
+ int sendopts,
const char *dsn_envid,
RCPT_BUF *rcpt_buf,
DSN_BUF *dsn_buf,
bounce_info->service = service;
bounce_info->queue_name = queue_name;
bounce_info->queue_id = queue_id;
- bounce_info->smtputf8 = smtputf8;
+ bounce_info->sendopts = sendopts;
/* Fix 20140708: override MIME encoding: addresses may be 8bit. */
/* Fix 20140718: override MIME encoding: 8bit $myhostname expansion. */
if (var_smtputf8_enable /* was: bounce_info->smtputf8 */ ) {
quote_822_local_flags(bounce_info->sender,
VSTRING_LEN(bounce_info->buf) ?
STR(bounce_info->buf) :
- mail_addr_mail_daemon(), 0);
+ mail_addr_mail_daemon(),
+ QUOTE_FLAG_8BITCLEAN);
}
/*
const char *queue_name,
const char *queue_id,
const char *encoding,
- int smtputf8,
+ int sendopts,
const char *dsn_envid,
BOUNCE_TEMPLATE *template)
{
dsn_buf = dsb_create();
}
bounce_info = bounce_mail_alloc(service, queue_name, queue_id, encoding,
- smtputf8, dsn_envid, rcpt_buf, dsn_buf,
+ sendopts, dsn_envid, rcpt_buf, dsn_buf,
template, log_handle);
return (bounce_info);
}
BOUNCE_INFO *bounce_mail_one_init(const char *queue_name,
const char *queue_id,
const char *encoding,
- int smtputf8,
+ int sendopts,
const char *dsn_envid,
RCPT_BUF *rcpt_buf,
DSN_BUF *dsn_buf,
* Initialize the bounce_info structure for just one recipient.
*/
bounce_info = bounce_mail_alloc("none", queue_name, queue_id, encoding,
- smtputf8, dsn_envid, rcpt_buf, dsn_buf,
+ sendopts, dsn_envid, rcpt_buf, dsn_buf,
template, (BOUNCE_LOG *) 0);
return (bounce_info);
}
"Delivery report");
/* Generate *global* only if the original requested SMTPUTF8 support. */
post_mail_fprintf(bounce, "Content-Type: message/%sdelivery-status",
- (bounce_info->smtputf8 & SMTPUTF8_FLAG_REQUESTED) ?
+ (bounce_info->sendopts & SMTPUTF8_FLAG_REQUESTED) ?
"global-" : "");
/* Fix 20140709: addresses may be 8bit. */
if (NOT_7BIT_MIME(bounce_info)
/* BC Fix 20170610: prevent MIME downgrade of message/delivery-status. */
- && (bounce_info->smtputf8 & SMTPUTF8_FLAG_REQUESTED))
+ && (bounce_info->sendopts & SMTPUTF8_FLAG_REQUESTED))
post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
bounce_info->mime_encoding);
/* Fix 20140708: use "utf-8" or "rfc822" as appropriate. */
if (VSTRING_LEN(bounce_info->sender) > 0)
post_mail_fprintf(bounce, "X-%s-Sender: %s; %s",
- bounce_info->mail_name, bounce_info->smtputf8
+ bounce_info->mail_name,
+ (bounce_info->sendopts & SMTPUTF8_FLAG_ALL)
&& IS_UTF8_ADDRESS(STR(bounce_info->sender)) ?
"utf-8" : "rfc822", STR(bounce_info->sender));
if (bounce_info->arrival_time > 0)
post_mail_fputs(bounce, "");
/* Fix 20140708: Don't send "utf-8" type with non-UTF8 address. */
post_mail_fprintf(bounce, "Final-Recipient: %s; %s",
- bounce_info->smtputf8
+ (bounce_info->sendopts & SMTPUTF8_FLAG_ALL)
&& IS_UTF8_ADDRESS(rcpt->address) ?
"utf-8" : "rfc822", rcpt->address);
} else if (NON_NULL_EMPTY(rcpt->orig_addr)) {
/* Fix 20140708: Don't send "utf-8" type with non-UTF8 address. */
post_mail_fprintf(bounce, "Original-Recipient: %s; %s",
- bounce_info->smtputf8
+ (bounce_info->sendopts & SMTPUTF8_FLAG_ALL)
&& IS_UTF8_ADDRESS(rcpt->orig_addr) ?
"utf-8" : "rfc822", rcpt->orig_addr);
}
headers_only == DSN_RET_HDRS ?
"Message Headers" : "Message");
/* Generate *global* only if the original requested SMTPUTF8 support. */
- if (bounce_info->smtputf8 & SMTPUTF8_FLAG_REQUESTED)
+ if (bounce_info->sendopts & SMTPUTF8_FLAG_REQUESTED)
post_mail_fprintf(bounce, "Content-Type: message/%s",
headers_only == DSN_RET_HDRS ?
"global-headers" : "global");
/* #include "bounce_service.h"
/*
/* int bounce_notify_verp(flags, service, queue_name, queue_id,
-/* encoding, smtputf8, sender,
+/* encoding, sendopts, sender,
/* dsn_envid, dsn_ret, verp_delims,
/* templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* char *sender;
/* char *dsn_envid;
/* int dsn_ret;
int bounce_notify_verp(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
- int smtputf8, char *recipient,
+ int sendopts, char *recipient,
char *dsn_envid, int dsn_ret,
char *verp_delims, BOUNCE_TEMPLATES *ts)
{
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, smtputf8, dsn_envid,
+ encoding, sendopts, dsn_envid,
ts->failure);
/*
vstring_strcpy(rcpt_buf->address, "(recipient address unavailable)");
(void) RECIPIENT_FROM_RCPT_BUF(rcpt_buf);
bounce_status = bounce_one_service(flags, queue_name, queue_id,
- encoding, smtputf8, recipient,
+ encoding, sendopts, recipient,
dsn_envid, dsn_ret, rcpt_buf,
dsn_buf, ts);
rcpb_free(rcpt_buf);
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, STR(verp_buf),
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
/*
postmaster,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
if (bounce_header(bounce, bounce_info, postmaster,
POSTMASTER_COPY) == 0
/* #include "bounce_service.h"
/*
/* int bounce_one_service(flags, queue_name, queue_id, encoding,
-/* smtputf8, orig_sender, envid, ret,
+/* sendopts, orig_sender, envid, ret,
/* rcpt_buf, dsn_buf, templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* char *orig_sender;
/* char *envid;
/* int ret;
/* bounce_one_service - send a bounce for one recipient */
int bounce_one_service(int flags, char *queue_name, char *queue_id,
- char *encoding, int smtputf8,
+ char *encoding, int sendopts,
char *orig_sender, char *dsn_envid,
int dsn_ret, RCPT_BUF *rcpt_buf,
DSN_BUF *dsn_buf, BOUNCE_TEMPLATES *ts)
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_one_init(queue_name, queue_id, encoding,
- smtputf8, dsn_envid, rcpt_buf,
+ sendopts, dsn_envid, rcpt_buf,
dsn_buf, ts->failure);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
var_2bounce_rcpt,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
/*
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, orig_sender,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
/*
var_bounce_rcpt,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
if (bounce_header(bounce, bounce_info, var_bounce_rcpt,
POSTMASTER_COPY) == 0
DSN_BUF *dsn_buf; /* delivery status info */
BOUNCE_LOG *log_handle; /* open logfile */
char *mail_name; /* $mail_name, cooked */
- int smtputf8; /* SMTPUTF8 requested */
+ int sendopts; /* smtputf8, requiretls, etc. */
} BOUNCE_INFO;
/* */
/* #include "bounce_service.h"
/*
/* int bounce_trace_service(flags, service, queue_name, queue_id,
-/* encoding, smtputf8, sender, envid,
+/* encoding, sendopts, sender, envid,
/* ret, templates)
/* int flags;
/* char *service;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* char *sender;
/* char *envid;
/* int ret;
int bounce_trace_service(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
- int smtputf8,
+ int sendopts,
char *recipient, char *dsn_envid,
int unused_dsn_ret,
BOUNCE_TEMPLATES *ts)
#define NON_DSN_FLAGS (DEL_REQ_FLAG_USR_VRFY | DEL_REQ_FLAG_RECORD)
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, smtputf8, dsn_envid,
+ encoding, sendopts, dsn_envid,
flags & NON_DSN_FLAGS ?
ts->verify : ts->success);
if ((bounce = post_mail_fopen_nowait(sender, recipient,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
count = -1;
if (bounce_header(bounce, bounce_info, recipient,
/* #include "bounce_service.h"
/*
/* int bounce_warn_service(flags, service, queue_name, queue_id,
-/* encoding, smtputf8, sender, envid,
+/* encoding, sendopts, sender, envid,
/* dsn_ret, templates)
/* int flags;
/* char *service;
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* char *sender;
/* char *envid;
/* int dsn_ret;
int bounce_warn_service(int unused_flags, char *service, char *queue_name,
char *queue_id, char *encoding,
- int smtputf8, char *recipient,
+ int sendopts, char *recipient,
char *dsn_envid, int dsn_ret,
BOUNCE_TEMPLATES *ts)
{
* notify_classes restrictions.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, smtputf8, dsn_envid, ts->delay);
+ encoding, sendopts, dsn_envid, ts->delay);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
postmaster,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
/*
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
/*
postmaster,
MAIL_SRC_MASK_BOUNCE,
NULL_TRACE_FLAGS,
- smtputf8,
+ sendopts,
new_id)) != 0) {
count = -1;
if (bounce_header(bounce, bounce_info, postmaster,
TESTSRC =
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= cleanup_masquerade cleanup_milter
+TESTPROG= cleanup_masquerade cleanup_milter cleanup_envelope_test
PROG = cleanup
INC_DIR = ../../include
LIBS = ../../lib/lib$(LIB_PREFIX)master$(LIB_SUFFIX) \
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(CLEANUP_MILTER_OBJS) $(LIBS) $(SYSLIBS)
mv junk cleanup_milter.o
-tests: cleanup_masquerade_test milter_tests
+CLEANUP_SIZE_TEST_OBJS = cleanup_envelope.o cleanup_state.o cleanup_out.o \
+ cleanup_final.o
+cleanup_envelope_test: cleanup_envelope_test.o $(CLEANUP_SIZE_TEST_OBJS) $(LIBS)
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(CLEANUP_SIZE_TEST_OBJS) $(LIBS) $(SYSLIBS)
+
+tests: cleanup_masquerade_test milter_tests test_cleanup_envelope
+
+test_cleanup_envelope: cleanup_envelope_test
+ $(SHLIB_ENV) $(VALGRIND) ./cleanup_envelope_test
milter_tests: cleanup_milter_test bug_tests \
cleanup_milter_test2 cleanup_milter_test3 cleanup_milter_test4 \
cleanup_addr.o: ../../include/rec_type.h
cleanup_addr.o: ../../include/record.h
cleanup_addr.o: ../../include/resolve_clnt.h
+cleanup_addr.o: ../../include/sendopts.h
cleanup_addr.o: ../../include/smtputf8.h
cleanup_addr.o: ../../include/string_list.h
cleanup_addr.o: ../../include/stringops.h
cleanup_api.o: ../../include/rec_type.h
cleanup_api.o: ../../include/recipient_list.h
cleanup_api.o: ../../include/resolve_clnt.h
+cleanup_api.o: ../../include/sendopts.h
cleanup_api.o: ../../include/smtputf8.h
cleanup_api.o: ../../include/string_list.h
cleanup_api.o: ../../include/sys_defs.h
cleanup_envelope.o: ../../include/recipient_list.h
cleanup_envelope.o: ../../include/record.h
cleanup_envelope.o: ../../include/resolve_clnt.h
+cleanup_envelope.o: ../../include/sendopts.h
cleanup_envelope.o: ../../include/smtputf8.h
cleanup_envelope.o: ../../include/string_list.h
cleanup_envelope.o: ../../include/stringops.h
cleanup_out.o: ../../include/rec_type.h
cleanup_out.o: ../../include/record.h
cleanup_out.o: ../../include/resolve_clnt.h
+cleanup_out.o: ../../include/sendopts.h
cleanup_out.o: ../../include/smtputf8.h
cleanup_out.o: ../../include/split_at.h
cleanup_out.o: ../../include/string_list.h
struct CLEANUP_REGION *curr_body_region;
/*
- * Internationalization.
+ * Internationalization, RequireTLS, etc.
*/
- int smtputf8; /* what support is desired */
+ int sendopts; /* what support is desired */
} CLEANUP_STATE;
/*
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
/* Fix 20140711: Auto-detect an UTF8 sender. */
if (var_smtputf8_enable && *STR(clean_addr) && !allascii(STR(clean_addr))
&& valid_utf8_stringz(STR(clean_addr))) {
- state->smtputf8 |= SMTPUTF8_FLAG_SENDER;
+ state->sendopts |= SMTPUTF8_FLAG_SENDER;
/* Fix 20140713: request SMTPUTF8 support selectively. */
if (state->flags & CLEANUP_FLAG_AUTOUTF8)
- state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ state->sendopts |= SMTPUTF8_FLAG_REQUESTED;
}
CLEANUP_OUT_BUF(state, REC_TYPE_FROM, clean_addr);
if (state->sender) /* XXX Can't happen */
&& valid_utf8_stringz(STR(clean_addr))) {
/* Fix 20140713: request SMTPUTF8 support selectively. */
if (state->flags & CLEANUP_FLAG_AUTOUTF8)
- state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ state->sendopts |= SMTPUTF8_FLAG_REQUESTED;
}
/* Fix 20141024: Don't fake up a "bare" DSN original rcpt in smtp(8). */
if (state->dsn_orcpt == 0 && *STR(clean_addr) != 0)
state->dsn_orcpt = concatenate((!allascii(STR(clean_addr))
- && (state->smtputf8 & SMTPUTF8_FLAG_REQUESTED)) ?
+ && (state->sendopts & SMTPUTF8_FLAG_REQUESTED)) ?
"utf-8" : "rfc822", ";", STR(clean_addr), (char *) 0);
cleanup_out_recipient(state, state->dsn_orcpt, state->dsn_notify,
state->orig_rcpt, STR(clean_addr));
&& valid_utf8_stringz(STR(clean_addr))) {
/* Fix 20140713: request SMTPUTF8 support selectively. */
if (state->flags & CLEANUP_FLAG_AUTOUTF8)
- state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ state->sendopts |= SMTPUTF8_FLAG_REQUESTED;
}
cleanup_out_recipient(state, dsn_orcpt, dsn_notify,
STR(clean_addr), STR(clean_addr));
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
state->err_mask = ~0;
}
if (state->flags & CLEANUP_FLAG_SMTPUTF8)
- state->smtputf8 = SMTPUTF8_FLAG_REQUESTED;
+ state->sendopts |= SMTPUTF8_FLAG_REQUESTED;
+ /* TODO(wietse) REQUIRETLS. */
}
/* cleanup_flush - finish queue file */
bounce_err =
bounce_flush(BOUNCE_FLAG_CLEAN,
state->queue_name, state->queue_id,
- encoding, state->smtputf8, state->sender,
+ encoding, state->sendopts, state->sender,
dsn_envid, dsn_ret);
} else {
bounce_err =
bounce_flush_verp(BOUNCE_FLAG_CLEAN,
state->queue_name, state->queue_id,
- encoding, state->smtputf8, state->sender,
+ encoding, state->sendopts, state->sender,
dsn_envid, dsn_ret, state->verp_delims);
}
if (bounce_err != 0) {
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
/*
* Initial envelope non-recipient record processing.
*
- * If the message was requeued with "postsuper -r" use their
- * SMTPUTF8_REQUESTED flag.
+ * If this message was requeued with "postsuper -r", use their sender
+ * options flags, excluding flags derived from headers or envelopes.
+ * Those flags may be derived again, depending on Postfix configuration.
*/
if (state->flags & CLEANUP_FLAG_INRCPT)
/* Tell qmgr that recipient records are mixed with other information. */
state->qmgr_opts |= QMGR_READ_FLAG_MIXED_RCPT_OTHER;
if (type == REC_TYPE_SIZE) {
- /* Use our own SIZE record, except for the SMTPUTF8_REQUESTED flag. */
- (void) sscanf(buf, "%*s $*s %*s %*s %*s %d", &state->smtputf8);
- state->smtputf8 &= SMTPUTF8_FLAG_REQUESTED;
+ /* Ignore their SIZE record, but keep the non-derived sender options. */
+ (void) sscanf(buf, "%*s %*s %*s %*s %*s %d", &state->sendopts);
+ state->sendopts &= ~SOPT_FLAG_DERIVED;
return;
}
if (mapped_type == REC_TYPE_CTIME)
--- /dev/null
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h> /* ssscanf() */
+#include <ctype.h>
+
+ /*
+ * Utility library.
+ */
+#include <msg.h>
+#include <msg_vstream.h>
+#include <vstring.h>
+#include <vstream.h>
+#include <stringops.h>
+
+ /*
+ * Global library.
+ */
+#include <been_here.h>
+#include <record.h>
+#include <rec_type.h>
+#include <cleanup_user.h>
+#include <mail_params.h>
+#include <smtputf8.h>
+
+ /*
+ * Application-specific.
+ */
+#include <cleanup.h>
+
+ /*
+ * Stubs for parameter dependencies.
+ */
+int var_delay_warn_time = 0;
+int var_dup_filter_limit = DEF_DUP_FILTER_LIMIT;
+char *var_remote_rwr_domain = DEF_REM_RWR_DOMAIN;
+int var_qattr_count_limit = DEF_QATTR_COUNT_LIMIT;
+VSTRING *cleanup_strip_chars = 0;
+MILTERS *cleanup_milters = 0;
+VSTRING *cleanup_trace_path = 0;
+MAPS *cleanup_virt_alias_maps = 0;
+char *cleanup_path = "fixed";
+
+ /*
+ * Stubs for cleanup_message.c dependencies. TODO(wietse) replace function
+ * stubs with mocks that can have expectations and that can report
+ * unexpected calls.
+ */
+void cleanup_message(CLEANUP_STATE *state, int type, const char *buf,
+ ssize_t len)
+{
+ msg_panic("cleanup_message");
+}
+
+ /*
+ * Stubs for cleanup_milter.c dependencies.
+ */
+void cleanup_milter_receive(CLEANUP_STATE *state, int count)
+{
+ msg_panic("cleanup_milter_receive");
+}
+
+void cleanup_milter_emul_mail(CLEANUP_STATE *state, MILTERS *milters,
+ const char *sender)
+{
+ msg_panic("cleanup_milter_emul_mail");
+}
+
+void cleanup_milter_emul_rcpt(CLEANUP_STATE *state, MILTERS *milters,
+ const char *recipient)
+{
+ msg_panic("cleanup_milter_emul_rcpt");
+}
+
+ /*
+ * Stubs for cleanup_addr.c dependencies.
+ */
+off_t cleanup_addr_sender(CLEANUP_STATE *state, const char *addr)
+{
+ msg_panic("cleanup_addr_sender");
+}
+
+void cleanup_addr_recipient(CLEANUP_STATE *state, const char *addr)
+{
+ msg_panic("cleanup_addr_recipient");
+}
+
+ /*
+ * Stubs for cleanup_region.c dependencies.
+ */
+void cleanup_region_done(CLEANUP_STATE *state)
+{
+}
+
+ /*
+ * Tests and test cases.
+ */
+typedef struct TEST_CASE {
+ const char *label; /* identifies test case */
+ int (*action) (const struct TEST_CASE *);
+} TEST_CASE;
+
+#define PASS 1
+#define FAIL 0
+
+static int overrides_size_fields(const TEST_CASE *tp)
+{
+
+ /*
+ * Generate one SIZE record test payload.
+ */
+ VSTRING *input_buf = vstring_alloc(100);
+
+ vstring_sprintf(input_buf, REC_TYPE_SIZE_FORMAT,
+ (REC_TYPE_SIZE_CAST1) ~ 0, /* message segment size */
+ (REC_TYPE_SIZE_CAST2) ~ 0, /* content offset */
+ (REC_TYPE_SIZE_CAST3) ~ 0, /* recipient count */
+ (REC_TYPE_SIZE_CAST4) ~ 0, /* qmgr options */
+ (REC_TYPE_SIZE_CAST5) ~ 0, /* content length */
+ (REC_TYPE_SIZE_CAST6) SOPT_FLAG_ALL); /* sendopts */
+
+ /*
+ * Instantiate CLEANUP_STATE, and save information that isn't expected to
+ * change. We only need to save simple-type CLEANUP_STATE fields that
+ * correspond with SIZE record fields.
+ */
+ CLEANUP_STATE *state = cleanup_state_alloc((VSTREAM *) 0);
+ CLEANUP_STATE saved_state = *state;
+
+ /*
+ * Process the test SIZE record payload and write an place-holder SIZE
+ * record that will be overwritten later with final information.
+ */
+ VSTRING *output_stream_buf = vstring_alloc(100);
+
+ if ((state->dst = vstream_memopen(output_stream_buf, O_WRONLY)) == 0) {
+ msg_warn("vstream_memopen(output_stream_buf, O_WRONLY): %m");
+ return (FAIL);
+ }
+ cleanup_envelope(state, REC_TYPE_SIZE, vstring_str(input_buf),
+ VSTRING_LEN(input_buf));
+ if (state->errs != CLEANUP_STAT_OK) {
+ msg_warn("cleanup_envelope: got: '%s', want: '%s'",
+ cleanup_strerror(state->errs),
+ cleanup_strerror(CLEANUP_STAT_OK));
+ return (FAIL);
+ }
+ vstring_free(input_buf);
+ input_buf = 0;
+
+ /*
+ * Write an updated SIZE record to the output stream.
+ */
+ cleanup_final(state);
+ if (state->errs != CLEANUP_STAT_OK) {
+ msg_warn("cleanup_final: got: '%s', want: '%s'",
+ cleanup_strerror(state->errs),
+ cleanup_strerror(CLEANUP_STAT_OK));
+ return (FAIL);
+ }
+ (void) vstream_fclose(state->dst);
+ state->dst = 0;
+
+ /*
+ * Compare the stored record content against the expected content.
+ */
+ VSTREAM *fp;
+
+ if ((fp = vstream_memopen(output_stream_buf, O_RDONLY)) == 0) {
+ msg_warn("vstream_memopen(output_stream_buf, O_RDONLY): %m");
+ return (FAIL);
+ }
+ VSTRING *got_size_payload = vstring_alloc(VSTRING_LEN(output_stream_buf));
+ int got_rec_type;
+
+ if ((got_rec_type = rec_get(fp, got_size_payload, 0)) != REC_TYPE_SIZE) {
+ msg_warn("rec_get: got: %s, want: %s",
+ rec_type_name(got_rec_type), rec_type_name(REC_TYPE_SIZE));
+ return (FAIL);
+ }
+ (void) vstream_fclose(fp);
+ vstring_free(output_stream_buf);
+
+ int got_conv;
+ long data_size, data_offset, cont_length;
+ int rcpt_count, qmgr_opts, sendopts;
+
+ if ((got_conv = sscanf(vstring_str(got_size_payload), "%ld %ld %d %d %ld %d",
+ &data_size, &data_offset, &rcpt_count, &qmgr_opts,
+ &cont_length, &sendopts)) != 6) {
+ msg_warn("sscanf SIZE record fields: got: %d, want 6", got_conv);
+ return (FAIL);
+ }
+ if (data_size != saved_state.xtra_offset - saved_state.data_offset) {
+ msg_warn("SIZE.data_size: got %ld, want: %ld", (long) data_size,
+ (long) (saved_state.xtra_offset - saved_state.data_offset));
+ return (FAIL);
+ }
+ if (data_offset != saved_state.data_offset) {
+ msg_warn("SIZE.data_offset: got %ld, want: %ld", (long) data_offset,
+ (long) saved_state.data_offset);
+ return (FAIL);
+ }
+ if (rcpt_count != saved_state.rcpt_count) {
+ msg_warn("SIZE.rcpt_count: got: %d, want: %d", rcpt_count,
+ (int) saved_state.rcpt_count);
+ return (FAIL);
+ }
+ if (qmgr_opts != saved_state.qmgr_opts) {
+ msg_warn("SIZE.qmgr_opts: got: %d, want: %d", qmgr_opts,
+ saved_state.qmgr_opts);
+ return (FAIL);
+ }
+ if (cont_length != saved_state.cont_length) {
+ msg_warn("SIZE.cont_length: got %ld, want: %ld", (long) cont_length,
+ (long) saved_state.cont_length);
+ return (FAIL);
+ }
+ if (sendopts != (SOPT_FLAG_ALL & ~SOPT_FLAG_DERIVED)) {
+ msg_warn("SIZE.sendopts: got: 0x%x, want: 0x%x",
+ sendopts, SOPT_FLAG_ALL & ~SOPT_FLAG_DERIVED);
+ return (FAIL);
+ }
+
+ /*
+ * Cleanup.
+ */
+ vstring_free(got_size_payload);
+ cleanup_state_free(state);
+ return (PASS);
+}
+
+static const TEST_CASE test_cases[] = {
+ {"overrides_size_fields",
+ overrides_size_fields,
+ },
+ {0},
+};
+
+int main(int argc, char **argv)
+{
+ const TEST_CASE *tp;
+ int pass = 0;
+ int fail = 0;
+
+ /* XXX How to avoid linking in mail_params.o? */
+ var_line_limit = DEF_LINE_LIMIT;
+
+ msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+ for (tp = test_cases; tp->label != 0; tp++) {
+ msg_info("RUN %s", tp->label);
+ if (tp->action(tp) != PASS) {
+ fail++;
+ msg_info("FAIL %s", tp->label);
+ } else {
+ msg_info("PASS %s", tp->label);
+ pass++;
+ }
+ }
+ msg_info("PASS=%d FAIL=%d", pass, fail);
+ exit(fail != 0);
+}
(REC_TYPE_SIZE_CAST3) state->rcpt_count,
(REC_TYPE_SIZE_CAST4) state->qmgr_opts,
(REC_TYPE_SIZE_CAST5) state->cont_length,
- (REC_TYPE_SIZE_CAST6) state->smtputf8);
+ (REC_TYPE_SIZE_CAST6) state->sendopts);
}
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
* Fix 20140711: Auto-detect the presence of a non-ASCII header.
*/
if (var_smtputf8_enable && *STR(header_buf) && !allascii(STR(header_buf))) {
- state->smtputf8 |= SMTPUTF8_FLAG_HEADER;
+ state->sendopts |= SMTPUTF8_FLAG_HEADER;
/* Fix 20140713: request SMTPUTF8 support selectively. */
if (state->flags & CLEANUP_FLAG_AUTOUTF8)
- state->smtputf8 |= SMTPUTF8_FLAG_REQUESTED;
+ state->sendopts |= SMTPUTF8_FLAG_REQUESTED;
}
/*
state->milter_err_text = 0;
state->milter_dsn_buf = 0;
state->free_regions = state->body_regions = state->curr_body_region = 0;
- state->smtputf8 = 0;
+ state->sendopts = 0;
return (state);
}
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 \
- hfrom_format.c rfc2047_code.c ascii_header_text.c
+ hfrom_format.c rfc2047_code.c ascii_header_text.c sendopts.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 \
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 \
- hfrom_format.o rfc2047_code.o ascii_header_text.o
+ hfrom_format.o rfc2047_code.o ascii_header_text.o sendopts.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.
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 \
- hfrom_format.h rfc2047_code.h ascii_header_text.h
+ hfrom_format.h rfc2047_code.h ascii_header_text.h sendopts.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
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 hfrom_format rfc2047_code \
- ascii_header_text
+ ascii_header_text sendopts
LIBS = ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
LIB_DIR = ../../lib
ascii_header_text: ascii_header_text.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+sendopts: sendopts.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)
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 hfrom_format_test rfc2047_code_test \
- ascii_header_text_test
+ ascii_header_text_test sendopts_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
ascii_header_text_test: update ascii_header_text
$(SHLIB_ENV) $(VALGRIND) ./ascii_header_text
+sendopts_test: update sendopts
+ -$(SHLIB_ENV) $(VALGRIND) ./sendopts
+
clean:
rm -f *.o $(LIB) *core $(TESTPROG) junk $(MAPS)
post_mail.o: post_mail.h
post_mail.o: rec_type.h
post_mail.o: record.h
+post_mail.o: sendopts.h
post_mail.o: smtputf8.h
quote_821_local.o: ../../include/check_arg.h
quote_821_local.o: ../../include/sys_defs.h
smtputf8.o: cleanup_user.h
smtputf8.o: mail_params.h
smtputf8.o: mail_proto.h
+smtputf8.o: sendopts.h
smtputf8.o: smtputf8.c
smtputf8.o: smtputf8.h
split_addr.o: ../../include/check_arg.h
/* SYNOPSIS
/* #include <abounce.h>
/*
-/* void abounce_flush(flags, queue, id, encoding, smtputf8, sender,
+/* void abounce_flush(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, void *context);
/* void *context;
/*
-/* void abounce_flush_verp(flags, queue, id, encoding, smtputf8, sender,
+/* void abounce_flush_verp(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, void *context);
/* void *context;
/*
-/* void adefer_flush(flags, queue, id, encoding, smtputf8, sender,
+/* void adefer_flush(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, void *context);
/* void *context;
/*
-/* void adefer_flush_verp(flags, queue, id, encoding, smtputf8, sender,
+/* void adefer_flush_verp(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, void *context);
/* void *context;
/*
-/* void adefer_warn(flags, queue, id, encoding, smtputf8, sender,
+/* void adefer_warn(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* void (*callback)(int status, void *context);
/* void *context;
/*
-/* void atrace_flush(flags, queue, id, encoding, smtputf8, sender,
+/* void atrace_flush(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* file has the same name as the original message file.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
-/* .IP smtputf8
-/* The level of SMTPUTF8 support (to be defined).
+/* .IP sendopts
+/* Sender-requested SMTPUTF8 or RequireTLS support.
/* .IP sender
/* The sender envelope address.
/* .IP dsn_envid
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
static void abounce_connect(const char *class, const char *service,
int command, int flags,
const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender,
const char *dsn_envid, int dsn_ret,
const char *verp, ABOUNCE_FN callback,
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
/* abounce_flush_verp - asynchronous bounce flush */
void abounce_flush_verp(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, const char *verp,
ABOUNCE_FN callback,
void *context)
{
abounce_connect(MAIL_CLASS_PRIVATE, var_bounce_service,
- BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
+ BOUNCE_CMD_VERP, flags, queue, id, encoding, sendopts,
sender, dsn_envid, dsn_ret, verp, callback, context);
}
/* adefer_flush_verp - asynchronous defer flush */
void adefer_flush_verp(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, const char *verp,
ABOUNCE_FN callback, void *context)
{
flags |= BOUNCE_FLAG_DELRCPT;
abounce_connect(MAIL_CLASS_PRIVATE, var_defer_service,
- BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
+ BOUNCE_CMD_VERP, flags, queue, id, encoding, sendopts,
sender, dsn_envid, dsn_ret, verp, callback, context);
}
/* abounce_flush - asynchronous bounce flush */
void abounce_flush(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, ABOUNCE_FN callback,
void *context)
{
abounce_connect(MAIL_CLASS_PRIVATE, var_bounce_service, BOUNCE_CMD_FLUSH,
- flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ flags, queue, id, encoding, sendopts, sender, dsn_envid,
dsn_ret, ABOUNCE_NO_VERP, callback, context);
}
/* adefer_flush - asynchronous defer flush */
void adefer_flush(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, ABOUNCE_FN callback, void *context)
{
flags |= BOUNCE_FLAG_DELRCPT;
abounce_connect(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_FLUSH,
- flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ flags, queue, id, encoding, sendopts, sender, dsn_envid,
dsn_ret, ABOUNCE_NO_VERP, callback, context);
}
/* adefer_warn - send copy of defer log to sender as warning bounce */
void adefer_warn(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, ABOUNCE_FN callback, void *context)
{
abounce_connect(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_WARN,
- flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ flags, queue, id, encoding, sendopts, sender, dsn_envid,
dsn_ret, ABOUNCE_NO_VERP, callback, context);
}
/* atrace_flush - asynchronous trace flush */
void atrace_flush(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, ABOUNCE_FN callback, void *context)
{
abounce_connect(MAIL_CLASS_PRIVATE, var_trace_service, BOUNCE_CMD_TRACE,
- flags, queue, id, encoding, smtputf8, sender, dsn_envid,
+ flags, queue, id, encoding, sendopts, sender, dsn_envid,
dsn_ret, ABOUNCE_NO_VERP, callback, context);
}
/* const char *relay;
/* DSN *dsn;
/*
-/* int bounce_flush(flags, queue, id, encoding, smtputf8, sender,
+/* int bounce_flush(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/*
-/* int bounce_flush_verp(flags, queue, id, encoding, smtputf8,
+/* int bounce_flush_verp(flags, queue, id, encoding, sendopts,
/* sender, dsn_envid, dsn_ret, verp_delims)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* const char *verp_delims;
/*
-/* int bounce_one(flags, queue, id, encoding, smtputf8, sender,
+/* int bounce_one(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, ret, stats, recipient, relay, dsn)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* RECIPIENT *rcpt;
/* const char *relay;
/*
-/* int bounce_one_intern(flags, queue, id, encoding, smtputf8, sender,
+/* int bounce_one_intern(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, ret, stats, recipient, relay, dsn)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* This information is used for syslogging only.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
-/* .IP smtputf8
-/* The level of SMTPUTF8 support (to be defined).
+/* .IP sendopts
+/* Sender-requested SMTPUTF8 or RequireTLS support.
/* .IP sender
/* The sender envelope address.
/* .IP dsn_envid
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
/* bounce_flush - flush the bounce log and deliver to the sender */
int bounce_flush(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret)
{
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
/* bounce_flush_verp - verpified notification */
int bounce_flush_verp(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, const char *verp_delims)
{
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
/* bounce_one - send notice for one recipient */
int bounce_one(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, MSG_STATS *stats, RECIPIENT *rcpt,
const char *relay, DSN *dsn)
return (defer_append_intern(flags, id, stats, rcpt, relay, dsn_res));
my_dsn = *dsn_res;
}
- return (bounce_one_intern(flags, queue, id, encoding, smtputf8, sender,
+ return (bounce_one_intern(flags, queue, id, encoding, sendopts, sender,
dsn_envid, dsn_ret, stats, rcpt, relay, &my_dsn));
}
/* bounce_one_intern - send notice for one recipient */
int bounce_one_intern(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, MSG_STATS *stats,
RECIPIENT *rcpt, const char *relay,
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
/* const char *relay;
/* DSN *dsn;
/*
-/* int defer_flush(flags, queue, id, encoding, smtputf8, sender,
+/* int defer_flush(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, dsn_ret)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/*
-/* int defer_warn(flags, queue, id, encoding, smtputf8, sender,
+/* int defer_warn(flags, queue, id, encoding, sendopts, sender,
dsn_envid, dsn_ret)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/*
-/* int defer_one(flags, queue, id, encoding, smtputf8, sender,
+/* int defer_one(flags, queue, id, encoding, sendopts, sender,
/* dsn_envid, ret, stats, recipient, relay, dsn)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
-/* int smtputf8;
+/* int sendopts;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* Delivery status. See dsn(3). The specified action is ignored.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
-/* .IP smtputf8
-/* The level of SMTPUTF8 support (to be defined).
+/* .IP sendopts
+/* Sender-requested SMTPUTF8 or RequireTLS support.
/* .IP sender
/* The sender envelope address.
/* .IP dsn_envid
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
/* defer_flush - flush the defer log and deliver to the sender */
int defer_flush(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret)
{
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
* do not flush the log */
int defer_warn(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *envid, int dsn_ret)
{
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
/* defer_one - defer mail for one recipient */
int defer_one(int flags, const char *queue, const char *id,
- const char *encoding, int smtputf8,
+ const char *encoding, int sendopts,
const char *sender, const char *dsn_envid,
int dsn_ret, MSG_STATS *stats, RECIPIENT *rcpt,
const char *relay, DSN *dsn)
if (delivery_status_filter != 0
&& (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
if (dsn_res->status[0] == '5')
- return (bounce_one_intern(flags, queue, id, encoding, smtputf8,
+ return (bounce_one_intern(flags, queue, id, encoding, sendopts,
sender, dsn_envid, dsn_ret, stats,
rcpt, relay, dsn_res));
my_dsn = *dsn_res;
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
SEND_ATTR_LONG(MAIL_ATTR_SIZE, request->data_size),
SEND_ATTR_STR(MAIL_ATTR_NEXTHOP, nexthop),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, request->encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, request->smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, request->sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, request->sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, request->dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, request->dsn_ret),
/* long data_size;
/* char *nexthop;
/* char *encoding;
+/* int sendopts;
/* char *sender;
/* MSG_STATS msg_stats;
/* RECIPIENT_LIST rcpt_list;
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
static VSTRING *dsn_envid;
static RCPT_BUF *rcpt_buf;
int rcpt_count;
- int smtputf8;
+ int sendopts;
int dsn_ret;
/*
RECV_ATTR_LONG(MAIL_ATTR_SIZE, &request->data_size),
RECV_ATTR_STR(MAIL_ATTR_NEXTHOP, nexthop),
RECV_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
- RECV_ATTR_INT(MAIL_ATTR_SMTPUTF8, &smtputf8),
+ RECV_ATTR_INT(MAIL_ATTR_SENDOPTS, &sendopts),
RECV_ATTR_STR(MAIL_ATTR_SENDER, address),
RECV_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
RECV_ATTR_INT(MAIL_ATTR_DSN_RET, &dsn_ret),
request->queue_id = mystrdup(vstring_str(queue_id));
request->nexthop = mystrdup(vstring_str(nexthop));
request->encoding = mystrdup(vstring_str(encoding));
- /* Fix 20140708: dedicated smtputf8 attribute with its own flags. */
- request->smtputf8 = smtputf8;
+ /* Fix 20140708: dedicated attribute for SMTPUTF8 etc. flags. */
+ request->sendopts = sendopts;
request->sender = mystrdup(vstring_str(address));
request->client_name = mystrdup(vstring_str(client_name));
request->client_addr = mystrdup(vstring_str(client_addr));
long data_size; /* message size */
char *nexthop; /* next hop name */
char *encoding; /* content encoding */
- int smtputf8; /* SMTPUTF8 level */
+ int sendopts; /* smtputf8, requiretls, etc. */
char *sender; /* envelope sender */
MSG_STATS msg_stats; /* time profile */
RECIPIENT_LIST rcpt_list; /* envelope recipients */
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
#endif
#define MAIL_ATTR_DSN_RET "ret_flags" /* dsn full/headers */
#define MAIL_ATTR_DSN_NOTIFY "notify_flags" /* dsn notify flags */
#define MAIL_ATTR_DSN_ORCPT "dsn_orig_rcpt" /* dsn original recipient */
-#define MAIL_ATTR_SMTPUTF8 "smtputf8" /* RFC6531 support */
+#define MAIL_ATTR_SENDOPTS "sendopts" /* RFC6531 etc. support */
/*
* SMTP reply footer support.
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
#endif
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20250109"
+#define MAIL_RELEASE_DATE "20250116"
#define MAIL_VERSION_NUMBER "3.10"
#ifdef SNAPSHOT
/* #include <post_mail.h>
/*
/* VSTREAM *post_mail_fopen(sender, recipient, source_class, trace_flags,
-/* utf8_flags, queue_id)
+/* sendopts, queue_id)
/* const char *sender;
/* const char *recipient;
/* int source_class;
/* int trace_flags;
-/* int utf8_flags;
+/* int sendopts;
/* VSTRING *queue_id;
/*
/* VSTREAM *post_mail_fopen_nowait(sender, recipient, source_class,
-/* trace_flags, utf8_flags, queue_id)
+/* trace_flags, sendopts, queue_id)
/* const char *sender;
/* const char *recipient;
/* int source_class;
/* int trace_flags;
-/* int utf8_flags;
+/* int sendopts;
/* VSTRING *queue_id;
/*
/* void post_mail_fopen_async(sender, recipient, source_class,
-/* trace_flags, utf8_flags,
+/* trace_flags, sendopts,
/* queue_id, notify, context)
/* const char *sender;
/* const char *recipient;
/* int source_class;
/* int trace_flags;
-/* int utf8_flags;
+/* int sendopts;
/* VSTRING *queue_id;
/* void (*notify)(VSTREAM *stream, void *context);
/* void *context;
/* autodetection.
/* .IP trace_flags
/* Message tracing flags as specified in \fB<deliver_request.h>\fR.
-/* .IP utf8_flags
-/* Flags defined in <smtputf8.h>. Flags other than
-/* SMTPUTF8_FLAG_REQUESTED are ignored.
+/* .IP sendopts
+/* Flags defined in <sendopts.h>. This ignores flags based on
+/* message header content, or envelope email addresses.
/* .IP queue_id
/* Null pointer, or pointer to buffer that receives the queue
/* ID of the new message.
char *recipient;
int source_class;
int trace_flags;
- int utf8_flags;
+ int sendopts;
POST_MAIL_NOTIFY notify;
void *context;
VSTREAM *stream;
static void post_mail_init(VSTREAM *stream, const char *sender,
const char *recipient,
int source_class, int trace_flags,
- int utf8_flags, VSTRING *queue_id)
+ int sendopts, VSTRING *queue_id)
{
VSTRING *id = queue_id ? queue_id : vstring_alloc(100);
struct timeval now;
int cleanup_flags =
int_filt_flags(source_class) | CLEANUP_FLAG_MASK_INTERNAL
| smtputf8_autodetect(source_class)
- | ((utf8_flags & SMTPUTF8_FLAG_REQUESTED) ? CLEANUP_FLAG_SMTPUTF8 : 0);
+ | ((sendopts & SMTPUTF8_FLAG_REQUESTED) ? CLEANUP_FLAG_SMTPUTF8 : 0);
+ /* TODO(wietse) REQUIRETLS. */
GETTIMEOFDAY(&now);
date = mail_date(now.tv_sec);
VSTREAM *post_mail_fopen(const char *sender, const char *recipient,
int source_class, int trace_flags,
- int utf8_flags, VSTRING *queue_id)
+ int sendopts, VSTRING *queue_id)
{
VSTREAM *stream;
stream = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
post_mail_init(stream, sender, recipient, source_class, trace_flags,
- utf8_flags, queue_id);
+ sendopts, queue_id);
return (stream);
}
VSTREAM *post_mail_fopen_nowait(const char *sender, const char *recipient,
int source_class, int trace_flags,
- int utf8_flags, VSTRING *queue_id)
+ int sendopts, VSTRING *queue_id)
{
VSTREAM *stream;
if ((stream = mail_connect(MAIL_CLASS_PUBLIC, var_cleanup_service,
BLOCKING)) != 0)
post_mail_init(stream, sender, recipient, source_class, trace_flags,
- utf8_flags, queue_id);
+ sendopts, queue_id);
else
msg_warn("connect to %s/%s: %m",
MAIL_CLASS_PUBLIC, var_cleanup_service);
non_blocking(vstream_fileno(state->stream), BLOCKING);
post_mail_init(state->stream, state->sender,
state->recipient, state->source_class,
- state->trace_flags, state->utf8_flags,
+ state->trace_flags, state->sendopts,
state->queue_id);
myfree(state->sender);
myfree(state->recipient);
void post_mail_fopen_async(const char *sender, const char *recipient,
int source_class, int trace_flags,
- int utf8_flags, VSTRING *queue_id,
+ int sendopts, VSTRING *queue_id,
void (*notify) (VSTREAM *, void *),
void *context)
{
state->recipient = mystrdup(recipient);
state->source_class = source_class;
state->trace_flags = trace_flags;
- state->utf8_flags = utf8_flags;
+ state->sendopts = sendopts;
state->notify = notify;
state->context = context;
state->stream = stream;
--- /dev/null
+/*++
+/* NAME
+/* sendopts 3
+/* SUMMARY
+/* Support for SMTPUTF8, REQUIRETLS, etc.
+/* SYNOPSIS
+/* #include <sendopts.h>
+/*
+/* const char *sendopts_strflags(code)
+/* int code;
+/* DESCRIPTION
+/* Postfix queue files and IPC messages contain a sendopts field
+/* with flags that control SMTPUTF8, REQUIRETLS, etc. support. The
+/* flags are documented in sendopts(3h), and are based on information
+/* received with ESMTP requests or with message content.
+/*
+/* The SMTPUTF8 flags life cycle is documented in smtputf8(3h).
+/*
+/* sendopts_strflags() maps a sendopts flag value to printable
+/* string. The result is overwritten upon each call.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* porcupine.org
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+ /*
+ * Utility library.
+ */
+#include <msg.h>
+#include <vstring.h>
+#include <name_mask.h>
+
+ /*
+ * Global library.
+ */
+#include <sendopts.h>
+
+ /*
+ * Mapping from flags code to printable string.
+ */
+static NAME_MASK sendopts_flag_map[] = {
+ "smtputf8_requested", SOPT_SMTPUTF8_REQUESTED,
+ "smtputf8_header", SOPT_SMTPUTF8_HEADER,
+ "smtputf8_sender", SOPT_SMTPUTF8_SENDER,
+ "smtputf8_recipient", SOPT_SMTPUTF8_RECIPIENT,
+ "requiretls_header", SOPT_REQUIRETLS_HEADER,
+ "requiretls_esmtp", SOPT_REQUIRETLS_ESMTP,
+ 0,
+};
+
+/* sendopts_strflags - map flags code to printable string */
+
+const char *sendopts_strflags(unsigned flags)
+{
+ static VSTRING *result;
+
+ if (flags == 0)
+ return ("none");
+
+ if (result == 0)
+ result = vstring_alloc(20);
+ else
+ VSTRING_RESET(result);
+
+ return (str_name_mask_opt(result, "sendopts_strflags", sendopts_flag_map,
+ flags, NAME_MASK_FATAL));
+}
+
+#ifdef TEST
+#include <stdlib.h>
+#include <string.h>
+#include <stringops.h>
+#include <msg_vstream.h>
+
+ /*
+ * Tests and test cases.
+ */
+typedef struct TEST_CASE {
+ const char *label; /* identifies test case */
+ int mask;
+ const char *want;
+} TEST_CASE;
+
+static const TEST_CASE test_cases[] = {
+ {"SOPT_SMTPUTF8_ALL",
+ SOPT_SMTPUTF8_ALL,
+ "smtputf8_requested smtputf8_header smtputf8_sender smtputf8_recipient"
+ },
+ {"SOPT_SMTPUTF8_DERIVED",
+ SOPT_SMTPUTF8_DERIVED,
+ "smtputf8_header smtputf8_sender smtputf8_recipient"
+ },
+ {"SOPT_SMTPUTF8_REQUESTED",
+ SOPT_SMTPUTF8_REQUESTED,
+ "smtputf8_requested"
+ },
+ {"SOPT_SMTPUTF8_HEADER",
+ SOPT_SMTPUTF8_HEADER,
+ "smtputf8_header"
+ },
+ {"SOPT_SMTPUTF8_SENDER",
+ SOPT_SMTPUTF8_SENDER,
+ "smtputf8_sender"
+ },
+ {"SOPT_SMTPUTF8_RECIPIENT",
+ SOPT_SMTPUTF8_RECIPIENT,
+ "smtputf8_recipient"
+ },
+ {"SOPT_REQUIRETLS_ALL",
+ SOPT_REQUIRETLS_ALL,
+ "requiretls_header requiretls_esmtp"
+ },
+ {"SOPT_REQUIRETLS_DERIVED",
+ SOPT_REQUIRETLS_DERIVED,
+ "requiretls_header"
+ },
+ {"SOPT_REQUIRETLS_HEADER",
+ SOPT_REQUIRETLS_HEADER,
+ "requiretls_header"
+ },
+ {"SOPT_REQUIRETLS_ESMTP",
+ SOPT_REQUIRETLS_ESMTP,
+ "requiretls_esmtp"
+ },
+ {0},
+};
+
+int main(int argc, char **argv)
+{
+ const TEST_CASE *tp;
+ int pass = 0;
+ int fail = 0;
+ const char *got;
+
+ msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+ for (tp = test_cases; tp->label != 0; tp++) {
+ msg_info("RUN %s", tp->label);
+ got = sendopts_strflags(tp->mask);
+ if (strcmp(got, tp->want) != 0) {
+ msg_warn("got result '%s', want: '%s'", got, tp->want);
+ fail++;
+ msg_info("FAIL %s", tp->label);
+ } else {
+ msg_info("PASS %s", tp->label);
+ pass++;
+ }
+ }
+ msg_info("PASS=%d FAIL=%d", pass, fail);
+ exit(fail != 0);
+}
+
+#endif
--- /dev/null
+#ifndef _SENDOPTS_H_INCLUDED_
+#define _SENDOPTS_H_INCLUDED_
+
+/*++
+/* NAME
+/* sendopts 3h
+/* SUMMARY
+/* Support for SMTPUTF8, REQUIRETLS, etc.
+/* SYNOPSIS
+/* #include <sendopts.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Support for SMTPUTF8 (RFC 6531, RFC 6532, RFC 6533). These flags were
+ * migrated from <smtputf8.h> and MUST NOT be changed, to maintain queue
+ * file compatibility.
+ */
+#define SOPT_SMTPUTF8_NONE (0)
+#define SOPT_SMTPUTF8_REQUESTED (1<<0) /* queue file/delivery/bounce request */
+#define SOPT_SMTPUTF8_HEADER (1<<1) /* queue file/delivery/bounce request */
+#define SOPT_SMTPUTF8_SENDER (1<<2) /* queue file/delivery/bounce request */
+#define SOPT_SMTPUTF8_RECIPIENT (1<<3) /* delivery request only */
+#define SOPT_SMTPUTF8_ALL (SOPT_SMTPUTF8_REQUESTED | \
+ SOPT_SMTPUTF8_HEADER | \
+ SOPT_SMTPUTF8_SENDER | \
+ SOPT_SMTPUTF8_RECIPIENT)
+#define SOPT_SMTPUTF8_DERIVED \
+ (SOPT_SMTPUTF8_ALL & ~SOPT_SMTPUTF8_REQUESTED)
+
+ /*
+ * Support for REQUIRETLS (RFC 8689). At this time only the TLS-Required:
+ * header is implemented, but we reserve the flag that would support it.
+ */
+#define SOPT_REQUIRETLS_HEADER (1<<4) /* TLS-Required: no */
+#define SOPT_REQUIRETLS_ESMTP (1<<5) /* MAIL FROM ... REQUIRETLS */
+#define SOPT_REQUIRETLS_ALL (SOPT_REQUIRETLS_HEADER | \
+ SOPT_REQUIRETLS_ESMTP)
+#define SOPT_REQUIRETLS_DERIVED SOPT_REQUIRETLS_HEADER
+
+#define SOPT_FLAG_ALL (SOPT_SMTPUTF8_ALL | SOPT_REQUIRETLS_ALL)
+#define SOPT_FLAG_DERIVED (SOPT_SMTPUTF8_DERIVED | SOPT_REQUIRETLS_DERIVED)
+
+ /*
+ * Debug helper.
+ */
+extern const char *sendopts_strflags(unsigned flags);
+
+/* 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
+/*
+/* Wietse Venema
+/* porcupine.org
+/*--*/
+
+#endif
/* DESCRIPTION
/* .nf
+ /*
+ * Global library.
+ */
+#include <sendopts.h>
+
/*
* Avoiding chicken-and-egg problems during the initial SMTPUTF8 roll-out in
* environments with pre-existing mail flows that contain UTF8.
- *
+ *
* Prior to SMTPUTF8, mail flows that contain UTF8 worked because the vast
* majority of MTAs is perfectly capable of handling UTF8 in address
* localparts (and in headers), even if pre-SMTPUTF8 standards do not
* support this practice.
- *
+ *
* When turning on Postfix SMTPUTF8 support for the first time, we don't want
* to suddenly break pre-existing mail flows that contain UTF8 because 1) a
* client does not request SMTPUTF8 support, and because 2) a down-stream
* MTA does not announce SMTPUTF8 support.
- *
+ *
* While 1) is easy enough to avoid (keep accepting UTF8 in address localparts
* just like Postfix has always done), 2) presents a thornier problem. The
* root cause of that problem is the need for SMTPUTF8 autodetection.
- *
+ *
* What is SMTPUTF8 autodetection? Postfix cannot rely solely on the sender's
* declaration that a message requires SMTPUTF8 support, because UTF8 may be
* introduced during local processing (for example, the client hostname in
* incomplete address, address rewriting, alias expansion, automatic BCC
* recipients, local forwarding, and changes made by header checks or Milter
* applications).
- *
+ *
* In summary, after local processing has happened, Postfix may decide that a
* message requires SMTPUTF8 support, even when that message initially did
* not require SMTPUTF8 support. This could make the message undeliverable
* to destinations that do not support SMTPUTF8. In an environment with
* pre-existing mail flows that contain UTF8, we want to avoid disrupting
* those mail flows when rolling out SMTPUTF8 support.
- *
+ *
* For the vast majority of sites, the simplest solution is to autodetect
* SMTPUTF8 support only for Postfix sendmail command-line submissions, at
* least as long as SMTPUTF8 support has not yet achieved wold domination.
- *
+ *
* However, sites that add UTF8 content via local processing (see above) should
* autodetect SMTPUTF8 support for all email.
- *
+ *
* smtputf8_autodetect() uses the setting of the smtputf8_autodetect_classes
* parameter, and the mail source classes defined in mail_params.h.
*/
/*
* The flag SMTPUTF8_FLAG_REQUESTED is raised on request by the sender, or
- * when a queue file contains at least one UTF8 envelope recipient. One this
- * flag is raised it is preserved when mail is forwarded or bounced.
+ * when SMTPUTF8 auto-detection is enabled and a queue file contains at
+ * least one UTF8 envelope sender, envelope recipient, or message header.
+ * Once this flag is raised, it is preserved when mail is forwarded or
+ * bounced.
*
* The flag SMTPUTF8_FLAG_HEADER is raised when a queue file contains at least
- * one UTF8 message header.
+ * one UTF8 message header even if SMTPUTF8_FLAG_REQUESTED is disabled.
*
* The flag SMTPUTF8_FLAG_SENDER is raised when a queue file contains an UTF8
- * envelope sender.
+ * envelope sender, even if SMTPUTF8_FLAG_REQUESTED is disabled.
*
* The three flags SMTPUTF8_FLAG_REQUESTED/HEADER/SENDER are stored in the
* queue file, are sent with delivery requests to Postfix delivery agents,
* and are sent with "flush" requests to the bounce daemon to ensure that
* the resulting notification message will have a content-transfer-encoding
- * of 8bit.
+ * of 8bit. The derived flags SMTPUTF8_FLAG_HEADER/SENDER are ignored when a
+ * message is re-queued with "postsuper -r". They may be regenerated by the
+ * cleanup daemon.
*
* In the future, mailing lists will have a mix of UTF8 and non-UTF8
* subscribers. With the following flag, Postfix can avoid requiring
* SMTPUTF8 delivery when it isn't really needed.
*
- * The flag SMTPUTF8_FLAG_RECIPIENT is raised when a delivery request (NOT:
- * message) contains at least one UTF8 envelope recipient. The flag is NOT
- * stored in the queue file. The flag sent in requests to the bounce daemon
- * ONLY when bouncing a single recipient. The flag is used ONLY in requests
- * to Postfix delivery agents, to give Postfix flexibility when delivering
- * messages to non-SMTPUTF8 servers.
+ * The fourth flag, SMTPUTF8_FLAG_RECIPIENT, is raised when a delivery request
+ * (NOT: message) contains at least one UTF8 envelope recipient. This flag
+ * is NOT stored in the queue file. The flag is used ONLY in requests to
+ * Postfix delivery agents, to give delivery agents flexibility when
+ * delivering messages to non-SMTPUTF8 servers. Delivery agents may then
+ * pass the flag to the bounce daemon.
*
* If a delivery request has none of the flags SMTPUTF8_FLAG_RECIPIENT,
* SMTPUTF8_FLAG_SENDER, or SMTPUTF8_FLAG_HEADER, then the message can
* the SMTP client protocol engine.
*/
#define SMTPUTF8_FLAG_NONE (0)
-#define SMTPUTF8_FLAG_REQUESTED (1<<0) /* queue file/delivery/bounce request */
-#define SMTPUTF8_FLAG_HEADER (1<<1) /* queue file/delivery/bounce request */
-#define SMTPUTF8_FLAG_SENDER (1<<2) /* queue file/delivery/bounce request */
-#define SMTPUTF8_FLAG_RECIPIENT (1<<3) /* delivery request only */
+ /* In queue file, delivery request, or bounce request. */
+#define SMTPUTF8_FLAG_REQUESTED SOPT_SMTPUTF8_REQUESTED
+#define SMTPUTF8_FLAG_HEADER SOPT_SMTPUTF8_HEADER
+#define SMTPUTF8_FLAG_SENDER SOPT_SMTPUTF8_SENDER
+ /* In delivery or bounce request only. */
+#define SMTPUTF8_FLAG_RECIPIENT SOPT_SMTPUTF8_RECIPIENT
+
+#define SMTPUTF8_FLAG_ALL SOPT_SMTPUTF8_ALL
+#define SMTPUTF8_FLAG_DERIVED SOPT_SMTPUTF8_DERIVED
/* LICENSE
/* .ad
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
#endif
forward.o: ../../include/recipient_list.h
forward.o: ../../include/record.h
forward.o: ../../include/resolve_clnt.h
+forward.o: ../../include/sendopts.h
forward.o: ../../include/sent.h
forward.o: ../../include/smtputf8.h
forward.o: ../../include/stringops.h
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
#define FORWARD_CLEANUP_FLAGS \
(CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_MASK_INTERNAL \
| smtputf8_autodetect(MAIL_SRC_MASK_FORWARD) \
- | ((request->smtputf8 & SMTPUTF8_FLAG_REQUESTED) ? \
+ | ((request->sendopts & SMTPUTF8_FLAG_REQUESTED) ? \
CLEANUP_FLAG_SMTPUTF8 : 0))
+ /* TODO(wietse) REQUIRETLS. */
attr_print(cleanup, ATTR_FLAG_NONE,
SEND_ATTR_INT(MAIL_ATTR_FLAGS, FORWARD_CLEANUP_FLAGS),
/* request before it is terminated by a built-in watchdog timer.
/* .IP "\fBdelay_logging_resolution_limit (2)\fR"
/* The maximal number of digits after the decimal point when logging
-/* sub-second delay values.
+/* delay values.
/* .IP "\fBexport_environment (see 'postconf -d' output)\fR"
/* The list of environment variables that a Postfix process will export
/* to non-Postfix processes.
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
state.msg_attr.fp = rqst->fp;
state.msg_attr.offset = rqst->data_offset;
state.msg_attr.encoding = rqst->encoding;
- state.msg_attr.smtputf8 = rqst->smtputf8;
+ state.msg_attr.sendopts = rqst->sendopts;
state.msg_attr.sender = rqst->sender;
state.msg_attr.dsn_envid = rqst->dsn_envid;
state.msg_attr.dsn_ret = rqst->dsn_ret;
char *queue_id; /* mail queue id */
long offset; /* data offset */
char *encoding; /* MIME encoding */
- int smtputf8; /* from delivery request */
+ int sendopts; /* from delivery request */
const char *sender; /* taken from envelope */
char *dsn_envid; /* DSN envelope ID */
int dsn_ret; /* DSN headers/full */
attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \
DSN_FROM_DSN_BUF(attr.why)
#define BOUNCE_ONE_ATTR(attr) \
- attr.queue_name, attr.queue_id, attr.encoding, attr.smtputf8, \
+ attr.queue_name, attr.queue_id, attr.encoding, attr.sendopts, \
attr.sender, attr.dsn_envid, attr.dsn_ret, \
&attr.msg_stats, &attr.rcpt, attr.relay, \
DSN_FROM_DSN_BUF(attr.why)
qmgr_deliver.o: ../../include/rcpt_print.h
qmgr_deliver.o: ../../include/recipient_list.h
qmgr_deliver.o: ../../include/scan_dir.h
+qmgr_deliver.o: ../../include/sendopts.h
qmgr_deliver.o: ../../include/smtputf8.h
qmgr_deliver.o: ../../include/stringops.h
qmgr_deliver.o: ../../include/sys_defs.h
qmgr_message.o: ../../include/resolve_clnt.h
qmgr_message.o: ../../include/rewrite_clnt.h
qmgr_message.o: ../../include/scan_dir.h
+qmgr_message.o: ../../include/sendopts.h
qmgr_message.o: ../../include/sent.h
qmgr_message.o: ../../include/split_addr.h
qmgr_message.o: ../../include/split_at.h
char *sender; /* complete address */
char *dsn_envid; /* DSN envelope ID */
int dsn_ret; /* DSN headers/full */
- int smtputf8; /* requires unicode */
+ int sendopts; /* smtputf8, requiretls, etc. */
char *verp_delims; /* VERP delimiters */
char *filter_xport; /* filtering transport */
char *inspect_xport; /* inspecting transport */
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
MSG_STATS stats;
char *sender;
int flags;
- int smtputf8 = message->smtputf8;
+ int sendopts = message->sendopts;
const char *addr;
/*
for (recipient = list.info; recipient < list.info + list.len; recipient++)
if (var_smtputf8_enable && (addr = recipient->address)[0]
&& !allascii(addr) && valid_utf8_stringz(addr)) {
- smtputf8 |= SMTPUTF8_FLAG_RECIPIENT;
+ sendopts |= SMTPUTF8_FLAG_RECIPIENT;
if (message->verp_delims)
- smtputf8 |= SMTPUTF8_FLAG_SENDER;
+ sendopts |= SMTPUTF8_FLAG_SENDER;
}
/*
SEND_ATTR_LONG(MAIL_ATTR_SIZE, message->cont_length),
SEND_ATTR_STR(MAIL_ATTR_NEXTHOP, entry->queue->nexthop),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, message->encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, message->dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, message->dsn_ret),
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
#include <split_addr.h>
#include <dsn_mask.h>
#include <rec_attr_map.h>
+#include <sendopts.h>
/* Client stubs. */
message->sender = 0;
message->dsn_envid = 0;
message->dsn_ret = 0;
- message->smtputf8 = 0;
+ message->sendopts = 0;
message->filter_xport = 0;
message->inspect_xport = 0;
message->redirect_addr = 0;
&message->data_size, &message->data_offset,
&nrcpt, &message->rflags,
&message->cont_length,
- &message->smtputf8)) >= 3) {
+ &message->sendopts)) >= 3) {
/* Postfix >= 1.0 (a.k.a. 20010228). */
if (message->data_offset <= 0 || message->data_size <= 0) {
msg_warn("%s: invalid size record: %.100s",
rec_type = REC_TYPE_ERROR;
break;
}
+ /* Forward compatibility. */
+ message->sendopts &= SOPT_FLAG_ALL;
} else if (count == 1) {
/* Postfix < 1.0 (a.k.a. 20010228). */
qmgr_message_oldstyle_scan(message);
pickup.o: ../../include/record.h
pickup.o: ../../include/safe_open.h
pickup.o: ../../include/scan_dir.h
+pickup.o: ../../include/sendopts.h
pickup.o: ../../include/set_ugid.h
pickup.o: ../../include/smtputf8.h
pickup.o: ../../include/stringops.h
cleanup_flags &= ~CLEANUP_FLAG_MILTER;
else
cleanup_flags |= smtputf8_autodetect(MAIL_SRC_MASK_SENDMAIL);
+ /* TODO(wietse) REQUIRETLS? */
cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
qmgr_deliver.o: ../../include/rcpt_print.h
qmgr_deliver.o: ../../include/recipient_list.h
qmgr_deliver.o: ../../include/scan_dir.h
+qmgr_deliver.o: ../../include/sendopts.h
qmgr_deliver.o: ../../include/smtputf8.h
qmgr_deliver.o: ../../include/stringops.h
qmgr_deliver.o: ../../include/sys_defs.h
qmgr_message.o: ../../include/rewrite_clnt.h
qmgr_message.o: ../../include/sane_time.h
qmgr_message.o: ../../include/scan_dir.h
+qmgr_message.o: ../../include/sendopts.h
qmgr_message.o: ../../include/sent.h
qmgr_message.o: ../../include/split_addr.h
qmgr_message.o: ../../include/split_at.h
char *sender; /* complete address */
char *dsn_envid; /* DSN envelope ID */
int dsn_ret; /* DSN headers/full */
- int smtputf8; /* requires unicode */
+ int sendopts; /* smtputf8, requiretls, etc. */
char *verp_delims; /* VERP delimiters */
char *filter_xport; /* filtering transport */
char *inspect_xport; /* inspecting transport */
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
+/* Wietse Venema
+/* porcupine.org
+/*
/* Preemptive scheduler enhancements:
/* Patrik Rak
/* Modra 6
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
message->queue_name,
message->queue_id,
message->encoding,
- message->smtputf8,
+ message->sendopts,
message->sender,
message->dsn_envid,
message->dsn_ret,
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
MSG_STATS stats;
char *sender;
int flags;
- int smtputf8 = message->smtputf8;
+ int sendopts = message->sendopts;
const char *addr;
/*
for (recipient = list.info; recipient < list.info + list.len; recipient++)
if (var_smtputf8_enable && (addr = recipient->address)[0]
&& !allascii(addr) && valid_utf8_stringz(addr)) {
- smtputf8 |= SMTPUTF8_FLAG_RECIPIENT;
+ sendopts |= SMTPUTF8_FLAG_RECIPIENT;
if (message->verp_delims)
- smtputf8 |= SMTPUTF8_FLAG_SENDER;
+ sendopts |= SMTPUTF8_FLAG_SENDER;
}
/*
SEND_ATTR_LONG(MAIL_ATTR_SIZE, message->cont_length),
SEND_ATTR_STR(MAIL_ATTR_NEXTHOP, entry->queue->nexthop),
SEND_ATTR_STR(MAIL_ATTR_ENCODING, message->encoding),
- SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
+ SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, sendopts),
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, message->dsn_envid),
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, message->dsn_ret),
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
+/* Wietse Venema
+/* porcupine.org
+/*
/* Preemptive scheduler enhancements:
/* Patrik Rak
/* Modra 6
#include <split_addr.h>
#include <dsn_mask.h>
#include <rec_attr_map.h>
+#include <sendopts.h>
/* Client stubs. */
message->sender = 0;
message->dsn_envid = 0;
message->dsn_ret = 0;
- message->smtputf8 = 0;
+ message->sendopts = 0;
message->filter_xport = 0;
message->inspect_xport = 0;
message->redirect_addr = 0;
&message->data_size, &message->data_offset,
&message->rcpt_unread, &message->rflags,
&message->cont_length,
- &message->smtputf8)) >= 3) {
+ &message->sendopts)) >= 3) {
/* Postfix >= 1.0 (a.k.a. 20010228). */
if (message->data_offset <= 0 || message->data_size <= 0) {
msg_warn("%s: invalid size record: %.100s",
rec_type = REC_TYPE_ERROR;
break;
}
+ /* Forward compatibility. */
+ message->sendopts &= SOPT_FLAG_ALL;
} else if (count == 1) {
/* Postfix < 1.0 (a.k.a. 20010228). */
qmgr_message_oldstyle_scan(message);
qmqpd.o: ../../include/rec_type.h
qmqpd.o: ../../include/recipient_list.h
qmqpd.o: ../../include/record.h
+qmqpd.o: ../../include/sendopts.h
qmqpd.o: ../../include/smtputf8.h
qmqpd.o: ../../include/sys_defs.h
qmqpd.o: ../../include/vbuf.h
cleanup_flags = input_transp_cleanup(CLEANUP_FLAG_MASK_EXTERNAL,
qmqpd_input_transp_mask);
cleanup_flags |= smtputf8_autodetect(MAIL_SRC_MASK_QMQPD);
+ /* TODO(wietse) REQUIRETLS? */
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC, var_cleanup_service);
if (state->dest == 0
|| attr_print(state->dest->stream, ATTR_FLAG_NONE,
smtp_chat.o: ../../include/recipient_list.h
smtp_chat.o: ../../include/resolve_clnt.h
smtp_chat.o: ../../include/scache.h
+smtp_chat.o: ../../include/sendopts.h
smtp_chat.o: ../../include/smtp_stream.h
smtp_chat.o: ../../include/smtputf8.h
smtp_chat.o: ../../include/sock_addr.h
smtp_proto.o: ../../include/record.h
smtp_proto.o: ../../include/resolve_clnt.h
smtp_proto.o: ../../include/scache.h
+smtp_proto.o: ../../include/sendopts.h
smtp_proto.o: ../../include/smtp_stream.h
smtp_proto.o: ../../include/smtputf8.h
smtp_proto.o: ../../include/sock_addr.h
*/
#ifdef USE_TLSRPT
if (smtp_mode && var_smtp_tlsrpt_enable
- && state->tls->level > TLS_LEV_NONE
+ && tls_level_lookup(var_smtp_tls_level) > TLS_LEV_NONE
&& !valid_hostaddr(domain, DONT_GRIPE))
smtp_tlsrpt_create_wrapper(state, domain);
else
* non-SMTPUTF8 server? That could make life easier for mailing lists.
*/
#define DELIVERY_REQUIRES_SMTPUTF8 \
- ((request->smtputf8 & SMTPUTF8_FLAG_REQUESTED) \
- && (request->smtputf8 & ~SMTPUTF8_FLAG_REQUESTED))
+ ((request->sendopts & SMTPUTF8_FLAG_REQUESTED) \
+ && (request->sendopts & SMTPUTF8_FLAG_DERIVED))
/*
* Require that the server supports SMTPUTF8 when delivery requires
* the SMTPUTF8 promise that was made to the sender.
*/
if ((session->features & SMTP_FEATURE_SMTPUTF8) != 0
- && (request->smtputf8 & SMTPUTF8_FLAG_REQUESTED) != 0)
+ && (request->sendopts & SMTPUTF8_FLAG_REQUESTED) != 0)
vstring_strcat(next_command, " SMTPUTF8");
+ /* TODO(wietse) REQUIRETLS. */
/*
* We authenticate the local MTA only, but not the sender.
quote_822_local(session->scratch, rcpt->orig_addr);
vstring_sprintf(session->scratch2, "%s;%s",
/* Fix 20140707: sender must request SMTPUTF8. */
- (request->smtputf8 != 0
- && !allascii(vstring_str(session->scratch))) ?
+ ((request->sendopts & SMTPUTF8_FLAG_ALL)
+ && !allascii(vstring_str(session->scratch))
+ && valid_utf8_stringz(vstring_str(session->scratch))) ?
"utf-8" : "rfc822",
vstring_str(session->scratch));
orcpt_type_addr = vstring_str(session->scratch2);
smtpd.o: ../../include/recipient_list.h
smtpd.o: ../../include/record.h
smtpd.o: ../../include/resolve_clnt.h
+smtpd.o: ../../include/sendopts.h
smtpd.o: ../../include/smtp_stream.h
smtpd.o: ../../include/smtputf8.h
smtpd.o: ../../include/sock_addr.h
smtpd_chat.o: ../../include/post_mail.h
smtpd_chat.o: ../../include/rec_type.h
smtpd_chat.o: ../../include/record.h
+smtpd_chat.o: ../../include/sendopts.h
smtpd_chat.o: ../../include/smtp_reply_footer.h
smtpd_chat.o: ../../include/smtp_stream.h
smtpd_chat.o: ../../include/smtputf8.h
cleanup_flags |= CLEANUP_FLAG_SMTPUTF8;
else
cleanup_flags |= smtputf8_autodetect(MAIL_SRC_MASK_SMTPD);
+ /* TODO(wietse) REQUIRETLS. */
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC,
var_cleanup_service);
if (state->dest == 0
verify.o: ../../include/nvtable.h
verify.o: ../../include/post_mail.h
verify.o: ../../include/recipient_list.h
+verify.o: ../../include/sendopts.h
verify.o: ../../include/set_eugid.h
verify.o: ../../include/smtputf8.h
verify.o: ../../include/split_at.h
post_mail_fopen_async(make_verify_sender_addr(), STR(addr),
MAIL_SRC_MASK_VERIFY,
DEL_REQ_FLAG_MTA_VRFY,
+ /* TODO(wietse) disable REQUIRETLS? */
SMTPUTF8_FLAG_NONE,
(VSTRING *) 0,
verify_post_mail_action,