2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

postfix-2.7-20090807

This commit is contained in:
Wietse Venema
2009-08-07 00:00:00 -05:00
committed by Viktor Dukhovni
parent 24a96550cb
commit fb6283acfc
4 changed files with 96 additions and 28 deletions

View File

@@ -15336,22 +15336,33 @@ Apologies for any names omitted.
Bugfix: don't panic when an unexpected smtpd access map is
specified. File: smtpd/smtpd_check.c.
20090807
Workaround: NS record lookups for certain domains always
fail, while other queries for those domains always succeed
(and even return replies with NS records as additional
information).
This specific inconsistency would allow spammers to avoid
the Postfix check_{client,helo,sender,etc}_ns_access
restrictions, because those restrictions have effect only
for NS records that can be looked up in the DNS.
This inconsistency would allow spammers to avoid the Postfix
check_{client,helo,sender,etc}_ns_access restrictions,
because those restrictions have effect only for names that
are known in the DNS.
To address this specific inconsistency, the Postfix
reject_unknown_helo_hostname, reject_unknown_sender_domain
and reject_unknown_recipient_domain restrictions now require
that a domain has NS records that resolve to at least one
IP address, and they now accept only MX records that resolve
to at least one IP address; those addresses may or may not
be "correct". Postfix has no code to determine whether the
SMTP client name has a resolvable NS or MX record. File:
smtpd/smtpd_check.c.
check_{client,etc}_ns_access feature now requires that a
known-in-DNS domain name (or parent thereof) resolves to
at least one name server IP address.
For consistency, check_{client,etc}_mx_access now requires
that a known-in-DNS domain name resolves to at least one
mail server IP address.
In addition, reject_unknown_helo_hostname,
reject_unknown_sender_domain now require that an MX record
resolves to at least one IP address. Until now, the existence
of an MX record was sufficient.
The IP addresses thus obtained may or may not be "correct".
There is little to stop an uncooperative DNS server from
lying, especially when the owner of the domain has no
intention to receive email. File: smtpd/smtpd_check.c.

View File

