parameter names). Files: postconf/postconf.c, postconf/postconf.h,
postconf_service.c, postconf/postconf_user.c.
+20111203
+
+ Cleanup: time-dependent sender addresses of address
+ verification probes. Specify an address_verify_sender_ttl
+ value of several hours or more to frustrate address harvesting.
+ Files: global/verify_sender_addr.[hc], smtpd/smtpd.c,
+ smtpd/smtpd_check.c, verify/verify.c, proto/postconf.proto,
+ proto/ADDRESS_VERIFICATION_README.html.
+
fail with mis-configured sites that reject MAIL FROM: <>, while probes from
"double-bounce@$myorigin" would succeed.
+ * The downside of using a non-empty sender address is that the address may
+ end op on spammer mailing lists. Although Postfix always discards mail to
+ the double-bounce address, this still results in wasted network bandwidth
+ and server capacity. To defeat address harvesting, Postfix 2.9 and later
+ support time-dependent sender addresses when you specify a non-zero
+ address_verify_sender_ttl value.
+
R\bRe\bec\bci\bip\bpi\bie\ben\bnt\bt a\bad\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn
As mentioned earlier, recipient address verification is useful to block mail
N\bNo\bot\bte\be
- Before Postfix version 2.3, Postfix had support only for Cyrus SASL.
Current Postfix versions have a plug-in architecture that can support
- multiple SASL implementations.
+ multiple SASL implementations. Before Postfix version 2.3, Postfix had
+ support only for Cyrus SASL.
To find out what SASL implementations are compiled into Postfix, use the
following commands:
If you upgrade from Postfix 2.7 or earlier, read RELEASE_NOTES-2.8
before proceeding.
+Major changes with snapshot 20111203
+====================================
+
+Support for time-dependent sender addresses of address verification
+probes. The default address, double-bounce, may end up on spammer
+blacklists. Although Postfix discards mail for this address, such
+mail still uses up network bandwidth and server resources. Specify
+an address_verify_sender_ttl value of several hours or more to
+frustrate address harvesting.
+
Major changes with snapshot 20111120
====================================
Things to do before the stable release:
- Add regression tests for postconf -C.
-
Remove this file from the stable release.
Things to do after the stable release:
mis-configured sites that reject MAIL FROM: <>, while
probes from "double-bounce@$<a href="postconf.5.html#myorigin">myorigin</a>" would succeed. </p>
+<li> <p> The downside of using a non-empty sender address is that
+the address may end op on spammer mailing lists. Although Postfix
+always discards mail to the double-bounce address, this still results
+in wasted network bandwidth and server capacity. To defeat
+address harvesting, Postfix 2.9 and later support time-dependent
+sender addresses when you specify a non-zero <a href="postconf.5.html#address_verify_sender_ttl">address_verify_sender_ttl</a>
+value. </p>
+
</ul>
<h2><a name="recipient">Recipient address verification</a></h2>
<strong>Note</strong>
-<p> Before Postfix version 2.3, Postfix had support only for Cyrus
-SASL. Current Postfix versions have a plug-in architecture that
-can support multiple SASL implementations. </p>
+<p> Current Postfix versions have a plug-in architecture that can
+support multiple SASL implementations. Before Postfix version 2.3,
+Postfix had support only for Cyrus SASL. </p>
</blockquote>
<b>SYNOPSIS</b>
<b>Managing <a href="postconf.5.html">main.cf</a>:</b>
- <b>postconf</b> [<b>-dfhnv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<b>-C</b> <i>class</i>] [<i>parameter</i>
- <i>...</i>]
+ <b>postconf</b> [<b>-dfhnv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<b>-C</b> <i>class,...</i>] [<i>parame-</i>
+ <i>ter ...</i>]
<b>postconf</b> [<b>-ev</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>parameter=value ...</i>]
<b>-C</b> <i>class,...</i>
When displaying <a href="postconf.5.html"><b>main.cf</b></a> parameters, select only
- parameters from the specified class(es), specified
- as a comma-separated list:
+ parameters from the specified class(es):
<b>builtin</b>
Parameters with built-in names.
<b>service</b>
- Parameters with service-defined names (the
- first field of a <a href="master.5.html"><b>master.cf</b></a> entry plus a
+ Parameters with service-defined names (the
+ first field of a <a href="master.5.html"><b>master.cf</b></a> entry plus a
Postfix-defined suffix).
<b>user</b> Parameters with user-defined names.
+ The default is as if "<b>-C builtin,service,user</b>" is
+ specified.
+
<b>-d</b> Print <a href="postconf.5.html"><b>main.cf</b></a> default parameter settings instead of
actual settings. Specify <b>-df</b> to fold long lines
for human readability (Postfix 2.9 and later).
If <i>service ...</i> is specified, only the matching ser-
vices will be output. For example, "<b>postconf -Mf</b>
- <b>inet</b>" will match all services that listen on the
+ <b>inet</b>" will output all services that listen on the
network.
Specify zero or more arguments, each with a <i>ser-</i>
</p>
+</DD>
+
+<DT><b><a name="address_verify_sender_ttl">address_verify_sender_ttl</a>
+(default: 0s)</b></DT><DD>
+
+<p> The time between changes in the time-dependent portion of address
+verification probe sender addresses. The time-dependent portion is
+appended to the localpart of the address specified with the
+<a href="postconf.5.html#address_verify_sender">address_verify_sender</a> parameter. This feature is ignored when the
+probe sender addresses is the null sender, i.e. the <a href="postconf.5.html#address_verify_sender">address_verify_sender</a>
+value is empty or <>. </p>
+
+<p> Historically, the probe sender address was fixed. This has
+caused such addresses to end up on spammer mailing lists, and has
+resulted in wasted network and processing resources. </p>
+
+<p> To enable time-dependent probe sender addresses, specify a
+non-zero time value (an integral value plus an optional one-letter
+suffix that specifies the time unit). Specify a value of at least
+several hours, to avoid problems with senders that use greylisting.
+Avoid nice TTL values, to make the result less predictable. Time
+units are: s (seconds), m (minutes), h (hours), d (days), w (weeks).
+</p>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+
</DD>
<DT><b><a name="address_verify_service_name">address_verify_service_name</a>
<a href="postconf.5.html#reject_unverified_recipient">ified_recipient</a> fails due to a temporary error con-
dition.
+ Available with Postfix 2.9 and later:
+
+ <b><a href="postconf.5.html#address_verify_sender_ttl">address_verify_sender_ttl</a> (0s)</b>
+ The time between changes in the time-dependent por-
+ tion of address verification probe sender
+ addresses.
+
<b>ACCESS CONTROL RESPONSES</b>
The following parameters control numerical SMTP reply
codes and/or text responses.
The text below provides only a parameter summary. See
<a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
+<b>PROBE MESSAGE CONTROLS</b>
+ <b><a href="postconf.5.html#address_verify_sender">address_verify_sender</a> ($<a href="postconf.5.html#double_bounce_sender">double_bounce_sender</a>)</b>
+ The sender address to use in address verification
+ probes; prior to Postfix 2.5 the default was "post-
+ master".
+
+ Available with Postfix 2.9 and later:
+
+ <b><a href="postconf.5.html#address_verify_sender_ttl">address_verify_sender_ttl</a> (0s)</b>
+ The time between changes in the time-dependent por-
+ tion of address verification probe sender
+ addresses.
+
<b>CACHE CONTROLS</b>
<b><a href="postconf.5.html#address_verify_map">address_verify_map</a> (see 'postconf -d' output)</b>
Lookup table for persistent address verification
status storage.
- <b><a href="postconf.5.html#address_verify_sender">address_verify_sender</a> ($<a href="postconf.5.html#double_bounce_sender">double_bounce_sender</a>)</b>
- The sender address to use in address verification
- probes; prior to Postfix 2.5 the default was "post-
- master".
-
<b><a href="postconf.5.html#address_verify_positive_expire_time">address_verify_positive_expire_time</a> (31d)</b>
The time after which a successful probe expires
from the address verification cache.
\fBManaging main.cf:\fR
\fBpostconf\fR [\fB-dfhnv\fR] [\fB-c \fIconfig_dir\fR]
-[\fB-C \fIclass\fR] [\fIparameter ...\fR]
+[\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
\fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
[\fIparameter=value ...\fR]
instead of the default configuration directory.
.IP "\fB-C \fIclass,...\fR"
When displaying \fBmain.cf\fR parameters, select only
-parameters from the specified class(es), specified as a
-comma-separated list:
+parameters from the specified class(es):
.RS
.IP \fBbuiltin\fR
Parameters with built-in names.
.IP \fBuser\fR
Parameters with user-defined names.
.RE
+.IP
+The default is as if "\fB-C builtin,service,user\fR" is
+specified.
.IP \fB-d\fR
Print \fBmain.cf\fR default parameter settings instead of
actual settings.
If \fIservice ...\fR is specified, only the matching services
will be output. For example, "\fBpostconf -Mf inet\fR"
-will match all services that listen on the network.
+will output all services that listen on the network.
Specify zero or more arguments, each with a \fIservice-type\fR
name (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR)
verification probes.
.PP
This feature is available in Postfix 2.3 and later.
+.SH address_verify_sender_ttl (default: 0s)
+The time between changes in the time-dependent portion of address
+verification probe sender addresses. The time-dependent portion is
+appended to the localpart of the address specified with the
+address_verify_sender parameter. This feature is ignored when the
+probe sender addresses is the null sender, i.e. the address_verify_sender
+value is empty or <>.
+.PP
+Historically, the probe sender address was fixed. This has
+caused such addresses to end up on spammer mailing lists, and has
+resulted in wasted network and processing resources.
+.PP
+To enable time-dependent probe sender addresses, specify a
+non-zero time value (an integral value plus an optional one-letter
+suffix that specifies the time unit). Specify a value of at least
+several hours, to avoid problems with senders that use greylisting.
+Avoid nice TTL values, to make the result less predictable. Time
+units are: s (seconds), m (minutes), h (hours), d (days), w (weeks).
+.PP
+This feature is available in Postfix 2.9 and later.
.SH address_verify_service_name (default: verify)
The name of the \fBverify\fR(8) address verification service. This service
maintains the status of sender and/or recipient address verification
.IP "\fBunverified_recipient_tempfail_action ($reject_tempfail_action)\fR"
The Postfix SMTP server's action when reject_unverified_recipient
fails due to a temporary error condition.
+.PP
+Available with Postfix 2.9 and later:
+.IP "\fBaddress_verify_sender_ttl (0s)\fR"
+The time between changes in the time-dependent portion of address
+verification probe sender addresses.
.SH "ACCESS CONTROL RESPONSES"
.na
.nf
The text below provides only a parameter summary. See
\fBpostconf\fR(5) for more details including examples.
+.SH "PROBE MESSAGE CONTROLS"
+.na
+.nf
+.ad
+.fi
+.IP "\fBaddress_verify_sender ($double_bounce_sender)\fR"
+The sender address to use in address verification probes; prior
+to Postfix 2.5 the default was "postmaster".
+.PP
+Available with Postfix 2.9 and later:
+.IP "\fBaddress_verify_sender_ttl (0s)\fR"
+The time between changes in the time-dependent portion of address
+verification probe sender addresses.
.SH "CACHE CONTROLS"
.na
.nf
.IP "\fBaddress_verify_map (see 'postconf -d' output)\fR"
Lookup table for persistent address verification status
storage.
-.IP "\fBaddress_verify_sender ($double_bounce_sender)\fR"
-The sender address to use in address verification probes; prior
-to Postfix 2.5 the default was "postmaster".
.IP "\fBaddress_verify_positive_expire_time (31d)\fR"
The time after which a successful probe expires from the address
verification cache.
s;\baddress_verify_relay[-</bB>]*\n*[ <bB>]*host\b;<a href="postconf.5.html#address_verify_relayhost">$&</a>;g;
s;\baddress_verify_sender_dependent_relay[-</bB>]*\n*[ <bB>]*host_maps\b;<a href="postconf.5.html#address_verify_sender_dependent_relayhost_maps">$&</a>;g;
s;\baddress_verify_sender\b;<a href="postconf.5.html#address_verify_sender">$&</a>;g;
+ s;\baddress_verify_sender_ttl\b;<a href="postconf.5.html#address_verify_sender_ttl">$&</a>;g;
s;\baddress_verify_service_name\b;<a href="postconf.5.html#address_verify_service_name">$&</a>;g;
s;\baddress_verify_transport_maps\b;<a href="postconf.5.html#address_verify_transport_maps">$&</a>;g;
s;\baddress_verify_virtual_transport\b;<a href="postconf.5.html#address_verify_virtual_transport">$&</a>;g;
mis-configured sites that reject MAIL FROM: <>, while
probes from "double-bounce@$myorigin" would succeed. </p>
+<li> <p> The downside of using a non-empty sender address is that
+the address may end op on spammer mailing lists. Although Postfix
+always discards mail to the double-bounce address, this still results
+in wasted network bandwidth and server capacity. To defeat
+address harvesting, Postfix 2.9 and later support time-dependent
+sender addresses when you specify a non-zero address_verify_sender_ttl
+value. </p>
+
</ul>
<h2><a name="recipient">Recipient address verification</a></h2>
<strong>Note</strong>
-<p> Before Postfix version 2.3, Postfix had support only for Cyrus
-SASL. Current Postfix versions have a plug-in architecture that
-can support multiple SASL implementations. </p>
+<p> Current Postfix versions have a plug-in architecture that can
+support multiple SASL implementations. Before Postfix version 2.3,
+Postfix had support only for Cyrus SASL. </p>
</blockquote>
configuration parameter. See there for details. </p>
<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM address_verify_sender_ttl 0s
+
+<p> The time between changes in the time-dependent portion of address
+verification probe sender addresses. The time-dependent portion is
+appended to the localpart of the address specified with the
+address_verify_sender parameter. This feature is ignored when the
+probe sender addresses is the null sender, i.e. the address_verify_sender
+value is empty or <>. </p>
+
+<p> Historically, the probe sender address was fixed. This has
+caused such addresses to end up on spammer mailing lists, and has
+resulted in wasted network and processing resources. </p>
+
+<p> To enable time-dependent probe sender addresses, specify a
+non-zero time value (an integral value plus an optional one-letter
+suffix that specifies the time unit). Specify a value of at least
+several hours, to avoid problems with senders that use greylisting.
+Avoid nice TTL values, to make the result less predictable. Time
+units are: s (seconds), m (minutes), h (hours), d (days), w (weeks).
+</p>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \
fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \
match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
- smtp_reply_footer.c safe_ultostr.c
+ smtp_reply_footer.c safe_ultostr.c verify_sender_addr.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 \
verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \
fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \
match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
- smtp_reply_footer.o safe_ultostr.o
+ smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
trace.h user_acl.h valid_mailhost_addr.h verify.h verify_clnt.h \
verp_sender.h wildcard_inet_addr.h xtext.h delivered_hdr.h \
fold_addr.h header_body_checks.h data_redirect.h match_service.h \
- addr_match_list.h smtp_reply_footer.h safe_ultostr.h
+ addr_match_list.h smtp_reply_footer.h safe_ultostr.h \
+ verify_sender_addr.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
quote_821_local mail_conf_time mime_state strip_addr \
verify_clnt xtext anvil_clnt scache ehlo_mask \
valid_mailhost_addr own_inet_addr header_body_checks \
- data_redirect addr_match_list safe_ultostr
+ data_redirect addr_match_list safe_ultostr verify_sender_addr
LIBS = ../../lib/libutil.a
LIB_DIR = ../../lib
safe_ultostr: safe_ultostr.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+verify_sender_addr: verify_sender_addr.c $(LIB) $(LIBS)
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
xtext_test scache_multi_test ehlo_mask_test \
namadr_list_test mail_conf_time_test header_body_checks_tests
header_body_checks_warn_test header_body_checks_prepend_test \
header_body_checks_ignore_test header_body_checks_replace_test
-root_tests: rewrite_clnt_test resolve_clnt_test
+root_tests: rewrite_clnt_test resolve_clnt_test verify_sender_addr_test
tok822_test: tok822_parse tok822_parse.in tok822_parse.ref
./tok822_parse <tok822_parse.in >tok822_parse.tmp 2>&1
resolve_clnt.ref | diff - resolve_clnt.tmp
rm -f resolve_clnt.tmp
+# Requires: Postfix, root, append_dot_mydomain=yes
+
+verify_sender_addr_test: verify_sender_addr verify_sender_addr.ref
+ @set -- `id`; case "$$1" in \
+ *"(root)") ;; \
+ *) echo 'This test requires root privilege'; exit 1;; \
+ esac
+ @test "X`postconf -h append_dot_mydomain`" = Xyes || { \
+ echo 'This test requires append_dot_mydomain=yes'; exit 1; }
+ (./verify_sender_addr aa@bb 0; \
+ ./verify_sender_addr aa@bb 1; \
+ ./verify_sender_addr aa 0; \
+ ./verify_sender_addr aa 1; \
+ ./verify_sender_addr '' 0; \
+ ./verify_sender_addr '' 1) | \
+ sed 's/[A-Z0-9][A-Z0-9]*@/STAMP@/' > verify_sender_addr.tmp
+ sed -e "s/MYDOMAIN/`postconf -h mydomain`/g" \
+ -e "s/MYORIGIN/`postconf -h myorigin`/g" \
+ -e "s/@.myhostname/@`postconf -h myhostname`/g" \
+ -e "s/@.mydomain/@`postconf -h mydomain`/g" \
+ -e "s;CONFIGDIR;`postconf -h config_directory`;" \
+ verify_sender_addr.ref | diff - verify_sender_addr.tmp
+ rm -f verify_sender_addr.tmp
+
scache_multi_test: scache scache_multi.in scache_multi.ref
./scache <scache_multi.in >scache_multi.tmp
diff scache_multi.ref scache_multi.tmp
trace.o: recipient_list.h
trace.o: trace.c
trace.o: trace.h
+user_acl.o: ../../include/argv.h
+user_acl.o: ../../include/dict.h
user_acl.o: ../../include/dict_static.h
user_acl.o: ../../include/match_list.h
user_acl.o: ../../include/match_ops.h
user_acl.o: ../../include/sys_defs.h
user_acl.o: ../../include/vbuf.h
+user_acl.o: ../../include/vstream.h
user_acl.o: ../../include/vstring.h
user_acl.o: mypwd.h
user_acl.o: string_list.h
verify_clnt.o: recipient_list.h
verify_clnt.o: verify_clnt.c
verify_clnt.o: verify_clnt.h
+verify_sender_addr.o: ../../include/attr.h
+verify_sender_addr.o: ../../include/events.h
+verify_sender_addr.o: ../../include/iostuff.h
+verify_sender_addr.o: ../../include/msg.h
+verify_sender_addr.o: ../../include/sys_defs.h
+verify_sender_addr.o: ../../include/vbuf.h
+verify_sender_addr.o: ../../include/vstream.h
+verify_sender_addr.o: ../../include/vstring.h
+verify_sender_addr.o: mail_params.h
+verify_sender_addr.o: mail_proto.h
+verify_sender_addr.o: rewrite_clnt.h
+verify_sender_addr.o: safe_ultostr.h
+verify_sender_addr.o: verify_sender_addr.c
+verify_sender_addr.o: verify_sender_addr.h
verp_sender.o: ../../include/sys_defs.h
verp_sender.o: ../../include/vbuf.h
verp_sender.o: ../../include/vstring.h
#define DEF_VERIFY_SENDER "$" VAR_DOUBLE_BOUNCE
extern char *var_verify_sender;
+#define VAR_VERIFY_SENDER_TTL "address_verify_sender_ttl"
+#define DEF_VERIFY_SENDER_TTL "0s"
+extern int var_verify_sender_ttl;
+
#define VAR_VERIFY_POLL_COUNT "address_verify_poll_count"
#define DEF_VERIFY_POLL_COUNT "${stress?1}${stress:3}"
extern int var_verify_poll_count;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20111129"
+#define MAIL_RELEASE_DATE "20111203"
#define MAIL_VERSION_NUMBER "2.9"
#ifdef SNAPSHOT
/* .IP padchar
/* Left-pad a short result with padchar characters to the
/* specified length. Specify padlen=0 to disable padding.
+/* .IP start
+/* Pointer to the first character of the string to be converted.
+/* .IP end
+/* On return, pointer to the first character not in the input
+/* alphabet, or to the string terminator.
/* DIAGNOSTICS
/* Fatal: out of memory.
+/*
+/* safe_strtoul() returns (0, EINVAL) when no conversion could
+/* be performed, and (ULONG_MAX, ERANGE) in case of overflow.
/* LICENSE
/* .ad
/* .fi
/* safe_strtoul - convert safe alphanumerical string to unsigned long */
-unsigned long safe_strtoul(char *start, char **end, int base)
+unsigned long safe_strtoul(const char *start, char **end, int base)
{
const char *myname = "safe_strtoul";
static unsigned char *char_map = 0;
/*
* Start the conversion.
*/
+ errno = 0;
for (cp = (unsigned char *) start; *cp; cp++) {
/* Return (0, EINVAL) if no conversion was made. */
if ((char_val = char_map[*cp]) >= base) {
} else {
(void) safe_ultostr(buf, ulval, base, 5, '0');
vstream_printf("%lu = %s\n", ulval, STR(buf));
- errno = 0;
ulval2 = safe_strtoul(STR(buf), &junk, base);
if (*junk || (ulval2 == ULONG_MAX && errno == ERANGE))
msg_warn("%s: %m", STR(buf));
* External interface.
*/
extern char *safe_ultostr(VSTRING *, unsigned long, int, int, int);
-extern unsigned long safe_strtoul(char *, char **, int);
+extern unsigned long safe_strtoul(const char *, char **, int);
/* LICENSE
/* .ad
--- /dev/null
+/*++
+/* NAME
+/* verify_sender_addr 3
+/* SUMMARY
+/* address verification support
+/* SYNOPSIS
+/* #include <verify_sender_addr.h>
+/*
+/* char *var_verify_sender;
+/* int var_verify_sender_ttl;
+/*
+/* const char *make_verify_sender_addr()
+/*
+/* const char *valid_verify_sender_addr(addr)
+/* const char *addr;
+/* DESCRIPTION
+/* This module computes or verifies a constant or time-dependent
+/* sender address for an address verification probe. The
+/* time-dependent portion is appended to the address localpart
+/* specified with the address_verify_sender parameter.
+/*
+/* The caller must initialize the address_verify_sender and
+/* address_verify_sender_ttl parameter values.
+/*
+/* make_verify_sender_addr() generates an envelope sender
+/* address for an address verification probe. When the
+/* address_verify_sender parameter is empty or <>, the result
+/* is always the null address.
+/*
+/* valid_verify_sender_addr() verifies that the given address
+/* is a valid sender address for address verification probes.
+/* When the address_verify_sender parameter is empty or <>,
+/* the match succeeds only if the given address is empty. When
+/* the address is time-dependent, it is allowed to differ by
+/* +/-1 TTL unit from the expected address. The result is a
+/* null pointer when no match is found. Otherwise, the result
+/* is the sender address without the time-dependent portion;
+/* this is the address that should be used for further delivery.
+/* DIAGNOSTICS
+/* Fatal errors: malformed address_verify_sender value.
+/* 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 <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <events.h>
+
+/* Global library */
+
+#include <mail_params.h>
+#include <rewrite_clnt.h>
+#include <safe_ultostr.h>
+#include <verify_sender_addr.h>
+
+/* Application-specific. */
+
+ /*
+ * We convert the time-dependent portion to a safe string (no vowels) in a
+ * reversible manner, so that we can check an incoming address against the
+ * previous, current, and next time slot. This allows for some time slippage
+ * between multiple MTAs that handle mail for the same site.
+ */
+#define VERIFY_BASE 31
+
+ /*
+ * The time-dependent address verification probe sender address has the form
+ * ``fixedvariable@fixed''. The fixed text is taken from var_verify_sender
+ * with perhaps domain information appended during address canonicalization.
+ * The variable part of the address changes every var_verify_sender_ttl
+ * seconds.
+ */
+char *var_verify_sender; /* "bare" probe sender address */
+int var_verify_sender_ttl; /* time between address changes */
+
+ /*
+ * Scaffolding for stand-alone testing.
+ */
+#ifdef TEST
+#undef event_time
+#define event_time() verify_time
+static unsigned long verify_time;
+
+#endif
+
+#define VERIFY_SENDER_ADDR_EPOCH() (event_time() / var_verify_sender_ttl)
+
+ /*
+ * SLMs.
+ */
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+/* make_verify_sender_addr - generate address_verify_sender address */
+
+const char *make_verify_sender_addr(void)
+{
+ static VSTRING *verify_sender_buf; /* the complete sender address */
+ static VSTRING *my_epoch_buf; /* scratch space */
+ char *at_domain;
+
+ /*
+ * The null sender is always time-independent.
+ */
+ if (*var_verify_sender == 0 || strcmp(var_verify_sender, "<>") == 0)
+ return ("");
+
+ /*
+ * Sanity check.
+ */
+ if (*var_verify_sender == '@')
+ msg_fatal("parameter %s: value \"%s\" must not start with '@'",
+ VAR_VERIFY_SENDER, var_verify_sender);
+ if ((at_domain = strchr(var_verify_sender, '@')) != 0 && at_domain[1] == 0)
+ msg_fatal("parameter %s: value \"%s\" must not end with '@'",
+ VAR_VERIFY_SENDER, var_verify_sender);
+
+ /*
+ * One-time initialization.
+ */
+ if (verify_sender_buf == 0) {
+ verify_sender_buf = vstring_alloc(10);
+ my_epoch_buf = vstring_alloc(10);
+ }
+
+ /*
+ * Start with the bare sender address.
+ */
+ vstring_strcpy(verify_sender_buf, var_verify_sender);
+
+ /*
+ * Append the time stamp to the address localpart, encoded in some
+ * non-decimal form for obscurity.
+ *
+ * XXX It would be nice to have safe_ultostr() append-only support.
+ */
+ if (var_verify_sender_ttl > 0) {
+ /* Strip the @domain portion, if applicable. */
+ if (at_domain != 0)
+ vstring_truncate(verify_sender_buf,
+ (ssize_t) (at_domain - var_verify_sender));
+ /* Append the time stamp to the address localpart. */
+ vstring_sprintf_append(verify_sender_buf, "%s",
+ safe_ultostr(my_epoch_buf,
+ VERIFY_SENDER_ADDR_EPOCH(),
+ VERIFY_BASE, 0, 0));
+ /* Add back the @domain, if applicable. */
+ if (at_domain != 0)
+ vstring_sprintf_append(verify_sender_buf, "%s", at_domain);
+ }
+
+ /*
+ * Rewrite the address to canonical form.
+ */
+ rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, STR(verify_sender_buf),
+ verify_sender_buf);
+
+ return (STR(verify_sender_buf));
+}
+
+/* valid_verify_sender_addr - decide if address matches time window +/-1 */
+
+const char *valid_verify_sender_addr(const char *addr)
+{
+ static VSTRING *fixed_sender_buf; /* sender without time stamp */
+ ssize_t base_len;
+ unsigned long my_epoch;
+ unsigned long their_epoch;
+ char *my_at_domain;
+ char *their_at_domain;
+ char *cp;
+
+ /*
+ * The null address is always time-independent.
+ */
+ if (*var_verify_sender == 0 || strcmp(var_verify_sender, "<>") == 0)
+ return (*addr ? 0 : "");
+
+ /*
+ * One-time initialization. Generate the time-independent address that we
+ * will return if the match is successful. This address is also used as a
+ * matching template.
+ */
+ if (fixed_sender_buf == 0) {
+ fixed_sender_buf = vstring_alloc(10);
+ vstring_strcpy(fixed_sender_buf, var_verify_sender);
+ rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, STR(fixed_sender_buf),
+ fixed_sender_buf);
+ }
+
+ /*
+ * Check the time-independent sender localpart.
+ */
+ if ((my_at_domain = strchr(STR(fixed_sender_buf), '@')) != 0)
+ base_len = my_at_domain - STR(fixed_sender_buf);
+ else
+ base_len = LEN(fixed_sender_buf);
+ if (strncasecmp(STR(fixed_sender_buf), addr, base_len) != 0)
+ return (0); /* sender localpart mis-match */
+
+ /*
+ * Check the time-independent domain.
+ */
+ if ((their_at_domain = strchr(addr, '@')) == 0 && my_at_domain != 0)
+ return ("domain mis-match"); /* sender domain mis-match */
+ if (their_at_domain != 0 && (my_at_domain == 0
+ || strcasecmp(their_at_domain, my_at_domain) != 0))
+ return (0); /* sender domain mis-match */
+
+ /*
+ * Check the time-dependent portion.
+ */
+ if (var_verify_sender_ttl > 0) {
+ their_epoch = safe_strtoul(addr + base_len, &cp, VERIFY_BASE);
+ if ((*cp != '@' && *cp != 0)
+ || (their_epoch == ULONG_MAX && errno == ERANGE))
+ return (0); /* malformed time stamp */
+ my_epoch = VERIFY_SENDER_ADDR_EPOCH();
+ if (their_epoch < my_epoch - 1 || their_epoch > my_epoch + 1)
+ return (0); /* outside time window */
+ }
+
+ /*
+ * No time-dependent portion.
+ */
+ else {
+ if (addr[base_len] != '@' && addr[base_len] != 0)
+ return (0); /* garbage after sender base */
+ }
+ return (STR(fixed_sender_buf));
+}
+
+ /*
+ * Proof-of-concept test program. Read test address_verify_sender and
+ * address_verify_sender_ttl values from stdin, and report results that we
+ * would get on stdout.
+ */
+#ifdef TEST
+
+#include <stdlib.h>
+#include <vstream.h>
+#include <msg_vstream.h>
+#include <vstring_vstream.h>
+#include <mail_conf.h>
+#include <conv_time.h>
+
+int main(int argc, char **argv)
+{
+ const char *verify_sender;
+ const char *valid_sender;
+
+ msg_vstream_init(argv[0], VSTREAM_ERR);
+
+ /*
+ * Prepare to talk to the address rewriting service.
+ */
+ mail_conf_read();
+ vstream_printf("using config files in %s\n", var_config_dir);
+ if (chdir(var_queue_dir) < 0)
+ msg_fatal("chdir %s: %m", var_queue_dir);
+
+ /*
+ * Parse JCL.
+ */
+ if (argc != 3)
+ msg_fatal("usage: %s address_verify_sender address_verify_sender_ttl",
+ argv[0]);
+ var_verify_sender = argv[1];
+ if (conv_time(argv[2], &var_verify_sender_ttl, 's') == 0)
+ msg_fatal("bad time value: %s", argv[2]);
+ verify_time = time((time_t *) 0);
+
+ /*
+ * Compute the current probe sender addres.
+ */
+ verify_sender = make_verify_sender_addr();
+
+ /*
+ * Check two past time slots.
+ */
+ if (var_verify_sender_ttl > 0) {
+ verify_time -= 2 * var_verify_sender_ttl;
+ vstream_printf("\"%s\" matches prev2: \"%s\"\n", verify_sender,
+ (valid_sender = valid_verify_sender_addr(verify_sender)) != 0 ?
+ valid_sender : "nope");
+ verify_time += var_verify_sender_ttl;
+ vstream_printf("\"%s\" matches prev1: \"%s\"\n", verify_sender,
+ (valid_sender = valid_verify_sender_addr(verify_sender)) != 0 ?
+ valid_sender : "nope");
+ verify_time += var_verify_sender_ttl;
+ }
+
+ /*
+ * Check the current time slot.
+ */
+ vstream_printf("\"%s\" matches self: \"%s\"\n", verify_sender,
+ (valid_sender = valid_verify_sender_addr(verify_sender)) != 0 ?
+ valid_sender : "nope");
+
+ /*
+ * Check two future time slots.
+ */
+ if (var_verify_sender_ttl > 0) {
+ verify_time += var_verify_sender_ttl;
+ vstream_printf("\"%s\" matches next1: \"%s\"\n", verify_sender,
+ (valid_sender = valid_verify_sender_addr(verify_sender)) != 0 ?
+ valid_sender : "nope");
+ verify_time += var_verify_sender_ttl;
+ vstream_printf("\"%s\" matches next2: \"%s\"\n", verify_sender,
+ (valid_sender = valid_verify_sender_addr(verify_sender)) != 0 ?
+ valid_sender : "nope");
+ }
+ vstream_fflush(VSTREAM_OUT);
+ exit(0);
+}
+
+#endif
--- /dev/null
+#ifndef _VERIFY_SENDER_ADDR_H_INCLUDED_
+#define _VERIFY_SENDER_ADDR_H_INCLUDED_
+
+/*++
+/* NAME
+/* verify_sender_addr 3h
+/* SUMMARY
+/* address verify sender utilities
+/* SYNOPSIS
+/* #include <verify_sender_addr.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External interface.
+ */
+const char *make_verify_sender_addr(void);
+const char *valid_verify_sender_addr(const char *);
+
+/* 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
+/*--*/
+
+#endif
--- /dev/null
+using config files in CONFIGDIR
+"aa@bb.MYDOMAIN" matches self: "aa@bb.MYDOMAIN"
+using config files in CONFIGDIR
+"aaSTAMP@bb.MYDOMAIN" matches prev2: "nope"
+"aaSTAMP@bb.MYDOMAIN" matches prev1: "aa@bb.MYDOMAIN"
+"aaSTAMP@bb.MYDOMAIN" matches self: "aa@bb.MYDOMAIN"
+"aaSTAMP@bb.MYDOMAIN" matches next1: "aa@bb.MYDOMAIN"
+"aaSTAMP@bb.MYDOMAIN" matches next2: "nope"
+using config files in CONFIGDIR
+"aa@MYORIGIN" matches self: "aa@MYORIGIN"
+using config files in CONFIGDIR
+"aaSTAMP@MYORIGIN" matches prev2: "nope"
+"aaSTAMP@MYORIGIN" matches prev1: "aa@MYORIGIN"
+"aaSTAMP@MYORIGIN" matches self: "aa@MYORIGIN"
+"aaSTAMP@MYORIGIN" matches next1: "aa@MYORIGIN"
+"aaSTAMP@MYORIGIN" matches next2: "nope"
+using config files in CONFIGDIR
+"" matches self: ""
+using config files in CONFIGDIR
+"" matches prev2: ""
+"" matches prev1: ""
+"" matches self: ""
+"" matches next1: ""
+"" matches next2: ""
tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 \
- test22
+ test22 test23 test24 test25
root_tests:
rm -f main.cf master.cf test4.tmp
# Define one user-defined parameter with name=value in master.cf,
-# validate it with known_parameter=$name in master.cf.
+# validate it with known_parameter=$$name in master.cf.
test5: $(PROG) test5.ref
rm -f main.cf master.cf
diff test22.ref test22.tmp
rm -f main.cf master.cf test22.tmp
+# Test the -C flag.
+
+test23: $(PROG) test23.ref
+ rm -f main.cf master.cf
+ touch main.cf master.cf
+ echo always_bcc = yes >> main.cf
+ echo name = value >> main.cf
+ echo whatevershebrings unix - n n - 0 smtp >> master.cf
+ echo ' -o always_bcc=$$name' >> master.cf
+ ./$(PROG) -c . -nC builtin >test23.tmp 2>&1
+ diff test23.ref test23.tmp
+ rm -f main.cf master.cf test23.tmp
+
+test24: $(PROG) test24.ref
+ rm -f main.cf master.cf
+ touch main.cf master.cf
+ echo always_bcc = yes >> main.cf
+ echo name = value >> main.cf
+ echo whatevershebrings unix - n n - 0 smtp >> master.cf
+ echo ' -o always_bcc=$$name' >> master.cf
+ ./$(PROG) -c . -nC user >test24.tmp 2>&1
+ diff test24.ref test24.tmp
+ rm -f main.cf master.cf test24.tmp
+
+test25: $(PROG) test25.ref
+ rm -f main.cf master.cf
+ touch main.cf master.cf
+ echo always_bcc = yes >> main.cf
+ echo name = value >> main.cf
+ echo whatevershebrings unix - n n - 0 smtp >> master.cf
+ echo ' -o always_bcc=$$name' >> master.cf
+ ./$(PROG) -c . -C service 2>&1 | grep whatevershebrings >test25.tmp
+ diff test25.ref test25.tmp
+ rm -f main.cf master.cf test25.tmp
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
/* \fBManaging main.cf:\fR
/*
/* \fBpostconf\fR [\fB-dfhnv\fR] [\fB-c \fIconfig_dir\fR]
-/* [\fB-C \fIclass\fR] [\fIparameter ...\fR]
+/* [\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
/*
/* \fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
/* [\fIparameter=value ...\fR]
/* instead of the default configuration directory.
/* .IP "\fB-C \fIclass,...\fR"
/* When displaying \fBmain.cf\fR parameters, select only
-/* parameters from the specified class(es), specified as a
-/* comma-separated list:
+/* parameters from the specified class(es):
/* .RS
/* .IP \fBbuiltin\fR
/* Parameters with built-in names.
/* .IP \fBuser\fR
/* Parameters with user-defined names.
/* .RE
+/* .IP
+/* The default is as if "\fB-C builtin,service,user\fR" is
+/* specified.
/* .IP \fB-d\fR
/* Print \fBmain.cf\fR default parameter settings instead of
/* actual settings.
/*
/* If \fIservice ...\fR is specified, only the matching services
/* will be output. For example, "\fBpostconf -Mf inet\fR"
-/* will match all services that listen on the network.
+/* will output all services that listen on the network.
/*
/* Specify zero or more arguments, each with a \fIservice-type\fR
/* name (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR)
*/
if ((node = PC_PARAM_TABLE_FIND(param_table, name)) != 0) {
PC_PARAM_CLASS_OVERRIDE(node, PC_PARAM_FLAG_SERVICE);
- myfree(name);
} else {
PC_PARAM_TABLE_ENTER(param_table, name, PC_PARAM_FLAG_SERVICE,
(char *) defparam, convert_service_parameter);
}
+ myfree(name);
}
/* register_service_parameters - add all service parameters with defaults */
--- /dev/null
+always_bcc = yes
+config_directory = .
--- /dev/null
+name = value
--- /dev/null
+whatevershebrings_delivery_slot_cost = $default_delivery_slot_cost
+whatevershebrings_delivery_slot_discount = $default_delivery_slot_discount
+whatevershebrings_delivery_slot_loan = $default_delivery_slot_loan
+whatevershebrings_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+whatevershebrings_destination_concurrency_limit = $default_destination_concurrency_limit
+whatevershebrings_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+whatevershebrings_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+whatevershebrings_destination_rate_delay = $default_destination_rate_delay
+whatevershebrings_destination_recipient_limit = $default_destination_recipient_limit
+whatevershebrings_extra_recipient_limit = $default_extra_recipient_limit
+whatevershebrings_initial_destination_concurrency = $initial_destination_concurrency
+whatevershebrings_minimum_delivery_slots = $default_minimum_delivery_slots
+whatevershebrings_recipient_limit = $default_recipient_limit
+whatevershebrings_recipient_refill_delay = $default_recipient_refill_delay
+whatevershebrings_recipient_refill_limit = $default_recipient_refill_limit
smtpd.o: ../../include/valid_hostname.h
smtpd.o: ../../include/valid_mailhost_addr.h
smtpd.o: ../../include/vbuf.h
+smtpd.o: ../../include/verify_sender_addr.h
smtpd.o: ../../include/verp_sender.h
smtpd.o: ../../include/vstream.h
smtpd.o: ../../include/vstring.h
/* .IP "\fBunverified_recipient_tempfail_action ($reject_tempfail_action)\fR"
/* The Postfix SMTP server's action when reject_unverified_recipient
/* fails due to a temporary error condition.
+/* .PP
+/* Available with Postfix 2.9 and later:
+/* .IP "\fBaddress_verify_sender_ttl (0s)\fR"
+/* The time between changes in the time-dependent portion of address
+/* verification probe sender addresses.
/* ACCESS CONTROL RESPONSES
/* .ad
/* .fi
#include <dsn_mask.h>
#include <xtext.h>
#include <tls_proxy.h>
+#include <verify_sender_addr.h>
/* Single-threaded server skeleton. */
char *var_unv_rcpt_why;
int var_mul_rcpt_code;
char *var_relay_rcpt_maps;
-char *var_verify_sender;
int var_local_rcpt_code;
int var_virt_alias_code;
int var_virt_mailbox_code;
return (-1);
}
if (SMTPD_STAND_ALONE(state) == 0) {
- err = smtpd_check_rcpt(state, STR(state->addr_buf));
+ const char *verify_sender;
+
+ /*
+ * XXX Don't reject the address when we're probed with our own
+ * address verification sender address. Otherwise, some timeout or
+ * some UCE block may result in mutual negative caching, making it
+ * painful to get the mail through. Unfortunately we still have to
+ * send the address to the Milters otherwise they may bail out with a
+ * "missing recipient" protocol error.
+ */
+ verify_sender = valid_verify_sender_addr(STR(state->addr_buf));
+ if (verify_sender != 0) {
+ vstring_strcpy(state->addr_buf, verify_sender);
+ err = 0;
+ } else {
+ err = smtpd_check_rcpt(state, STR(state->addr_buf));
+ }
if (smtpd_milters != 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) {
PUSH_STRING(saved_rcpt, state->recipient, STR(state->addr_buf));
VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, &var_milt_conn_time, 1, 0,
VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, &var_milt_cmd_time, 1, 0,
VAR_MILT_MSG_TIME, DEF_MILT_MSG_TIME, &var_milt_msg_time, 1, 0,
+ VAR_VERIFY_SENDER_TTL, DEF_VERIFY_SENDER_TTL, &var_verify_sender_ttl, 0, 0,
0,
};
static const CONFIG_BOOL_TABLE bool_table[] = {
#include <namadr_list.h>
#include <domain_list.h>
#include <mail_params.h>
-#include <rewrite_clnt.h>
#include <resolve_clnt.h>
#include <mail_error.h>
#include <resolve_local.h>
#include <verify_clnt.h>
#include <input_transp.h>
#include <is_header.h>
-#include <rewrite_clnt.h>
#include <valid_mailhost_addr.h>
#include <dsn_util.h>
#include <conv_time.h>
int status;
char *saved_recipient;
char *err;
- static VSTRING *canon_verify_sender;
/*
* Initialize.
if (strcasecmp(recipient, "postmaster") == 0)
return (0);
- /*
- * XXX Always say OK when we're probed with our own address verification
- * sender address. Otherwise, some timeout or some UCE block may result
- * in mutual negative caching, making it painful to get the mail through.
- */
-#ifndef TEST
- if (*recipient) {
- if (canon_verify_sender == 0) {
- canon_verify_sender = vstring_alloc(10);
- rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL,
- var_verify_sender,
- canon_verify_sender);
- }
- if (strcasecmp(STR(canon_verify_sender), recipient) == 0)
- return (0);
- }
-#endif
-
/*
* Minor kluge so that we can delegate work to the generic routine and so
* that we can syslog the recipient with the reject messages.
#include <vstring_vstream.h>
#include <mail_conf.h>
+#include <rewrite_clnt.h>
#include <smtpd_chat.h>
verify.o: ../../include/sys_defs.h
verify.o: ../../include/vbuf.h
verify.o: ../../include/verify_clnt.h
+verify.o: ../../include/verify_sender_addr.h
verify.o: ../../include/vstream.h
verify.o: ../../include/vstring.h
verify.o: verify.c
/*
/* The text below provides only a parameter summary. See
/* \fBpostconf\fR(5) for more details including examples.
+/* PROBE MESSAGE CONTROLS
+/* .ad
+/* .fi
+/* .IP "\fBaddress_verify_sender ($double_bounce_sender)\fR"
+/* The sender address to use in address verification probes; prior
+/* to Postfix 2.5 the default was "postmaster".
+/* .PP
+/* Available with Postfix 2.9 and later:
+/* .IP "\fBaddress_verify_sender_ttl (0s)\fR"
+/* The time between changes in the time-dependent portion of address
+/* verification probe sender addresses.
/* CACHE CONTROLS
/* .ad
/* .fi
/* .IP "\fBaddress_verify_map (see 'postconf -d' output)\fR"
/* Lookup table for persistent address verification status
/* storage.
-/* .IP "\fBaddress_verify_sender ($double_bounce_sender)\fR"
-/* The sender address to use in address verification probes; prior
-/* to Postfix 2.5 the default was "postmaster".
/* .IP "\fBaddress_verify_positive_expire_time (31d)\fR"
/* The time after which a successful probe expires from the address
/* verification cache.
#include <post_mail.h>
#include <data_redirect.h>
#include <verify_clnt.h>
+#include <verify_sender_addr.h>
/* Server skeleton. */
int var_verify_neg_exp;
int var_verify_neg_try;
int var_verify_scan_cache;
-char *var_verify_sender;
/*
* State.
if (msg_verbose)
msg_info("PROBE %s status=%d probed=%ld updated=%ld",
STR(addr), addr_status, now, updated);
- post_mail_fopen_async(strcmp(var_verify_sender, "<>") == 0 ?
- "" : var_verify_sender, STR(addr),
+ post_mail_fopen_async(make_verify_sender_addr(), STR(addr),
INT_FILT_MASK_NONE,
DEL_REQ_FLAG_MTA_VRFY,
(VSTRING *) 0,
VAR_VERIFY_NEG_EXP, DEF_VERIFY_NEG_EXP, &var_verify_neg_exp, 1, 0,
VAR_VERIFY_NEG_TRY, DEF_VERIFY_NEG_TRY, &var_verify_neg_try, 1, 0,
VAR_VERIFY_SCAN_CACHE, DEF_VERIFY_SCAN_CACHE, &var_verify_scan_cache, 0, 0,
+ VAR_VERIFY_SENDER_TTL, DEF_VERIFY_SENDER_TTL, &var_verify_sender_ttl, 0, 0,
0,
};