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

postfix-2.0.14-20030716

This commit is contained in:
Wietse Venema
2003-07-16 00:00:00 -05:00
committed by Viktor Dukhovni
parent 57acae7051
commit b9775dd2c8
10 changed files with 107 additions and 32 deletions

View File

@@ -8384,6 +8384,19 @@ Apologies for any names omitted.
"check_smtpd_policy_service" in smtpd_mumble_restrictions. "check_smtpd_policy_service" in smtpd_mumble_restrictions.
See SMTPD_POLICY_SERVICE_README for details. See SMTPD_POLICY_SERVICE_README for details.
20030716
Bugfix: in the sample policy server, changed "ok" into
"dunno" so the server can be used in the middle of a
restriction list.
Cleanup: when an RBL reply has multiple TXT records,
concatenate them up to some reasonable limit, instead of
selecting one randomly. File: smtpd/smtpd_check.c.
Safety: always truncate SMTP server error replies to 512
bytes. File: smtpd/smtpd_check.c.
Open problems: Open problems:
Low: smtp-source may block when sending large test messages. Low: smtp-source may block when sending large test messages.

View File

@@ -47,8 +47,8 @@ server sends in a delegated SMTPD access policy request:
The following is specific to SMTPD delegated policy requests: The following is specific to SMTPD delegated policy requests:
- Protocol names are ESMTP or SMTP. - Protocol names are ESMTP or SMTP.
- Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, or DATA; - Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, DATA or
these are all the SMTP protocol states where the Postfix SMTP ETRN; these are the SMTP protocol states where the Postfix SMTP
server makes an OK/REJECT/HOLD/etc. decision. server makes an OK/REJECT/HOLD/etc. decision.
The policy server replies with any action that is allowed in a The policy server replies with any action that is allowed in a
@@ -259,9 +259,11 @@ sub smtpd_access_policy {
update_database($key, $time_stamp); update_database($key, $time_stamp);
} }
# Specify DUNNO instead of OK so that the check_policy_service restriction
# can be used in the middle of a restriction list.
syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose; syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose;
if ($now - $time_stamp > $greylist_delay) { if ($now - $time_stamp > $greylist_delay) {
return "ok"; return "dunno";
} else { } else {
return "450 Service is unavailable"; return "450 Service is unavailable";
} }

View File