@@ -14,22 +14,31 @@ specifies the release date of a stable release or snapshot release.
If you upgrade from Postfix 2.5 or earlier, read RELEASE_NOTES-2.6
before proceeding.
Incompatibility with snapshot 20090805
Incompatibility with snapshot 20090807
======================================
With some domain names, NS record lookups always fail while other
lookups always succeed (and often return NS records as additional
lookups always succeed (and may even return NS records as additional
information). This anomaly could be used by evil elements to skip
Postfix check_{client,helo,sender,recipient}_ns_access checks,
because those apply only domains with an NS record in the DNS.
because these apply only to domains that are known in the DNS.
To address this specific problem, the reject_unknown_helo_hostname,
reject_unknown_sender_domain and reject_unknown_recipient_domain
features now require that a domain name has NS records that resolve
to at least one IP address, and they now accept only MX records
that resolve to at least one IP address; those addresses may or may
not be "correct". Postfix has no code to determine whether the
SMTP client name has a resolvable NS or MX record.
To address this specific problem, check_{client,etc}_ns_access now
requires that a known-in-DNS domain name (or parent thereof) resolves
to at least one name server IP address.
For consistency, check_{client,etc}_mx_access now requires that a
known-in-DNS domain name resolves to at least one mail server IP
address.
In addition, reject_unknown_helo_hostname, reject_unknown_sender_domain
and reject_unknown_recipient_domain now require that an MX record
resolves to at least one IP address. Until now, the existence of
an MX record was sufficient.
Keep in mind that these measures provide no hard assurances. There
is little to stop an uncooperative DNS server from lying, especially
when the owner of the domain has no intention to receive email.
Incompatibility with snapshot 20090606
======================================

View File

@@ -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 "20090805"
#define MAIL_RELEASE_DATE "20090807"
#define MAIL_VERSION_NUMBER "2.7"
#ifdef SNAPSHOT

View File

@@ -1166,12 +1166,12 @@ static int resolve_server_list(const char *name, int type,
*/
dns_status = dns_lookup(domain, type, 0, &server_list,
(VSTRING *) 0, (VSTRING *) 0);
if (dns_status == DNS_NOTFOUND && h_errno == NO_DATA) {
if (dns_status == DNS_NOTFOUND /* Not: h_errno == NO_DATA */ ) {
if (type == T_MX) {
server_list = dns_rr_create(domain, domain, type, C_IN, 0, 0,
domain, strlen(domain) + 1);
dns_status = DNS_OK;
} else if (type == T_NS) {
} else if (type == T_NS && h_errno == NO_DATA) {
while ((domain = strchr(domain, '.')) != 0 && domain[1]) {
domain += 1;
dns_status = dns_lookup(domain, type, 0, &server_list,
@@ -1232,8 +1232,10 @@ static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
* check_server_access() wants to check.
*/
dns_status = resolve_server_list(name, T_MX, reply_name, reply_class);
#ifdef REQUIRE_NS_FOR_REJECT_UNKNOWN_DOMAIN_CHECK
if (dns_status == DNS_OK)
dns_status = resolve_server_list(name, T_NS, reply_name, reply_class);
#endif
if (dns_status != DNS_OK) { /* incl. DNS_INVAL */
if (dns_status != DNS_RETRY)
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
@@ -1268,8 +1270,10 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, const char *name,
* check_server_access() wants to check.
*/
dns_status = resolve_server_list(name, T_MX, reply_name, reply_class);
#ifdef REQUIRE_NS_FOR_REJECT_UNKNOWN_DOMAIN_CHECK
if (dns_status == DNS_OK)
dns_status = resolve_server_list(name, T_NS, reply_name, reply_class);
#endif
if (dns_status != DNS_OK) { /* incl. DNS_INVAL */
if (dns_status != DNS_RETRY)
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
@@ -2590,6 +2594,10 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
struct addrinfo *res;
int status;
INET_PROTO_INFO *proto_info;
const char *saved_domain;
int non_err, soft_err;
int known_name_in_dns;
int ping_status;
/*
* Sanity check.
@@ -2644,15 +2652,26 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
*
* If the domain name exists but no NS record exists, look up parent domain
* NS records.
*
* After the initial lookup fails, do one final DNS sanity check. Reject
* mail when the name exists, but MX lookup produces no valid response or
* NS lookup fails for any reason. Beware, this sanity check provides no
* hard assurance. An uncooperative DNS server may lie about everything,
* including non-existence.
*/
#define SOME_DNS_RR_EXISTS(stat, herr) \
((stat) == DNS_OK || (stat) == DNS_INVAL || (herr) == NO_DATA)
saved_domain = domain;
dns_status = dns_lookup(domain, type, 0, &server_list,
(VSTRING *) 0, (VSTRING *) 0);
if (dns_status == DNS_NOTFOUND && h_errno == NO_DATA) {
known_name_in_dns = SOME_DNS_RR_EXISTS(dns_status, h_errno);
if (dns_status == DNS_NOTFOUND /* Not: h_errno == NO_DATA */ ) {
if (type == T_MX) {
server_list = dns_rr_create(domain, domain, type, C_IN, 0, 0,
domain, strlen(domain) + 1);
dns_status = DNS_OK;
} else if (type == T_NS) {
} else if (type == T_NS && h_errno == NO_DATA) {
while ((domain = strchr(domain, '.')) != 0 && domain[1]) {
domain += 1;
dns_status = dns_lookup(domain, type, 0, &server_list,
@@ -2665,6 +2684,22 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
if (dns_status != DNS_OK) {
msg_warn("Unable to look up %s host for %s: %s", dns_strtype(type),
domain && domain[1] ? domain : name, dns_strerror(h_errno));
if (known_name_in_dns == 0) {
/* With hostile DNS, an address query is more likely to work. */
ping_status = dns_lookup_l(saved_domain, 0, (DNS_RR **) 0,
(VSTRING *) 0, (VSTRING *) 0,
DNS_REQ_FLAG_STOP_OK,
CHECK_RR_ADDR_TYPES, 0);
known_name_in_dns = SOME_DNS_RR_EXISTS(ping_status, h_errno);
}
if (known_name_in_dns)
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
dns_status == DNS_RETRY ?
var_map_defer_code : var_map_reject_code,
smtpd_dsn_fix("4.1.8", reply_class),
"<%s>: %s rejected: %s",
reply_name, reply_class,
"Domain not found"));
return (SMTPD_CHECK_DUNNO);
}
@@ -2677,11 +2712,13 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
* Check the hostnames first, then the addresses.
*/
proto_info = inet_proto_info();
non_err = soft_err = 0;
for (server = server_list; server != 0; server = server->next) {
if (msg_verbose)
msg_info("%s: %s hostname check: %s",
myname, dns_strtype(type), (char *) server->data);
if (valid_hostaddr((char *) server->data, DONT_GRIPE)) {
non_err = 1;
if ((status = check_addr_access(state, table, (char *) server->data,
FULL, &found, reply_name, reply_class,
def_acl)) != 0 || found)
@@ -2697,8 +2734,11 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
msg_warn("Unable to look up %s host %s for %s %s: %s",
dns_strtype(type), (char *) server->data,
reply_class, reply_name, MAI_STRERROR(aierr));
if (aierr == EAI_AGAIN || aierr == EAI_SYSTEM)
soft_err = 1;
continue;
}
non_err = 1;
/* Now we must also free the addrinfo result. */
if (msg_verbose)
msg_info("%s: %s host address check: %s",
@@ -2722,7 +2762,15 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
}
freeaddrinfo(res0); /* 200412 */
}
CHECK_SERVER_RETURN(SMTPD_CHECK_DUNNO);
status = non_err ? SMTPD_CHECK_DUNNO :
smtpd_check_reject(state, MAIL_ERROR_POLICY,
soft_err ? var_map_defer_code :
var_map_reject_code,
smtpd_dsn_fix("4.1.8", reply_class),
"<%s>: %s rejected: %s",
reply_name, reply_class,
"Domain not found");
CHECK_SERVER_RETURN(status);
}
/* check_ccert_access - access for TLS clients by certificate fingerprint */