mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-28 12:48:01 +00:00
postfix-2.8-20101108
This commit is contained in:
parent
925f7004f2
commit
83f3d1e20c
@ -16123,3 +16123,16 @@ Apologies for any names omitted.
|
||||
notify" as with Postfix automatically-added BCC recipients.
|
||||
Files: cleanup/cleanup_addr.c, cleanup/cleanup.h,
|
||||
cleanup/cleanup_milter.c.
|
||||
|
||||
20101105
|
||||
|
||||
Feature: DNS whitelist support in the Postfix SMTP server.
|
||||
permit_dnswl_client whitelists a client by IP address, and
|
||||
permit_rhswl_client whitelists a client by its hostname.
|
||||
The syntax is the same as reject_rbl_client etc., but the
|
||||
result is PERMIT instead of REJECT. For safety reasons,
|
||||
permit_xxx_client are silently ignored when they would
|
||||
override reject_unauth_destination. The result is
|
||||
DEFER_IF_REJECT when DNSWL lookup fails. The implementation
|
||||
is based on a design documented by Noel Jones (August 2010).
|
||||
File: smtpd/smtpd_check.c.
|
||||
|
@ -33,6 +33,26 @@ This is supported only when the default value is stress-dependent
|
||||
postscreen parameters always evaluate as if the stress value is
|
||||
equal to the empty string.
|
||||
|
||||
Major changes with snapshot 20101105
|
||||
====================================
|
||||
|
||||
The Postfix SMTP server now supports DNS-based whitelisting with
|
||||
several safety features: permit_dnswl_client whitelists a client
|
||||
by IP address, and permit_rhswl_client whitelists a client by its
|
||||
hostname. These features use the same syntax as reject_rbl_client
|
||||
and reject_rhsbl_client, respectively. The main difference is that
|
||||
they return PERMIT instead of REJECT.
|
||||
|
||||
Whitelisting is primarily a tool to reduce the false positive rate
|
||||
of DNS blocklist lookups. Client name whitelisting should not be
|
||||
used to make exceptions to access rules. The reason is that client
|
||||
name lookup can fail unpredictably due to some temporary outage.
|
||||
|
||||
For safety reasons, permit_dnswl_client and permit_rhswl_client are
|
||||
silently ignored when they would override reject_unauth_destination.
|
||||
Also for safety reasons, the result is DEFER_IF_REJECT when DNS
|
||||
whitelist lookup fails (this result will be made configurable).
|
||||
|
||||
Incompatibility with snapshot 20101103
|
||||
======================================
|
||||
|
||||
|
@ -4,6 +4,11 @@ Wish list:
|
||||
|
||||
anvil rate limit for sasl_username.
|
||||
|
||||
permit_tempfail_action (default: defer_if_reject) to be
|
||||
used as the default value for dnswl_tempfail_action and
|
||||
rhswl_tempfail_action. Steal liberally from the code that
|
||||
implements unverified_recipient_tempfail_action etc.
|
||||
|
||||
Support filtering of messages that are generated by Postfix:
|
||||
This would apply to postmaster notices and bounce messages
|
||||
(DKIM), and address verification (BATV).
|
||||
|
@ -74,10 +74,13 @@
|
||||
# The pattern domain.tld also matches subdomains, but
|
||||
# only when the string smtpd_access_maps is listed in
|
||||
# the Postfix parent_domain_matches_subdomains con-
|
||||
# figuration setting (note that this is the default
|
||||
# for some versions of Postfix). Otherwise, specify
|
||||
# .domain.tld (note the initial dot) in order to
|
||||
# match subdomains.
|
||||
# figuration setting.
|
||||
#
|
||||
# .domain.tld
|
||||
# Matches subdomains of domain.tld, but only when the
|
||||
# string smtpd_access_maps is not listed in the Post-
|
||||
# fix parent_domain_matches_subdomains configuration
|
||||
# setting.
|
||||
#
|
||||
# user@ Matches all mail addresses with the specified user
|
||||
# part.
|
||||
@ -105,9 +108,13 @@
|
||||
# The pattern domain.tld also matches subdomains, but
|
||||
# only when the string smtpd_access_maps is listed in
|
||||
# the Postfix parent_domain_matches_subdomains con-
|
||||
# figuration setting. Otherwise, specify .domain.tld
|
||||
# (note the initial dot) in order to match subdo-
|
||||
# mains.
|
||||
# figuration setting.
|
||||
#
|
||||
# .domain.tld
|
||||
# Matches subdomains of domain.tld, but only when the
|
||||
# string smtpd_access_maps is not listed in the Post-
|
||||
# fix parent_domain_matches_subdomains configuration
|
||||
# setting.
|
||||
#
|
||||
# net.work.addr.ess
|
||||
#
|
||||
|
@ -80,10 +80,13 @@ ACCESS(5) ACCESS(5)
|
||||
The pattern <i>domain.tld</i> also matches subdomains, but
|
||||
only when the string <b>smtpd_access_maps</b> is listed in
|
||||
the Postfix <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a></b> con-
|
||||
figuration setting (note that this is the default
|
||||
for some versions of Postfix). Otherwise, specify
|
||||
<i>.domain.tld</i> (note the initial dot) in order to
|
||||
match subdomains.
|
||||
figuration setting.
|
||||
|
||||
<i>.domain.tld</i>
|
||||
Matches subdomains of <i>domain.tld</i>, but only when the
|
||||
string <b>smtpd_access_maps</b> is not listed in the Post-
|
||||
fix <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a></b> configuration
|
||||
setting.
|
||||
|
||||
<i>user</i>@ Matches all mail addresses with the specified user
|
||||
part.
|
||||
@ -111,9 +114,13 @@ ACCESS(5) ACCESS(5)
|
||||
The pattern <i>domain.tld</i> also matches subdomains, but
|
||||
only when the string <b>smtpd_access_maps</b> is listed in
|
||||
the Postfix <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a></b> con-
|
||||
figuration setting. Otherwise, specify <i>.domain.tld</i>
|
||||
(note the initial dot) in order to match subdo-
|
||||
mains.
|
||||
figuration setting.
|
||||
|
||||
<i>.domain.tld</i>
|
||||
Matches subdomains of <i>domain.tld</i>, but only when the
|
||||
string <b>smtpd_access_maps</b> is not listed in the Post-
|
||||
fix <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a></b> configuration
|
||||
setting.
|
||||
|
||||
<i>net.work.addr.ess</i>
|
||||
|
||||
|
@ -11688,7 +11688,18 @@ specifies the default server reply, and the <a href="postconf.5.html#rbl_reply_m
|
||||
specifies tables with server replies indexed by <i>rbl_domain</i>.
|
||||
This feature is available in Postfix 2.0 and later. </dd>
|
||||
|
||||
<dt><b><a name="reject_rhsbl_client">reject_rhsbl_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
|
||||
<dt><b><a name="permit_dnswl_client">permit_dnswl_client <i>dnswl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Accept the request when the reversed client network address is
|
||||
listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>.
|
||||
If no "<i>=d.d.d.d</i>" is specified, accept the request when the
|
||||
reversed client network address is listed with any A record under
|
||||
<i>dnswl_domain</i>. <br> For safety, <a href="postconf.5.html#permit_dnswl_client">permit_dnswl_client</a> is silently
|
||||
ignored when it would override <a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>. The
|
||||
result is DEFER_IF_REJECT when whitelist lookup fails. This feature
|
||||
is available in Postfix 2.8 and later. </dd>
|
||||
|
||||
</dd> <dt><b><a name="reject_rhsbl_client">reject_rhsbl_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Reject the request when the client hostname is listed with the
|
||||
A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
|
||||
@ -11700,6 +11711,21 @@ This feature is available in Postfix 2.0 and later; with Postfix
|
||||
version 2.8 and later, <a href="postconf.5.html#reject_rhsbl_reverse_client">reject_rhsbl_reverse_client</a> will usually
|
||||
produce better results. </dd>
|
||||
|
||||
</dd> <dt><b><a name="permit_rhswl_client">permit_rhswl_client <i>rhswl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Accept the request when the client hostname is listed with the
|
||||
A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. If no
|
||||
"<i>=d.d.d.d</i>" is specified, accept the request when the client
|
||||
hostname is listed with any A record under <i>rhswl_domain</i>.
|
||||
<br> Caution: client name whitelisting is fragile, since the client
|
||||
name lookup can fail due to temporary outages. Client name
|
||||
whitelisting should be used only to reduce false positives in e.g.
|
||||
DNS-based blocklists, and not for making access rule exceptions.
|
||||
<br> For safety, <a href="postconf.5.html#permit_rhswl_client">permit_rhswl_client</a> is silently ignored when it
|
||||
would override <a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>. The result is DEFER_IF_REJECT
|
||||
when whitelist lookup fails. This feature is available in Postfix
|
||||
2.8 and later. </dd>
|
||||
|
||||
<dt><b><a name="reject_rhsbl_reverse_client">reject_rhsbl_reverse_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Reject the request when the unverified reverse client hostname
|
||||
|
@ -77,10 +77,11 @@ Matches \fIdomain.tld\fR as the domain part of an email address.
|
||||
.sp
|
||||
The pattern \fIdomain.tld\fR also matches subdomains, but only
|
||||
when the string \fBsmtpd_access_maps\fR is listed in the Postfix
|
||||
\fBparent_domain_matches_subdomains\fR configuration setting
|
||||
(note that this is the default for some versions of Postfix).
|
||||
Otherwise, specify \fI.domain.tld\fR (note the initial dot) in
|
||||
order to match subdomains.
|
||||
\fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
.IP \fI.domain.tld\fR
|
||||
Matches subdomains of \fIdomain.tld\fR, but only when the
|
||||
string \fBsmtpd_access_maps\fR is not listed in the Postfix
|
||||
\fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
.IP \fIuser\fR@
|
||||
Matches all mail addresses with the specified user part.
|
||||
.PP
|
||||
@ -112,8 +113,10 @@ Matches \fIdomain.tld\fR.
|
||||
The pattern \fIdomain.tld\fR also matches subdomains, but only
|
||||
when the string \fBsmtpd_access_maps\fR is listed in the Postfix
|
||||
\fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
Otherwise, specify \fI.domain.tld\fR (note the initial dot) in
|
||||
order to match subdomains.
|
||||
.IP \fI.domain.tld\fR
|
||||
Matches subdomains of \fIdomain.tld\fR, but only when the
|
||||
string \fBsmtpd_access_maps\fR is not listed in the Postfix
|
||||
\fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
.IP \fInet.work.addr.ess\fR
|
||||
.IP \fInet.work.addr\fR
|
||||
.IP \fInet.work\fR
|
||||
|
@ -7175,6 +7175,17 @@ rejected requests (default: 554), the default_rbl_reply parameter
|
||||
specifies the default server reply, and the rbl_reply_maps parameter
|
||||
specifies tables with server replies indexed by \fIrbl_domain\fR.
|
||||
This feature is available in Postfix 2.0 and later.
|
||||
.IP "\fBpermit_dnswl_client \fIdnswl_domain=d.d.d.d\fR\fR"
|
||||
Accept the request when the reversed client network address is
|
||||
listed with the A record "\fId.d.d.d\fR" under \fIdnswl_domain\fR.
|
||||
If no "\fI=d.d.d.d\fR" is specified, accept the request when the
|
||||
reversed client network address is listed with any A record under
|
||||
\fIdnswl_domain\fR.
|
||||
.br
|
||||
For safety, permit_dnswl_client is silently
|
||||
ignored when it would override reject_unauth_destination. The
|
||||
result is DEFER_IF_REJECT when whitelist lookup fails. This feature
|
||||
is available in Postfix 2.8 and later.
|
||||
.IP "\fBreject_rhsbl_client \fIrbl_domain=d.d.d.d\fR\fR"
|
||||
Reject the request when the client hostname is listed with the
|
||||
A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix version
|
||||
@ -7185,6 +7196,21 @@ description above for additional RBL related configuration parameters.
|
||||
This feature is available in Postfix 2.0 and later; with Postfix
|
||||
version 2.8 and later, reject_rhsbl_reverse_client will usually
|
||||
produce better results.
|
||||
.IP "\fBpermit_rhswl_client \fIrhswl_domain=d.d.d.d\fR\fR"
|
||||
Accept the request when the client hostname is listed with the
|
||||
A record "\fId.d.d.d\fR" under \fIrhswl_domain\fR. If no
|
||||
"\fI=d.d.d.d\fR" is specified, accept the request when the client
|
||||
hostname is listed with any A record under \fIrhswl_domain\fR.
|
||||
.br
|
||||
Caution: client name whitelisting is fragile, since the client
|
||||
name lookup can fail due to temporary outages. Client name
|
||||
whitelisting should be used only to reduce false positives in e.g.
|
||||
DNS-based blocklists, and not for making access rule exceptions.
|
||||
.br
|
||||
For safety, permit_rhswl_client is silently ignored when it
|
||||
would override reject_unauth_destination. The result is DEFER_IF_REJECT
|
||||
when whitelist lookup fails. This feature is available in Postfix
|
||||
2.8 and later.
|
||||
.IP "\fBreject_rhsbl_reverse_client \fIrbl_domain=d.d.d.d\fR\fR"
|
||||
Reject the request when the unverified reverse client hostname
|
||||
is listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR.
|
||||
|
@ -835,6 +835,8 @@ while (<>) {
|
||||
s;\breject_rbl_client\b;<a href="postconf.5.html#reject_rbl_client">$&</a>;g;
|
||||
s;\breject_rhsbl_client\b;<a href="postconf.5.html#reject_rhsbl_client">$&</a>;g;
|
||||
s;\breject_rhsbl_reverse_client\b;<a href="postconf.5.html#reject_rhsbl_reverse_client">$&</a>;g;
|
||||
s;\bpermit_dnswl_client\b;<a href="postconf.5.html#permit_dnswl_client">$&</a>;g;
|
||||
s;\bpermit_rhswl_client\b;<a href="postconf.5.html#permit_rhswl_client">$&</a>;g;
|
||||
|
||||
# Access restrictions - helo
|
||||
|
||||
|
@ -65,10 +65,11 @@
|
||||
# .sp
|
||||
# The pattern \fIdomain.tld\fR also matches subdomains, but only
|
||||
# when the string \fBsmtpd_access_maps\fR is listed in the Postfix
|
||||
# \fBparent_domain_matches_subdomains\fR configuration setting
|
||||
# (note that this is the default for some versions of Postfix).
|
||||
# Otherwise, specify \fI.domain.tld\fR (note the initial dot) in
|
||||
# order to match subdomains.
|
||||
# \fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
# .IP \fI.domain.tld\fR
|
||||
# Matches subdomains of \fIdomain.tld\fR, but only when the
|
||||
# string \fBsmtpd_access_maps\fR is not listed in the Postfix
|
||||
# \fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
# .IP \fIuser\fR@
|
||||
# Matches all mail addresses with the specified user part.
|
||||
# .PP
|
||||
@ -96,8 +97,10 @@
|
||||
# The pattern \fIdomain.tld\fR also matches subdomains, but only
|
||||
# when the string \fBsmtpd_access_maps\fR is listed in the Postfix
|
||||
# \fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
# Otherwise, specify \fI.domain.tld\fR (note the initial dot) in
|
||||
# order to match subdomains.
|
||||
# .IP \fI.domain.tld\fR
|
||||
# Matches subdomains of \fIdomain.tld\fR, but only when the
|
||||
# string \fBsmtpd_access_maps\fR is not listed in the Postfix
|
||||
# \fBparent_domain_matches_subdomains\fR configuration setting.
|
||||
# .IP \fInet.work.addr.ess\fR
|
||||
# .IP \fInet.work.addr\fR
|
||||
# .IP \fInet.work\fR
|
||||
|
@ -4888,6 +4888,17 @@ specifies the default server reply, and the rbl_reply_maps parameter
|
||||
specifies tables with server replies indexed by <i>rbl_domain</i>.
|
||||
This feature is available in Postfix 2.0 and later. </dd>
|
||||
|
||||
<dt><b><a name="permit_dnswl_client">permit_dnswl_client <i>dnswl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Accept the request when the reversed client network address is
|
||||
listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>.
|
||||
If no "<i>=d.d.d.d</i>" is specified, accept the request when the
|
||||
reversed client network address is listed with any A record under
|
||||
<i>dnswl_domain</i>. <br> For safety, permit_dnswl_client is silently
|
||||
ignored when it would override reject_unauth_destination. The
|
||||
result is DEFER_IF_REJECT when whitelist lookup fails. This feature
|
||||
is available in Postfix 2.8 and later. </dd>
|
||||
|
||||
<dt><b><a name="reject_rhsbl_client">reject_rhsbl_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Reject the request when the client hostname is listed with the
|
||||
@ -4900,6 +4911,21 @@ This feature is available in Postfix 2.0 and later; with Postfix
|
||||
version 2.8 and later, reject_rhsbl_reverse_client will usually
|
||||
produce better results. </dd>
|
||||
|
||||
</dd> <dt><b><a name="permit_rhswl_client">permit_rhswl_client <i>rhswl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Accept the request when the client hostname is listed with the
|
||||
A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. If no
|
||||
"<i>=d.d.d.d</i>" is specified, accept the request when the client
|
||||
hostname is listed with any A record under <i>rhswl_domain</i>.
|
||||
<br> Caution: client name whitelisting is fragile, since the client
|
||||
name lookup can fail due to temporary outages. Client name
|
||||
whitelisting should be used only to reduce false positives in e.g.
|
||||
DNS-based blocklists, and not for making access rule exceptions.
|
||||
<br> For safety, permit_rhswl_client is silently ignored when it
|
||||
would override reject_unauth_destination. The result is DEFER_IF_REJECT
|
||||
when whitelist lookup fails. This feature is available in Postfix
|
||||
2.8 and later. </dd>
|
||||
|
||||
<dt><b><a name="reject_rhsbl_reverse_client">reject_rhsbl_reverse_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
|
||||
|
||||
<dd>Reject the request when the unverified reverse client hostname
|
||||
|
@ -2151,6 +2151,9 @@ extern int var_map_defer_code;
|
||||
#define REJECT_RHSBL_SENDER "reject_rhsbl_sender"
|
||||
#define REJECT_RHSBL_RECIPIENT "reject_rhsbl_recipient"
|
||||
|
||||
#define PERMIT_DNSWL_CLIENT "permit_dnswl_client"
|
||||
#define PERMIT_RHSWL_CLIENT "permit_rhswl_client"
|
||||
|
||||
#define VAR_RBL_REPLY_MAPS "rbl_reply_maps"
|
||||
#define DEF_RBL_REPLY_MAPS ""
|
||||
extern char *var_rbl_reply_maps;
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20101103"
|
||||
#define MAIL_RELEASE_DATE "20101108"
|
||||
#define MAIL_VERSION_NUMBER "2.8"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -66,7 +66,7 @@ tidy: clean
|
||||
|
||||
tests: smtpd_check_test smtpd_check_test2 smtpd_acl_test smtpd_exp_test \
|
||||
smtpd_token_test smtpd_check_test4 smtpd_check_dsn_test \
|
||||
smtpd_check_backup_test
|
||||
smtpd_check_backup_test smtpd_dnswl_test
|
||||
|
||||
root_tests:
|
||||
|
||||
@ -124,6 +124,13 @@ smtpd_token_test: smtpd_token smtpd_token.in smtpd_token.ref
|
||||
diff smtpd_token.ref smtpd_token.tmp
|
||||
rm -f smtpd_token.tmp
|
||||
|
||||
# This requires that the DNS server can query porcupine.org and rfc-ignorant.org
|
||||
|
||||
smtpd_dnswl_test: smtpd_check smtpd_dnswl.in smtpd_dnswl.ref
|
||||
./smtpd_check <smtpd_dnswl.in >smtpd_dnswl.tmp 2>&1
|
||||
diff smtpd_dnswl.ref smtpd_dnswl.tmp
|
||||
rm -f smtpd_dnswl.tmp
|
||||
|
||||
depend: $(MAKES)
|
||||
(sed '1,/^# do not edit/!d' Makefile.in; \
|
||||
set -e; for i in [a-z][a-z0-9]*.c; do \
|
||||
|
@ -2939,6 +2939,15 @@ static const char *smtpd_expand_lookup(const char *name, int unused_mode,
|
||||
}
|
||||
}
|
||||
|
||||
/* Support for different DNSXL lookup results. */
|
||||
|
||||
static SMTPD_RBL_STATE dnsxl_stat_soft[1];
|
||||
|
||||
#define SMTPD_DNSXL_STAT_SOFT(dnsxl_res) ((dnsxl_res) == dnsxl_stat_soft)
|
||||
#define SMTPD_DNXSL_STAT_HARD(dnsxl_res) ((dnsxl_res) == 0)
|
||||
#define SMTPD_DNSXL_STAT_OK(dnsxl_res) \
|
||||
!(SMTPD_DNXSL_STAT_HARD(dnsxl_res) || SMTPD_DNSXL_STAT_SOFT(dnsxl_res))
|
||||
|
||||
/* rbl_pagein - look up an RBL lookup result */
|
||||
|
||||
static void *rbl_pagein(const char *query, void *unused_context)
|
||||
@ -2947,7 +2956,7 @@ static void *rbl_pagein(const char *query, void *unused_context)
|
||||
DNS_RR *txt_list;
|
||||
VSTRING *why;
|
||||
int dns_status;
|
||||
SMTPD_RBL_STATE *rbl;
|
||||
SMTPD_RBL_STATE *rbl = 0;
|
||||
DNS_RR *addr_list;
|
||||
MAI_HOSTADDR_STR hostaddr;
|
||||
DNS_RR *rr;
|
||||
@ -2964,11 +2973,13 @@ static void *rbl_pagein(const char *query, void *unused_context)
|
||||
*/
|
||||
why = vstring_alloc(10);
|
||||
dns_status = dns_lookup(query, T_A, 0, &addr_list, (VSTRING *) 0, why);
|
||||
if (dns_status != DNS_OK && dns_status != DNS_NOTFOUND)
|
||||
if (dns_status != DNS_OK && dns_status != DNS_NOTFOUND) {
|
||||
msg_warn("%s: RBL lookup error: %s", query, STR(why));
|
||||
rbl = dnsxl_stat_soft;
|
||||
}
|
||||
vstring_free(why);
|
||||
if (dns_status != DNS_OK)
|
||||
return (0);
|
||||
return ((void *) rbl);
|
||||
|
||||
/*
|
||||
* Save the result. Yes, we cache negative results as well as positive
|
||||
@ -3013,7 +3024,7 @@ static void rbl_pageout(void *data, void *unused_context)
|
||||
{
|
||||
SMTPD_RBL_STATE *rbl = (SMTPD_RBL_STATE *) data;
|
||||
|
||||
if (rbl != 0) {
|
||||
if (SMTPD_DNSXL_STAT_OK(rbl)) {
|
||||
if (rbl->txt)
|
||||
myfree(rbl->txt);
|
||||
if (rbl->a)
|
||||
@ -3059,7 +3070,7 @@ static const char *rbl_expand_lookup(const char *name, int mode,
|
||||
|
||||
/* rbl_reject_reply - format reply after RBL reject */
|
||||
|
||||
static int rbl_reject_reply(SMTPD_STATE *state, SMTPD_RBL_STATE *rbl,
|
||||
static int rbl_reject_reply(SMTPD_STATE *state, const SMTPD_RBL_STATE *rbl,
|
||||
const char *rbl_domain,
|
||||
const char *what,
|
||||
const char *reply_class)
|
||||
@ -3144,12 +3155,13 @@ static int rbl_match_addr(SMTPD_RBL_STATE *rbl, const char *addr)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* reject_rbl_addr - reject if address in real-time blackhole list */
|
||||
/* find_dnsxl_addr - look up address in DNSXL */
|
||||
|
||||
static int reject_rbl_addr(SMTPD_STATE *state, const char *rbl_domain,
|
||||
const char *addr, const char *reply_class)
|
||||
static const SMTPD_RBL_STATE *find_dnsxl_addr(SMTPD_STATE *state,
|
||||
const char *rbl_domain,
|
||||
const char *addr)
|
||||
{
|
||||
const char *myname = "reject_rbl";
|
||||
const char *myname = "find_dnsxl_addr";
|
||||
ARGV *octets;
|
||||
VSTRING *query;
|
||||
int i;
|
||||
@ -3158,9 +3170,6 @@ static int reject_rbl_addr(SMTPD_STATE *state, const char *rbl_domain,
|
||||
struct addrinfo *res;
|
||||
unsigned char *ipv6_addr;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s %s", myname, reply_class, addr);
|
||||
|
||||
query = vstring_alloc(100);
|
||||
|
||||
/*
|
||||
@ -3203,31 +3212,79 @@ static int reject_rbl_addr(SMTPD_STATE *state, const char *rbl_domain,
|
||||
rbl = (SMTPD_RBL_STATE *) ctable_locate(smtpd_rbl_cache, STR(query));
|
||||
|
||||
/*
|
||||
* If the record exists, the address is blacklisted.
|
||||
* If the record exists, match the result address.
|
||||
*/
|
||||
if (rbl == 0 || (reply_addr != 0 && !rbl_match_addr(rbl, reply_addr))) {
|
||||
if (SMTPD_DNSXL_STAT_OK(rbl) && reply_addr != 0
|
||||
&& !rbl_match_addr(rbl, reply_addr))
|
||||
rbl = 0;
|
||||
vstring_free(query);
|
||||
return (rbl);
|
||||
}
|
||||
|
||||
/* reject_rbl_addr - reject address in real-time blackhole list */
|
||||
|
||||
static int reject_rbl_addr(SMTPD_STATE *state, const char *rbl_domain,
|
||||
const char *addr, const char *reply_class)
|
||||
{
|
||||
const char *myname = "reject_rbl_addr";
|
||||
const SMTPD_RBL_STATE *rbl;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s %s", myname, reply_class, addr);
|
||||
|
||||
rbl = find_dnsxl_addr(state, rbl_domain, addr);
|
||||
if (!SMTPD_DNSXL_STAT_OK(rbl)) {
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
} else {
|
||||
vstring_free(query);
|
||||
return (rbl_reject_reply(state, rbl, rbl_domain, addr, reply_class));
|
||||
}
|
||||
}
|
||||
|
||||
/* reject_rbl_domain - reject if domain in real-time blackhole list */
|
||||
/* permit_dnswl_addr - permit address in DNSWL */
|
||||
|
||||
static int reject_rbl_domain(SMTPD_STATE *state, const char *rbl_domain,
|
||||
const char *what, const char *reply_class)
|
||||
static int permit_dnswl_addr(SMTPD_STATE *state, const char *dnswl_domain,
|
||||
const char *addr, const char *reply_class)
|
||||
{
|
||||
const char *myname = "permit_dnswl_addr";
|
||||
const SMTPD_RBL_STATE *dnswl_result;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s", myname, addr);
|
||||
|
||||
/* Safety: don't whitelist unauthorized recipients. */
|
||||
if (strcmp(state->where, SMTPD_CMD_RCPT) == 0 && state->recipient != 0
|
||||
&& permit_auth_destination(state, state->recipient) != SMTPD_CHECK_OK)
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
|
||||
dnswl_result = find_dnsxl_addr(state, dnswl_domain, addr);
|
||||
if (SMTPD_DNXSL_STAT_HARD(dnswl_result)) {
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
} else if (SMTPD_DNSXL_STAT_SOFT(dnswl_result)) {
|
||||
/* XXX: Make configurable as dnswl_tempfail_action. */
|
||||
DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
|
||||
450, "4.7.1",
|
||||
"<%s>: %s rejected: %s",
|
||||
addr, reply_class,
|
||||
"Service unavailable");
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
} else if (SMTPD_DNSXL_STAT_OK(dnswl_result)) {
|
||||
return (SMTPD_CHECK_OK);
|
||||
} else {
|
||||
/* Future proofing, in case find_dnsxl_addr() result is changed. */
|
||||
msg_panic("%s: find_dnsxl_addr API failure", myname);
|
||||
}
|
||||
}
|
||||
|
||||
/* find_dnsxl_domain - reject if domain in real-time blackhole list */
|
||||
|
||||
static const SMTPD_RBL_STATE *find_dnsxl_domain(SMTPD_STATE *state,
|
||||
const char *rbl_domain, const char *what)
|
||||
{
|
||||
const char *myname = "reject_rbl_domain";
|
||||
VSTRING *query;
|
||||
SMTPD_RBL_STATE *rbl;
|
||||
const char *domain;
|
||||
const char *reply_addr;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s %s", myname, reply_class, what);
|
||||
|
||||
/*
|
||||
* Extract the domain, tack on the RBL domain name and query the DNS for
|
||||
* an A record.
|
||||
@ -3247,17 +3304,69 @@ static int reject_rbl_domain(SMTPD_STATE *state, const char *rbl_domain,
|
||||
rbl = (SMTPD_RBL_STATE *) ctable_locate(smtpd_rbl_cache, STR(query));
|
||||
|
||||
/*
|
||||
* If the record exists, the domain is blacklisted.
|
||||
* If the record exists, match the result address.
|
||||
*/
|
||||
if (rbl == 0 || (reply_addr != 0 && !rbl_match_addr(rbl, reply_addr))) {
|
||||
if (SMTPD_DNSXL_STAT_OK(rbl) && reply_addr != 0
|
||||
&& !rbl_match_addr(rbl, reply_addr))
|
||||
rbl = 0;
|
||||
vstring_free(query);
|
||||
return (rbl);
|
||||
}
|
||||
|
||||
/* reject_rbl_domain - reject if domain in real-time blackhole list */
|
||||
|
||||
static int reject_rbl_domain(SMTPD_STATE *state, const char *rbl_domain,
|
||||
const char *what, const char *reply_class)
|
||||
{
|
||||
const char *myname = "reject_rbl_domain";
|
||||
const SMTPD_RBL_STATE *rbl;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s %s", myname, rbl_domain, what);
|
||||
|
||||
rbl = find_dnsxl_domain(state, rbl_domain, what);
|
||||
if (!SMTPD_DNSXL_STAT_OK(rbl)) {
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
} else {
|
||||
vstring_free(query);
|
||||
return (rbl_reject_reply(state, rbl, rbl_domain, what, reply_class));
|
||||
}
|
||||
}
|
||||
|
||||
/* permit_dnswl_domain - permit domain in DNSWL */
|
||||
|
||||
static int permit_dnswl_domain(SMTPD_STATE *state, const char *dnswl_domain,
|
||||
const char *what, const char *reply_class)
|
||||
{
|
||||
const char *myname = "permit_dnswl_domain";
|
||||
const SMTPD_RBL_STATE *dnswl_result;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s", myname, what);
|
||||
|
||||
/* Safety: don't whitelist unauthorized recipients. */
|
||||
if (strcmp(state->where, SMTPD_CMD_RCPT) == 0 && state->recipient != 0
|
||||
&& permit_auth_destination(state, state->recipient) != SMTPD_CHECK_OK)
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
|
||||
dnswl_result = find_dnsxl_domain(state, dnswl_domain, what);
|
||||
if (SMTPD_DNXSL_STAT_HARD(dnswl_result)) {
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
} else if (SMTPD_DNSXL_STAT_SOFT(dnswl_result)) {
|
||||
/* XXX: Make configurable as rhswl_tempfail_action. */
|
||||
DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
|
||||
450, "4.7.1",
|
||||
"<%s>: %s rejected: %s",
|
||||
what, reply_class,
|
||||
"Service unavailable");
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
} else if (SMTPD_DNSXL_STAT_OK(dnswl_result)) {
|
||||
return (SMTPD_CHECK_OK);
|
||||
} else {
|
||||
/* Future proofing, in case find_dnsxl_addr() result is changed. */
|
||||
msg_panic("%s: find_dnsxl_addr API failure", myname);
|
||||
}
|
||||
}
|
||||
|
||||
/* reject_maps_rbl - reject if client address in real-time blackhole list */
|
||||
|
||||
static int reject_maps_rbl(SMTPD_STATE *state)
|
||||
@ -3680,6 +3789,12 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
||||
else
|
||||
status = reject_rbl_addr(state, *(cpp += 1), state->addr,
|
||||
SMTPD_NAME_CLIENT);
|
||||
} else if (strcasecmp(name, PERMIT_DNSWL_CLIENT) == 0) {
|
||||
if (cpp[1] == 0)
|
||||
msg_warn("restriction %s requires domain name argument", name);
|
||||
else
|
||||
status = permit_dnswl_addr(state, *(cpp += 1), state->addr,
|
||||
SMTPD_NAME_CLIENT);
|
||||
} else if (strcasecmp(name, REJECT_RHSBL_CLIENT) == 0) {
|
||||
if (cpp[1] == 0)
|
||||
msg_warn("restriction %s requires domain name argument",
|
||||
@ -3690,6 +3805,16 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
||||
status = reject_rbl_domain(state, *cpp, state->name,
|
||||
SMTPD_NAME_CLIENT);
|
||||
}
|
||||
} else if (strcasecmp(name, PERMIT_RHSWL_CLIENT) == 0) {
|
||||
if (cpp[1] == 0)
|
||||
msg_warn("restriction %s requires domain name argument",
|
||||
name);
|
||||
else {
|
||||
cpp += 1;
|
||||
if (strcasecmp(state->name, "unknown") != 0)
|
||||
status = permit_dnswl_domain(state, *cpp, state->name,
|
||||
SMTPD_NAME_CLIENT);
|
||||
}
|
||||
} else if (strcasecmp(name, REJECT_RHSBL_REVERSE_CLIENT) == 0) {
|
||||
if (cpp[1] == 0)
|
||||
msg_warn("restriction %s requires domain name argument",
|
||||
@ -4979,7 +5104,7 @@ static const INT_TABLE int_table[] = {
|
||||
VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code,
|
||||
VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code,
|
||||
VAR_SHOW_UNK_RCPT_TABLE, DEF_SHOW_UNK_RCPT_TABLE, &var_show_unk_rcpt_table,
|
||||
VAR_VERIFY_POLL_COUNT, DEF_VERIFY_POLL_COUNT, &var_verify_poll_count,
|
||||
VAR_VERIFY_POLL_COUNT, 3, &var_verify_poll_count,
|
||||
VAR_SMTPD_REJ_UNL_FROM, DEF_SMTPD_REJ_UNL_FROM, &var_smtpd_rej_unl_from,
|
||||
VAR_SMTPD_REJ_UNL_RCPT, DEF_SMTPD_REJ_UNL_RCPT, &var_smtpd_rej_unl_rcpt,
|
||||
VAR_PLAINTEXT_CODE, DEF_PLAINTEXT_CODE, &var_plaintext_code,
|
||||
@ -5238,6 +5363,12 @@ int main(int argc, char **argv)
|
||||
resp = "bad command";
|
||||
switch (args->argc) {
|
||||
|
||||
/*
|
||||
* Emtpy line.
|
||||
*/
|
||||
case 0:
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Special case: client identity.
|
||||
*/
|
||||
|
56
postfix/src/smtpd/smtpd_dnswl.in
Normal file
56
postfix/src/smtpd/smtpd_dnswl.in
Normal file
@ -0,0 +1,56 @@
|
||||
#
|
||||
# Initialize.
|
||||
#
|
||||
#msg_verbose 1
|
||||
smtpd_delay_reject 0
|
||||
mynetworks 127.0.0.0/8,168.100.189.0/28
|
||||
mydestination porcupine.org
|
||||
relay_domains porcupine.org
|
||||
helo foobar
|
||||
|
||||
#
|
||||
# DNSWL (by IP address)
|
||||
#
|
||||
|
||||
# Whitelist overrides reject.
|
||||
client_restrictions permit_dnswl_client,wild.porcupine.org,reject
|
||||
client spike.porcupine.org 168.100.189.2
|
||||
|
||||
# Whitelist does not fire - reject.
|
||||
client_restrictions permit_dnswl_client,porcupine.org,reject
|
||||
client spike.porcupine.org 168.100.189.2
|
||||
|
||||
# Whitelist does not override reject_unauth_destination.
|
||||
client_restrictions permit
|
||||
recipient_restrictions permit_dnswl_client,wild.porcupine.org,reject_unauth_destination
|
||||
# Unauthorized destination - reject.
|
||||
rcpt rname@rdomain
|
||||
# Authorized destination - accept.
|
||||
rcpt wietse@porcupine.org
|
||||
|
||||
#
|
||||
# RHSWL (by domain name)
|
||||
#
|
||||
|
||||
# Whitelist overrides reject.
|
||||
client_restrictions permit_rhswl_client,dsn.rfc-ignorant.org,reject
|
||||
# Non-whitelisted client name - reject.
|
||||
client spike.porcupine.org 168.100.189.2
|
||||
# Whitelisted client name - accept.
|
||||
client example.tld 168.100.189.2
|
||||
|
||||
# Whitelist does not override reject_unauth_destination.
|
||||
client_restrictions permit
|
||||
recipient_restrictions permit_rhswl_client,dsn.rfc-ignorant.org,reject_unauth_destination
|
||||
# Non-whitelisted client name.
|
||||
client spike.porcupine.org 168.100.189.2
|
||||
# Unauthorized destination - reject.
|
||||
rcpt rname@rdomain
|
||||
# Authorized destination - accept.
|
||||
rcpt wietse@porcupine.org
|
||||
# Whitelisted client name.
|
||||
client example.tld 168.100.189.2
|
||||
# Unauthorized destination - reject.
|
||||
rcpt rname@rdomain
|
||||
# Authorized destination - accept.
|
||||
rcpt wietse@porcupine.org
|
85
postfix/src/smtpd/smtpd_dnswl.ref
Normal file
85
postfix/src/smtpd/smtpd_dnswl.ref
Normal file
@ -0,0 +1,85 @@
|
||||
>>> #
|
||||
>>> # Initialize.
|
||||
>>> #
|
||||
>>> #msg_verbose 1
|
||||
>>> smtpd_delay_reject 0
|
||||
OK
|
||||
>>> mynetworks 127.0.0.0/8,168.100.189.0/28
|
||||
OK
|
||||
>>> mydestination porcupine.org
|
||||
OK
|
||||
>>> relay_domains porcupine.org
|
||||
OK
|
||||
>>> helo foobar
|
||||
OK
|
||||
>>>
|
||||
>>> #
|
||||
>>> # DNSWL (by IP address)
|
||||
>>> #
|
||||
>>>
|
||||
>>> # Whitelist overrides reject.
|
||||
>>> client_restrictions permit_dnswl_client,wild.porcupine.org,reject
|
||||
OK
|
||||
>>> client spike.porcupine.org 168.100.189.2
|
||||
OK
|
||||
>>>
|
||||
>>> # Whitelist does not fire - reject.
|
||||
>>> client_restrictions permit_dnswl_client,porcupine.org,reject
|
||||
OK
|
||||
>>> client spike.porcupine.org 168.100.189.2
|
||||
./smtpd_check: <queue id>: reject: CONNECT from spike.porcupine.org[168.100.189.2]: 554 5.7.1 <spike.porcupine.org[168.100.189.2]>: Client host rejected: Access denied; proto=SMTP helo=<foobar>
|
||||
554 5.7.1 <spike.porcupine.org[168.100.189.2]>: Client host rejected: Access denied
|
||||
>>>
|
||||
>>> # Whitelist does not override reject_unauth_destination.
|
||||
>>> client_restrictions permit
|
||||
OK
|
||||
>>> recipient_restrictions permit_dnswl_client,wild.porcupine.org,reject_unauth_destination
|
||||
OK
|
||||
>>> # Unauthorized destination - reject.
|
||||
>>> rcpt rname@rdomain
|
||||
./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.189.2]: 554 5.7.1 <rname@rdomain>: Relay access denied; to=<rname@rdomain> proto=SMTP helo=<foobar>
|
||||
554 5.7.1 <rname@rdomain>: Relay access denied
|
||||
>>> # Authorized destination - accept.
|
||||
>>> rcpt wietse@porcupine.org
|
||||
OK
|
||||
>>>
|
||||
>>> #
|
||||
>>> # RHSWL (by domain name)
|
||||
>>> #
|
||||
>>>
|
||||
>>> # Whitelist overrides reject.
|
||||
>>> client_restrictions permit_rhswl_client,dsn.rfc-ignorant.org,reject
|
||||
OK
|
||||
>>> # Non-whitelisted client name - reject.
|
||||
>>> client spike.porcupine.org 168.100.189.2
|
||||
./smtpd_check: <queue id>: reject: CONNECT from spike.porcupine.org[168.100.189.2]: 554 5.7.1 <spike.porcupine.org[168.100.189.2]>: Client host rejected: Access denied; proto=SMTP helo=<foobar>
|
||||
554 5.7.1 <spike.porcupine.org[168.100.189.2]>: Client host rejected: Access denied
|
||||
>>> # Whitelisted client name - accept.
|
||||
>>> client example.tld 168.100.189.2
|
||||
OK
|
||||
>>>
|
||||
>>> # Whitelist does not override reject_unauth_destination.
|
||||
>>> client_restrictions permit
|
||||
OK
|
||||
>>> recipient_restrictions permit_rhswl_client,dsn.rfc-ignorant.org,reject_unauth_destination
|
||||
OK
|
||||
>>> # Non-whitelisted client name.
|
||||
>>> client spike.porcupine.org 168.100.189.2
|
||||
OK
|
||||
>>> # Unauthorized destination - reject.
|
||||
>>> rcpt rname@rdomain
|
||||
./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.189.2]: 554 5.7.1 <rname@rdomain>: Relay access denied; to=<rname@rdomain> proto=SMTP helo=<foobar>
|
||||
554 5.7.1 <rname@rdomain>: Relay access denied
|
||||
>>> # Authorized destination - accept.
|
||||
>>> rcpt wietse@porcupine.org
|
||||
OK
|
||||
>>> # Whitelisted client name.
|
||||
>>> client example.tld 168.100.189.2
|
||||
OK
|
||||
>>> # Unauthorized destination - reject.
|
||||
>>> rcpt rname@rdomain
|
||||
./smtpd_check: <queue id>: reject: RCPT from example.tld[168.100.189.2]: 554 5.7.1 <rname@rdomain>: Relay access denied; to=<rname@rdomain> proto=SMTP helo=<foobar>
|
||||
554 5.7.1 <rname@rdomain>: Relay access denied
|
||||
>>> # Authorized destination - accept.
|
||||
>>> rcpt wietse@porcupine.org
|
||||
OK
|
Loading…
x
Reference in New Issue
Block a user