@@ -148,6 +148,8 @@ smtpd_banner = $myhostname ESMTP $mail_name
# in an A record under domain.tld. # in an A record under domain.tld.
# Append e.g., "=127.0.0.2" to the RBL domain name to select a specific # Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
# address record when an RBL server provides multi-valued results. # address record when an RBL server provides multi-valued results.
# check_policy_service transport:endpoint: delegate the decision to
# an external policy server. See SMTPD_POLICY_README for details.
# reject: reject the request. Place this at the end of a restriction. # reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction.
# warn_if_reject: next restriction logs a warning instead of rejecting. # warn_if_reject: next restriction logs a warning instead of rejecting.
@@ -326,6 +328,8 @@ mynetworks_style = subnet
# in an A record under domain.tld. # in an A record under domain.tld.
# Append e.g., "=127.0.0.2" to the RBL domain name to select a specific # Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
# address record when an RBL server provides multi-valued results. # address record when an RBL server provides multi-valued results.
# check_policy_service transport:endpoint: delegate the decision to
# an external policy server. See SMTPD_POLICY_README for details.
# reject: reject the request. Place this at the end of a restriction. # reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction.
# warn_if_reject: next restriction logs a warning instead of rejecting. # warn_if_reject: next restriction logs a warning instead of rejecting.
@@ -370,6 +374,8 @@ smtpd_helo_required = no
# Filter the message if the result is FILTER transport:nexthop. # Filter the message if the result is FILTER transport:nexthop.
# Redirect the message if the result is REDIRECT user@domain. # Redirect the message if the result is REDIRECT user@domain.
# Permit the HELO command if the result is OK or all numerical. # Permit the HELO command if the result is OK or all numerical.
# check_policy_service transport:endpoint: delegate the decision to
# an external policy server. See SMTPD_POLICY_README for details.
# reject: reject the request. Place this at the end of a restriction. # reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction.
# warn_if_reject: next restriction logs a warning instead of rejecting. # warn_if_reject: next restriction logs a warning instead of rejecting.
@@ -415,6 +421,8 @@ smtpd_helo_restrictions =
# the client login name doesn't own the MAIL FROM address according to # the client login name doesn't own the MAIL FROM address according to
# $smtpd_sender_login_maps (see above). # $smtpd_sender_login_maps (see above).
# reject_non_fqdn_sender: reject sender address that is not in FQDN form # reject_non_fqdn_sender: reject sender address that is not in FQDN form
# check_policy_service transport:endpoint: delegate the decision to
# an external policy server. See SMTPD_POLICY_README for details.
# reject: reject the request. Place this at the end of a restriction. # reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction.
# warn_if_reject: next restriction logs a warning instead of rejecting. # warn_if_reject: next restriction logs a warning instead of rejecting.
@@ -486,6 +494,8 @@ smtpd_sender_restrictions =
# Redirect the message if the result is REDIRECT user@domain. # Redirect the message if the result is REDIRECT user@domain.
# Permit the recipient if the result is OK or all numerical. # Permit the recipient if the result is OK or all numerical.
# reject_non_fqdn_recipient: reject recipient address that is not in FQDN form # reject_non_fqdn_recipient: reject recipient address that is not in FQDN form
# check_policy_service transport:endpoint: delegate the decision to
# an external policy server. See SMTPD_POLICY_README for details.
# reject: reject the request. Place this at the end of a restriction. # reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction.
# warn_if_reject: next restriction logs a warning instead of rejecting. # warn_if_reject: next restriction logs a warning instead of rejecting.

View File

