2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +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.
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:
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:
- Protocol names are ESMTP or SMTP.
- Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, or DATA;
these are all the SMTP protocol states where the Postfix SMTP
- Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, DATA or
ETRN; these are the SMTP protocol states where the Postfix SMTP
server makes an OK/REJECT/HOLD/etc. decision.
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);
}
# 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;
if ($now - $time_stamp > $greylist_delay) {
return "ok";
return "dunno";
} else {
return "450 Service is unavailable";
}

View File

@ -148,6 +148,8 @@ smtpd_banner = $myhostname ESMTP $mail_name
# in an A record under domain.tld.
# 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.
# 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.
# permit: permit the request. Place this at the end of a restriction.
# 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.
# 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.
# 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.
# permit: permit the request. Place this at the end of a restriction.
# 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.
# Redirect the message if the result is REDIRECT user@domain.
# 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.
# permit: permit the request. Place this at the end of a restriction.
# 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
# $smtpd_sender_login_maps (see above).
# 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.
# permit: permit the request. Place this at the end of a restriction.
# 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.
# Permit the recipient if the result is OK or all numerical.
# 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.
# permit: permit the request. Place this at the end of a restriction.
# 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:
#
# smtpd_recipient_restrictions =
# ... reject_unauth_destination
# ... reject_unauth_destination
# check_policy_service unix:private/policy ...
#
# 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
# attribute list followed by a empty line:
#
# action=ok
# action=dunno
# [empty line]
#
@ -67,7 +67,7 @@ $database_name="/var/mta/smtpd-policy.db";
$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
# work on your system.
#
@ -92,15 +92,17 @@ sub smtpd_access_policy {
$time_stamp = read_database($key);
$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) {
$time_stamp = $now;
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;
if ($now - $time_stamp > $greylist_delay) {
return "ok";
return "dunno";
} else {
return "450 Service is unavailable";
}
@ -130,7 +132,7 @@ sub open_database {
my($database_fd);
# 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) ||
fatal_exit "Cannot open database %s: $!", $database_name;
$database_fd = $database_obj->fd;
@ -187,7 +189,7 @@ while ($option = shift(@ARGV)) {
if ($option eq "-v") {
$verbose = 1;
} else {
syslog $syslog_priority, "Invalid option: %s. Usage: %s [-v]",
syslog $syslog_priority, "Invalid option: %s. Usage: %s [-v]",
$option, $0;
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="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions.
</dl>
@ -593,6 +595,8 @@ or parent domains.
<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.
</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="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions.
</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="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions.
</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="#check_policy_service">check_policy_service</a></b>
<dd> See generic restrictions.
</dl>
@ -1206,6 +1216,33 @@ Postfix actually supports SMTP command pipelining. This stops mail
from bulk mail software that improperly uses SMTP command pipelining
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>

View File

@ -20,7 +20,7 @@
* Patches change the patchlevel and the release date. Snapshots change the
* 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 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/lex_822.h
qmqpd.o: ../../include/verp_sender.h
qmqpd.o: ../../include/input_transp.h
qmqpd.o: ../../include/mail_server.h
qmqpd.o: qmqpd.h
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/mac_expand.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/string_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/mail_proto.h
smtpd_check.o: ../../include/iostuff.h
smtpd_check.o: ../../include/attr.h
smtpd_check.o: ../../include/mail_addr.h
smtpd_check.o: ../../include/verify_clnt.h
smtpd_check.o: ../../include/deliver_request.h

View File

@ -297,7 +297,6 @@
#include <htable.h>
#include <ctable.h>
#include <mac_expand.h>
#include <myrand.h>
#include <attr_clnt.h>
/* DNS library. */
@ -487,7 +486,7 @@ static void PRINTFLIKE(3, 4) defer_if(SMTPD_DEFER *, int, const char *,...);
* Cached RBL lookup state.
*/
typedef struct {
ARGV *txt; /* TXT records or NULL */
char *txt; /* TXT content or NULL */
ARGV *a; /* A records */
} SMTPD_RBL_STATE;
@ -834,6 +833,13 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
vstring_vsprintf(error_text, format, 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
* 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;
struct in_addr addr;
DNS_RR *rr;
DNS_RR *next;
VSTRING *buf;
int space_left;
/*
* 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
* 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));
if (dns_lookup(query, T_TXT, 0, &txt_list,
(VSTRING *) 0, (VSTRING *) 0) == DNS_OK) {
rbl->txt = argv_alloc(1);
for (rr = txt_list; rr != 0; rr = rr->next)
argv_addn(rbl->txt, rr->data, rr->data_len > RBL_TXT_LIMIT ?
RBL_TXT_LIMIT : rr->data_len, ARGV_END);
buf = vstring_alloc(1);
space_left = RBL_TXT_LIMIT;
for (rr = txt_list; rr != 0 && space_left > 0; rr = next) {
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);
} else
rbl->txt = 0;
@ -2437,7 +2455,7 @@ static void rbl_pageout(void *data, void *unused_context)
if (rbl != 0) {
if (rbl->txt)
argv_free(rbl->txt);
myfree(rbl->txt);
if (rbl->a)
argv_free(rbl->a);
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.what = what;
rbl_exp.class = reply_class;
/*
* 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]);
rbl_exp.txt = (rbl->txt == 0 ? "" : rbl->txt);
for (;;) {
if (template == 0)
@ -2537,7 +2546,6 @@ static int rbl_reject_reply(SMTPD_STATE *state, SMTPD_RBL_STATE *rbl,
* Clean up.
*/
vstring_free(why);
myfree((char *) rbl_exp.txt);
return (result);
}

View File

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