@@ -26,7 +26,7 @@ use Sys::Syslog qw(:DEFAULT setlogsock);
# To use this from Postfix SMTPD, use in /etc/postfix/main.cf: # To use this from Postfix SMTPD, use in /etc/postfix/main.cf:
# #
# smtpd_recipient_restrictions = # smtpd_recipient_restrictions =
# ... reject_unauth_destination # ... reject_unauth_destination
# check_policy_service unix:private/policy ... # check_policy_service unix:private/policy ...
# #
# NOTE: specify check_policy_service AFTER reject_unauth_destination # NOTE: specify check_policy_service AFTER reject_unauth_destination
@@ -53,7 +53,7 @@ use Sys::Syslog qw(:DEFAULT setlogsock);
# The policy server script will answer in the same style, with an # The policy server script will answer in the same style, with an
# attribute list followed by a empty line: # attribute list followed by a empty line:
# #
# action=ok # action=dunno
# [empty line] # [empty line]
# #
@@ -67,7 +67,7 @@ $database_name="/var/mta/smtpd-policy.db";
$greylist_delay=3600; $greylist_delay=3600;
# #
# Syslogging options for verbose mode and for fatal errors. # Syslogging options for verbose mode and for fatal errors.
# NOTE: comment out the $syslog_socktype line if syslogging does not # NOTE: comment out the $syslog_socktype line if syslogging does not
# work on your system. # work on your system.
# #
@@ -92,15 +92,17 @@ sub smtpd_access_policy {
$time_stamp = read_database($key); $time_stamp = read_database($key);
$now = time(); $now = time();
# If new request, add this client/sender/recipient to the database. # If this is a new request add this client/sender/recipient to the database.
if ($time_stamp == 0) { if ($time_stamp == 0) {
$time_stamp = $now; $time_stamp = $now;
update_database($key, $time_stamp); update_database($key, $time_stamp);
} }
# Specify DUNNO instead of OK so that the check_policy_service restriction
# can be followed by other restrictions.
syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose; syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose;
if ($now - $time_stamp > $greylist_delay) { if ($now - $time_stamp > $greylist_delay) {
return "ok"; return "dunno";
} else { } else {
return "450 Service is unavailable"; return "450 Service is unavailable";
} }
@@ -130,7 +132,7 @@ sub open_database {
my($database_fd); my($database_fd);
# Use tied database to make complex manipulations easier to express. # Use tied database to make complex manipulations easier to express.
$database_obj = tie(%db_hash, 'DB_File', $database_name, $database_obj = tie(%db_hash, 'DB_File', $database_name,
O_CREAT|O_RDWR, 0644) || O_CREAT|O_RDWR, 0644) ||
fatal_exit "Cannot open database %s: $!", $database_name; fatal_exit "Cannot open database %s: $!", $database_name;
$database_fd = $database_obj->fd; $database_fd = $database_obj->fd;
@@ -187,7 +189,7 @@ while ($option = shift(@ARGV)) {
if ($option eq "-v") { if ($option eq "-v") {
$verbose = 1; $verbose = 1;
} else { } else {
syslog $syslog_priority, "Invalid option: %s. Usage: %s [-v]", syslog $syslog_priority, "Invalid option: %s. Usage: %s [-v]",
$option, $0; $option, $0;
exit 1; exit 1;
} }

View File

@@ -441,6 +441,8 @@ significant octets.
<dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b> <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
<dt> <b><a href="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions. <dd> See generic restrictions.
</dl> </dl>
@@ -593,6 +595,8 @@ or parent domains.
<dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b> <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
<dt> <b><a href="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions. <dd> See generic restrictions.
</dl> </dl>
@@ -776,6 +780,8 @@ client login name doesn't own the MAIL FROM address according to
<dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b> <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
<dt> <b><a href="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions. <dd> See generic restrictions.
</dl> </dl>
@@ -1058,6 +1064,8 @@ response code to rejected requests (default: <b>504</b>).
<dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b> <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
<dt> <b><a href="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions. <dd> See generic restrictions.
</dl> </dl>
@@ -1139,6 +1147,8 @@ the result code for rejected requests (default: <b>554</b>).
<dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b> <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
<dt> <b><a href="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions. <dd> See generic restrictions.
</dl> </dl>
@@ -1206,6 +1216,33 @@ Postfix actually supports SMTP command pipelining. This stops mail
from bulk mail software that improperly uses SMTP command pipelining from bulk mail software that improperly uses SMTP command pipelining
to speed up deliveries. to speed up deliveries.
<p>
<a name="check_policy_service">
<dt> <b>check_policy_service inet</b>:<i>host</i>:<i>port</i>
<dt> <b>check_policy_service unix</b>:<i>pathname</i>
<dd> Query the specified server with a list of attributes that
specify (where available) the mail protocol (SMTP or ESMTP), the
queue file name, the protocol state (CONNECT, HELO, EHLO, MAIL,
RCPT, ETRN), the client network address, the hostname given in the
HELO or EHLO command, the sender email address, the recipient email
address. The server is expected to reply with an action just like
the actions found in a Postfix <a href="access.5.html"> access</a>
table.
<p>
Example:
<dd><b>check_policy_service inet:localhost:9998</b>
<dd><b>check_policy_service unix:private/policy</b>
<dd><b>check_policy_service unix:/some/where</b>
</dl> </dl>
</dl> </dl>

View File

@@ -20,7 +20,7 @@
* Patches change the patchlevel and the release date. Snapshots change the * Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release. * release date only, unless they include the same bugfix as a patch release.
*/ */
#define MAIL_RELEASE_DATE "20030715" #define MAIL_RELEASE_DATE "20030716"
#define VAR_MAIL_VERSION "mail_version" #define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "2.0.14-" MAIL_RELEASE_DATE #define DEF_MAIL_VERSION "2.0.14-" MAIL_RELEASE_DATE

View File

@@ -96,6 +96,7 @@ qmqpd.o: ../../include/quote_flags.h
qmqpd.o: ../../include/match_parent_style.h qmqpd.o: ../../include/match_parent_style.h
qmqpd.o: ../../include/lex_822.h qmqpd.o: ../../include/lex_822.h
qmqpd.o: ../../include/verp_sender.h qmqpd.o: ../../include/verp_sender.h
qmqpd.o: ../../include/input_transp.h
qmqpd.o: ../../include/mail_server.h qmqpd.o: ../../include/mail_server.h
qmqpd.o: qmqpd.h qmqpd.o: qmqpd.h
qmqpd_peer.o: qmqpd_peer.c qmqpd_peer.o: qmqpd_peer.c

View File

@@ -198,6 +198,8 @@ smtpd_check.o: ../../include/htable.h
smtpd_check.o: ../../include/ctable.h smtpd_check.o: ../../include/ctable.h
smtpd_check.o: ../../include/mac_expand.h smtpd_check.o: ../../include/mac_expand.h
smtpd_check.o: ../../include/mac_parse.h smtpd_check.o: ../../include/mac_parse.h
smtpd_check.o: ../../include/attr_clnt.h
smtpd_check.o: ../../include/attr.h
smtpd_check.o: ../../include/dns.h smtpd_check.o: ../../include/dns.h
smtpd_check.o: ../../include/string_list.h smtpd_check.o: ../../include/string_list.h
smtpd_check.o: ../../include/match_list.h smtpd_check.o: ../../include/match_list.h
@@ -222,7 +224,6 @@ smtpd_check.o: ../../include/record.h
smtpd_check.o: ../../include/rec_type.h smtpd_check.o: ../../include/rec_type.h
smtpd_check.o: ../../include/mail_proto.h smtpd_check.o: ../../include/mail_proto.h
smtpd_check.o: ../../include/iostuff.h smtpd_check.o: ../../include/iostuff.h
smtpd_check.o: ../../include/attr.h
smtpd_check.o: ../../include/mail_addr.h smtpd_check.o: ../../include/mail_addr.h
smtpd_check.o: ../../include/verify_clnt.h smtpd_check.o: ../../include/verify_clnt.h
smtpd_check.o: ../../include/deliver_request.h smtpd_check.o: ../../include/deliver_request.h

View File

@@ -297,7 +297,6 @@
#include <htable.h> #include <htable.h>
#include <ctable.h> #include <ctable.h>
#include <mac_expand.h> #include <mac_expand.h>
#include <myrand.h>
#include <attr_clnt.h> #include <attr_clnt.h>
/* DNS library. */ /* DNS library. */
@@ -487,7 +486,7 @@ static void PRINTFLIKE(3, 4) defer_if(SMTPD_DEFER *, int, const char *,...);
* Cached RBL lookup state. * Cached RBL lookup state.
*/ */
typedef struct { typedef struct {
ARGV *txt; /* TXT records or NULL */ char *txt; /* TXT content or NULL */
ARGV *a; /* A records */ ARGV *a; /* A records */
} SMTPD_RBL_STATE; } SMTPD_RBL_STATE;
@@ -834,6 +833,13 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
vstring_vsprintf(error_text, format, ap); vstring_vsprintf(error_text, format, ap);
va_end(ap); va_end(ap);
/*
* Ensure RFC compliance. We could do this inside smtpd_chat_reply() and
* switch to multi-line for long replies.
*/
vstring_truncate(error_text, 510);
VSTRING_TERMINATE(error_text);
/* /*
* Validate the response, that is, the response must begin with a * Validate the response, that is, the response must begin with a
* three-digit status code, and the first digit must be 4 or 5. If the * three-digit status code, and the first digit must be 4 or 5. If the
@@ -2390,6 +2396,9 @@ static void *rbl_pagein(const char *query, void *unused_context)
DNS_RR *addr_list; DNS_RR *addr_list;
struct in_addr addr; struct in_addr addr;
DNS_RR *rr; DNS_RR *rr;
DNS_RR *next;
VSTRING *buf;
int space_left;
/* /*
* Do the query. If the DNS lookup produces no definitive reply, give the * Do the query. If the DNS lookup produces no definitive reply, give the
@@ -2406,17 +2415,26 @@ static void *rbl_pagein(const char *query, void *unused_context)
/* /*
* Save the result. Yes, we cache negative results as well as positive * Save the result. Yes, we cache negative results as well as positive
* results. * results. Concatenate multiple TXT records, up to some limit.
*/ */
#define RBL_TXT_LIMIT 256 #define RBL_TXT_LIMIT 500
rbl = (SMTPD_RBL_STATE *) mymalloc(sizeof(*rbl)); rbl = (SMTPD_RBL_STATE *) mymalloc(sizeof(*rbl));
if (dns_lookup(query, T_TXT, 0, &txt_list, if (dns_lookup(query, T_TXT, 0, &txt_list,
(VSTRING *) 0, (VSTRING *) 0) == DNS_OK) { (VSTRING *) 0, (VSTRING *) 0) == DNS_OK) {
rbl->txt = argv_alloc(1); buf = vstring_alloc(1);
for (rr = txt_list; rr != 0; rr = rr->next) space_left = RBL_TXT_LIMIT;
argv_addn(rbl->txt, rr->data, rr->data_len > RBL_TXT_LIMIT ? for (rr = txt_list; rr != 0 && space_left > 0; rr = next) {
RBL_TXT_LIMIT : rr->data_len, ARGV_END); vstring_strncat(buf, rr->data, (int) rr->data_len > space_left ?
space_left : rr->data_len);
space_left = RBL_TXT_LIMIT - VSTRING_LEN(buf);
next = rr->next;
if (next && space_left > 3) {
vstring_strcat(buf, " / ");
space_left -= 3;
}
}
rbl->txt = vstring_export(buf);
dns_rr_free(txt_list); dns_rr_free(txt_list);
} else } else
rbl->txt = 0; rbl->txt = 0;
@@ -2437,7 +2455,7 @@ static void rbl_pageout(void *data, void *unused_context)
if (rbl != 0) { if (rbl != 0) {
if (rbl->txt) if (rbl->txt)
argv_free(rbl->txt); myfree(rbl->txt);
if (rbl->a) if (rbl->a)
argv_free(rbl->a); argv_free(rbl->a);
myfree((char *) rbl); myfree((char *) rbl);
@@ -2506,16 +2524,7 @@ static int rbl_reject_reply(SMTPD_STATE *state, SMTPD_RBL_STATE *rbl,
rbl_exp.domain = rbl_domain; rbl_exp.domain = rbl_domain;
rbl_exp.what = what; rbl_exp.what = what;
rbl_exp.class = reply_class; rbl_exp.class = reply_class;
rbl_exp.txt = (rbl->txt == 0 ? "" : rbl->txt);
/*
* XXX When presented with multiple txt records pick a random one! There
* is no way to pair up the A records with associated TXT records. If a
* client connects multiple times, it will learn the right reject reason
* at least some of the time.
*/
rbl_exp.txt = mystrdup(rbl->txt == 0 ? "" :
rbl->txt->argc == 1 ? rbl->txt->argv[0] :
rbl->txt->argv[myrand() % rbl->txt->argc]);
for (;;) { for (;;) {
if (template == 0) if (template == 0)
@@ -2537,7 +2546,6 @@ static int rbl_reject_reply(SMTPD_STATE *state, SMTPD_RBL_STATE *rbl,
* Clean up. * Clean up.
*/ */
vstring_free(why); vstring_free(why);
myfree((char *) rbl_exp.txt);
return (result); return (result);
} }

View File

@@ -459,6 +459,7 @@ attr_clnt.o: vstream.h
attr_clnt.o: vbuf.h attr_clnt.o: vbuf.h
attr_clnt.o: connect.h attr_clnt.o: connect.h
attr_clnt.o: iostuff.h attr_clnt.o: iostuff.h
attr_clnt.o: htable.h
attr_clnt.o: attr.h attr_clnt.o: attr.h
attr_clnt.o: auto_clnt.h attr_clnt.o: auto_clnt.h
attr_clnt.o: attr_clnt.h attr_clnt.o: attr_clnt.h