mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 13:48:06 +00:00
postfix-2.3-20050627
This commit is contained in:
committed by
Viktor Dukhovni
parent
df5802491a
commit
6122cc449d
@@ -10931,8 +10931,34 @@ Apologies for any names omitted.
|
||||
util/attr_print0.c, global/dsb_scan.c, global/dsn_print.c,
|
||||
global/rcpt_buf,c global/rcpt_print.c, global/deliver_pass.c.
|
||||
|
||||
Added delegated attribute scan/print function support to
|
||||
the base64 and plain attribute I/O encodings. Files:
|
||||
util/attr_scan_plain.c util/attr_print_plain.c.
|
||||
|
||||
20040624
|
||||
|
||||
Added "." to the list commands that smtp-sink can "break"
|
||||
(by disconnecting, or by responding with a 4XX or 5XX reply
|
||||
code). File: smtpstone/smtp-sink.c.
|
||||
|
||||
20040625
|
||||
|
||||
Safety: allow only 4.x.x and 5.x.x enhanced status codes
|
||||
in header/body_checks REJECT actions. File:
|
||||
cleanup/cleanup_message.c.
|
||||
|
||||
20050627
|
||||
|
||||
Code cleanup: generalized the smtp-sink code that simulates
|
||||
server errors. File: smtpstone/smtp-sink.c.
|
||||
|
||||
Open problems:
|
||||
|
||||
Look for systems with XPG basename() declared in <libgen.h>,
|
||||
and prepare for phasing out the Postfix-supplied one.
|
||||
Beware, however, that XPG basename() takes (char *), and
|
||||
not (const char *) because it may change its argument.
|
||||
|
||||
Laptop friendliness: make the qmgr remember when the next
|
||||
deferred queue scan needs to be done, and have the pickup
|
||||
server stat() the maildrop directory before searching it.
|
||||
|
@@ -281,11 +281,16 @@ LMTP(8) LMTP(8)
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
|
||||
Alterations for LMTP by:
|
||||
Modifications for LMTP by:
|
||||
Philip A. Prindeville
|
||||
Mirapoint, Inc.
|
||||
USA.
|
||||
|
||||
SASL support originally by:
|
||||
Till Franke
|
||||
SuSE Rhein/Main AG
|
||||
65760 Eschborn, Germany
|
||||
|
||||
Additional work on LMTP by:
|
||||
Amos Gouaux
|
||||
University of Texas at Dallas
|
||||
|
@@ -6206,7 +6206,7 @@ The default time unit is s (seconds).
|
||||
<p>
|
||||
The maximal number of MX (mail exchanger) IP addresses that can
|
||||
result from mail exchanger lookups, or zero (no limit). Prior to
|
||||
Postfix 2.3, this limit was disabled.
|
||||
Postfix 2.3, this limit was disabled by default.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@@ -50,6 +50,12 @@ SMTP-SINK(1) SMTP-SINK(1)
|
||||
Reject the specified commands with a hard (5xx)
|
||||
error code. This option implies <b>-p</b>.
|
||||
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL,
|
||||
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
|
||||
command names by white space or commas, and use
|
||||
quotes to protect white space from the shell. Com-
|
||||
mand names are case-insensitive.
|
||||
|
||||
<b>-F</b> Disable XFORWARD support.
|
||||
|
||||
<b>-h</b> <i>hostname</i>
|
||||
@@ -73,21 +79,34 @@ SMTP-SINK(1) SMTP-SINK(1)
|
||||
Disconnect (without replying) after receiving one
|
||||
of the specified commands.
|
||||
|
||||
<b>-r</b> <i>command,command,...</i>
|
||||
Reject the specified commands with a soft (4xx)
|
||||
error code. This option implies <b>-p</b>.
|
||||
|
||||
<b>-s</b> <i>command,command,...</i>
|
||||
Log the named commands to syslogd. Examples of
|
||||
commands that can be logged are HELO, EHLO, LHLO,
|
||||
MAIL, RCPT, VRFY, RSET, NOOP, and QUIT. Separate
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL,
|
||||
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
|
||||
command names by white space or commas, and use
|
||||
quotes to protect white space from the shell. Com-
|
||||
mand names are case-insensitive.
|
||||
|
||||
<b>-r</b> <i>command,command,...</i>
|
||||
Reject the specified commands with a soft (4xx)
|
||||
error code. This option implies <b>-p</b>.
|
||||
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL,
|
||||
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
|
||||
command names by white space or commas, and use
|
||||
quotes to protect white space from the shell. Com-
|
||||
mand names are case-insensitive.
|
||||
|
||||
<b>-s</b> <i>command,command,...</i>
|
||||
Log the named commands to syslogd.
|
||||
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL,
|
||||
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
|
||||
command names by white space or commas, and use
|
||||
quotes to protect white space from the shell. Com-
|
||||
mand names are case-insensitive.
|
||||
|
||||
<b>-t</b> <i>timeout</i> (default: 100)
|
||||
Limit the time for receiving a command or sending a
|
||||
response. The time limit is specified in seconds.
|
||||
response. The time limit is specified in seconds.
|
||||
|
||||
<b>-v</b> Show the SMTP conversations.
|
||||
|
||||
@@ -96,7 +115,7 @@ SMTP-SINK(1) SMTP-SINK(1)
|
||||
mand.
|
||||
|
||||
[<b>inet:</b>][<i>host</i>]:<i>port</i>
|
||||
Listen on network interface <i>host</i> (default: any
|
||||
Listen on network interface <i>host</i> (default: any
|
||||
interface) TCP port <i>port</i>. Both <i>host</i> and <i>port</i> may be
|
||||
specified in numeric or symbolic form.
|
||||
|
||||
@@ -104,14 +123,14 @@ SMTP-SINK(1) SMTP-SINK(1)
|
||||
Listen on the UNIX-domain socket at <i>pathname</i>.
|
||||
|
||||
<i>backlog</i>
|
||||
The maximum length the queue of pending connec-
|
||||
The maximum length the queue of pending connec-
|
||||
tions, as defined by the <b>listen</b>(2) system call.
|
||||
|
||||
<b>SEE ALSO</b>
|
||||
<a href="smtp-source.1.html">smtp-source(1)</a>, SMTP/LMTP message generator
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
|
@@ -523,6 +523,11 @@ SMTP(8) SMTP(8)
|
||||
Coventry,
|
||||
CV1 4LY, United Kingdom.
|
||||
|
||||
SASL support originally by:
|
||||
Till Franke
|
||||
SuSE Rhein/Main AG
|
||||
65760 Eschborn, Germany
|
||||
|
||||
Connection caching in cooperation with:
|
||||
Victor Duchovni
|
||||
Morgan Stanley
|
||||
|
@@ -962,6 +962,11 @@ SMTPD(8) SMTPD(8)
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
|
||||
SASL support originally by:
|
||||
Till Franke
|
||||
SuSE Rhein/Main AG
|
||||
65760 Eschborn, Germany
|
||||
|
||||
TLS support originally by:
|
||||
Lutz Jaenicke
|
||||
BTU Cottbus
|
||||
|
@@ -49,6 +49,11 @@ Do not announce ENHANCEDSTATUSCODES support.
|
||||
.IP "\fB-f \fIcommand,command,...\fR"
|
||||
Reject the specified commands with a hard (5xx) error code.
|
||||
This option implies \fB-p\fR.
|
||||
.sp
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
white space or commas, and use quotes to protect white space
|
||||
from the shell. Command names are case-insensitive.
|
||||
.IP \fB-F\fR
|
||||
Disable XFORWARD support.
|
||||
.IP "\fB-h\fI hostname\fR"
|
||||
@@ -66,15 +71,26 @@ a CISCO PIX system. Implies \fB-e\fR.
|
||||
.IP "\fB-q \fIcommand,command,...\fR"
|
||||
Disconnect (without replying) after receiving one of the
|
||||
specified commands.
|
||||
.sp
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
white space or commas, and use quotes to protect white space
|
||||
from the shell. Command names are case-insensitive.
|
||||
.IP "\fB-r \fIcommand,command,...\fR"
|
||||
Reject the specified commands with a soft (4xx) error code.
|
||||
This option implies \fB-p\fR.
|
||||
.sp
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
white space or commas, and use quotes to protect white space
|
||||
from the shell. Command names are case-insensitive.
|
||||
.IP "\fB-s \fIcommand,command,...\fR"
|
||||
Log the named commands to syslogd.
|
||||
Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
|
||||
RCPT, VRFY, RSET, NOOP, and QUIT. Separate command names by white
|
||||
space or commas, and use quotes to protect white space from the
|
||||
shell. Command names are case-insensitive.
|
||||
.sp
|
||||
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
white space or commas, and use quotes to protect white space
|
||||
from the shell. Command names are case-insensitive.
|
||||
.IP "\fB-t \fItimeout\fR (default: 100)"
|
||||
Limit the time for receiving a command or sending a response.
|
||||
The time limit is specified in seconds.
|
||||
|
@@ -3437,7 +3437,7 @@ The default time unit is s (seconds).
|
||||
.SH smtp_mx_address_limit (default: 5)
|
||||
The maximal number of MX (mail exchanger) IP addresses that can
|
||||
result from mail exchanger lookups, or zero (no limit). Prior to
|
||||
Postfix 2.3, this limit was disabled.
|
||||
Postfix 2.3, this limit was disabled by default.
|
||||
.PP
|
||||
This feature is available in Postfix 2.1 and later.
|
||||
.SH smtp_mx_session_limit (default: 2)
|
||||
|
@@ -259,11 +259,16 @@ IBM T.J. Watson Research
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
|
||||
Alterations for LMTP by:
|
||||
Modifications for LMTP by:
|
||||
Philip A. Prindeville
|
||||
Mirapoint, Inc.
|
||||
USA.
|
||||
|
||||
SASL support originally by:
|
||||
Till Franke
|
||||
SuSE Rhein/Main AG
|
||||
65760 Eschborn, Germany
|
||||
|
||||
Additional work on LMTP by:
|
||||
Amos Gouaux
|
||||
University of Texas at Dallas
|
||||
|
@@ -429,6 +429,11 @@ Canal Basin,
|
||||
Coventry,
|
||||
CV1 4LY, United Kingdom.
|
||||
|
||||
SASL support originally by:
|
||||
Till Franke
|
||||
SuSE Rhein/Main AG
|
||||
65760 Eschborn, Germany
|
||||
|
||||
Connection caching in cooperation with:
|
||||
Victor Duchovni
|
||||
Morgan Stanley
|
||||
|
@@ -779,6 +779,11 @@ IBM T.J. Watson Research
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
|
||||
SASL support originally by:
|
||||
Till Franke
|
||||
SuSE Rhein/Main AG
|
||||
65760 Eschborn, Germany
|
||||
|
||||
TLS support originally by:
|
||||
Lutz Jaenicke
|
||||
BTU Cottbus
|
||||
|
@@ -3829,7 +3829,7 @@ The default time unit is s (seconds).
|
||||
<p>
|
||||
The maximal number of MX (mail exchanger) IP addresses that can
|
||||
result from mail exchanger lookups, or zero (no limit). Prior to
|
||||
Postfix 2.3, this limit was disabled.
|
||||
Postfix 2.3, this limit was disabled by default.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@@ -315,6 +315,11 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context,
|
||||
if (state->reason == 0) {
|
||||
if (*optional_text) {
|
||||
state->reason = dsn_prepend("5.7.1", optional_text);
|
||||
if (*state->reason != '4' && *state->reason != '5') {
|
||||
msg_warn("bad DSN action in %s -- need 4.x.x or 5.x.x",
|
||||
optional_text);
|
||||
*state->reason = '4';
|
||||
}
|
||||
} else {
|
||||
detail = cleanup_stat_detail(CLEANUP_STAT_CONT);
|
||||
state->reason = dsn_prepend(detail->dsn, detail->text);
|
||||
|
@@ -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 "20050623"
|
||||
#define MAIL_RELEASE_DATE "20050627"
|
||||
#define MAIL_VERSION_NUMBER "2.3"
|
||||
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
|
@@ -225,11 +225,16 @@
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Alterations for LMTP by:
|
||||
/* Modifications for LMTP by:
|
||||
/* Philip A. Prindeville
|
||||
/* Mirapoint, Inc.
|
||||
/* USA.
|
||||
/*
|
||||
/* SASL support originally by:
|
||||
/* Till Franke
|
||||
/* SuSE Rhein/Main AG
|
||||
/* 65760 Eschborn, Germany
|
||||
/*
|
||||
/* Additional work on LMTP by:
|
||||
/* Amos Gouaux
|
||||
/* University of Texas at Dallas
|
||||
|
@@ -389,6 +389,11 @@
|
||||
/* Coventry,
|
||||
/* CV1 4LY, United Kingdom.
|
||||
/*
|
||||
/* SASL support originally by:
|
||||
/* Till Franke
|
||||
/* SuSE Rhein/Main AG
|
||||
/* 65760 Eschborn, Germany
|
||||
/*
|
||||
/* Connection caching in cooperation with:
|
||||
/* Victor Duchovni
|
||||
/* Morgan Stanley
|
||||
|
@@ -355,7 +355,7 @@ int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
|
||||
/*
|
||||
* Append the passivated SASL attributes.
|
||||
*/
|
||||
#ifdef USE_SASL
|
||||
#ifdef notdef
|
||||
if (smtp_sasl_enable)
|
||||
smtp_sasl_passivate(endp_prop, session);
|
||||
#endif
|
||||
@@ -460,7 +460,7 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
|
||||
/*
|
||||
* Re-activate the SASL attributes.
|
||||
*/
|
||||
#ifdef USE_SASL
|
||||
#ifdef notdef
|
||||
if (smtp_sasl_enable && smtp_sasl_activate(session, endp_props) < 0) {
|
||||
vstream_fdclose(session->stream);
|
||||
session->stream = 0;
|
||||
|
@@ -721,6 +721,11 @@
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* SASL support originally by:
|
||||
/* Till Franke
|
||||
/* SuSE Rhein/Main AG
|
||||
/* 65760 Eschborn, Germany
|
||||
/*
|
||||
/* TLS support originally by:
|
||||
/* Lutz Jaenicke
|
||||
/* BTU Cottbus
|
||||
@@ -1435,8 +1440,12 @@ static int extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
|
||||
}
|
||||
|
||||
/*
|
||||
* Report trouble. Log a warning only if we are going to sleep+reject so
|
||||
* that attackers can't flood our logfiles.
|
||||
* Report trouble. XXX Should log a warning only if we are going to
|
||||
* sleep+reject so that attackers can't flood our logfiles.
|
||||
*
|
||||
* XXX Unfortunately, the sleep-before-reject feature had to be abandoned
|
||||
* (at least for small error counts) because servers were DOS-ing
|
||||
* themselves when flooded by backscatter traffic.
|
||||
*/
|
||||
if (naddr > 1
|
||||
|| (strict_rfc821 && (non_addr || *STR(arg->vstrval) != '<'))) {
|
||||
@@ -1503,8 +1512,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
* XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a
|
||||
* command in which invalid character codes have been employed, and for
|
||||
* which there are no other reasons for rejection, MUST reject that
|
||||
* command with a 501 response. So much for the principle of "be liberal
|
||||
* in what you accept, be strict in what you send".
|
||||
* command with a 501 response. Postfix attempts to be 8-bit clean.
|
||||
*/
|
||||
if (var_helo_required && state->helo_name == 0) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
@@ -2448,6 +2456,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
smtpd_chat_reply(state, "501 5.1.3 Bad recipient address syntax");
|
||||
return (-1);
|
||||
}
|
||||
/* Not: state->addr_buf */
|
||||
if (SMTPD_STAND_ALONE(state) == 0
|
||||
&& (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) {
|
||||
smtpd_chat_reply(state, "%s", err);
|
||||
@@ -2555,8 +2564,11 @@ static int quit_cmd(SMTPD_STATE *state, int unused_argc, SMTPD_TOKEN *unused_arg
|
||||
* When the "." and quit replies are pipelined, make sure they are
|
||||
* flushed now, to avoid repeated mail deliveries in case of a crash in
|
||||
* the "clean up before disconnect" code.
|
||||
*
|
||||
* XXX When this was added in Postfix 2.1 we used vstream_fflush(). As of
|
||||
* Postfix 2.3 we use smtp_flush() for better error reporting.
|
||||
*/
|
||||
vstream_fflush(state->client);
|
||||
smtp_flush(state->client);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -2945,7 +2957,7 @@ static void chat_reset(SMTPD_STATE *state, int threshold)
|
||||
|
||||
#ifdef USE_TLS
|
||||
|
||||
/* smtpd_start_tls -turn on TLS or force disconnect */
|
||||
/* smtpd_start_tls - turn on TLS or force disconnect */
|
||||
|
||||
static void smtpd_start_tls(SMTPD_STATE *state)
|
||||
{
|
||||
@@ -2961,10 +2973,10 @@ static void smtpd_start_tls(SMTPD_STATE *state)
|
||||
* verification unless TLS is required.
|
||||
*/
|
||||
state->tls_context =
|
||||
tls_server_start(smtpd_tls_ctx, state->client,
|
||||
var_smtpd_starttls_tmout,
|
||||
state->name, state->addr, &(state->tls_info),
|
||||
(var_smtpd_tls_req_ccert && state->tls_enforce_tls));
|
||||
tls_server_start(smtpd_tls_ctx, state->client,
|
||||
var_smtpd_starttls_tmout,
|
||||
state->name, state->addr, &(state->tls_info),
|
||||
(var_smtpd_tls_req_ccert && state->tls_enforce_tls));
|
||||
|
||||
/*
|
||||
* When the TLS handshake fails, the conversation is in an unknown state.
|
||||
@@ -3493,12 +3505,13 @@ static void post_jail_init(char *unused_name, char **unused_argv)
|
||||
* recipient checks, address mapping, header_body_checks?.
|
||||
*/
|
||||
smtpd_input_transp_mask =
|
||||
input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
|
||||
input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
|
||||
|
||||
/*
|
||||
* Sanity checks. The queue_minfree value should be at least as large as
|
||||
* (process_limit * message_size_limit) but that is unpractical, so we
|
||||
* arbitrarily pick a number and require twice the message size limit.
|
||||
* arbitrarily pick a small multiple of the per-message size limit. This
|
||||
* helps to avoid many unneeded (re)transmissions.
|
||||
*/
|
||||
if (var_queue_minfree > 0
|
||||
&& var_message_limit > 0
|
||||
|
@@ -43,6 +43,11 @@
|
||||
/* .IP "\fB-f \fIcommand,command,...\fR"
|
||||
/* Reject the specified commands with a hard (5xx) error code.
|
||||
/* This option implies \fB-p\fR.
|
||||
/* .sp
|
||||
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
/* white space or commas, and use quotes to protect white space
|
||||
/* from the shell. Command names are case-insensitive.
|
||||
/* .IP \fB-F\fR
|
||||
/* Disable XFORWARD support.
|
||||
/* .IP "\fB-h\fI hostname\fR"
|
||||
@@ -60,15 +65,26 @@
|
||||
/* .IP "\fB-q \fIcommand,command,...\fR"
|
||||
/* Disconnect (without replying) after receiving one of the
|
||||
/* specified commands.
|
||||
/* .sp
|
||||
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
/* white space or commas, and use quotes to protect white space
|
||||
/* from the shell. Command names are case-insensitive.
|
||||
/* .IP "\fB-r \fIcommand,command,...\fR"
|
||||
/* Reject the specified commands with a soft (4xx) error code.
|
||||
/* This option implies \fB-p\fR.
|
||||
/* .sp
|
||||
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
/* white space or commas, and use quotes to protect white space
|
||||
/* from the shell. Command names are case-insensitive.
|
||||
/* .IP "\fB-s \fIcommand,command,...\fR"
|
||||
/* Log the named commands to syslogd.
|
||||
/* Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
|
||||
/* RCPT, VRFY, RSET, NOOP, and QUIT. Separate command names by white
|
||||
/* space or commas, and use quotes to protect white space from the
|
||||
/* shell. Command names are case-insensitive.
|
||||
/* .sp
|
||||
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||
/* white space or commas, and use quotes to protect white space
|
||||
/* from the shell. Command names are case-insensitive.
|
||||
/* .IP "\fB-t \fItimeout\fR (default: 100)"
|
||||
/* Limit the time for receiving a command or sending a response.
|
||||
/* The time limit is specified in seconds.
|
||||
@@ -141,6 +157,7 @@ typedef struct SINK_STATE {
|
||||
int data_state;
|
||||
int (*read_fn) (struct SINK_STATE *);
|
||||
int rcpts;
|
||||
char *push_back_ptr;
|
||||
} SINK_STATE;
|
||||
|
||||
#define ST_ANY 0
|
||||
@@ -150,6 +167,10 @@ typedef struct SINK_STATE {
|
||||
#define ST_CR_LF_DOT_CR 4
|
||||
#define ST_CR_LF_DOT_CR_LF 5
|
||||
|
||||
#define PUSH_BACK_PEEK(state) (*(state)->push_back_ptr != 0)
|
||||
#define PUSH_BACK_GET(state) (*(state)->push_back_ptr++)
|
||||
#define PUSH_BACK_SET(state, text) ((state)->push_back_ptr = (text))
|
||||
|
||||
static int var_tmout = 100;
|
||||
static int var_max_line_length = 2048;
|
||||
static char *var_myhostname;
|
||||
@@ -170,6 +191,25 @@ static int disable_xclient;
|
||||
static int disable_xforward;
|
||||
static int disable_enh_status;
|
||||
|
||||
#define SOFT_ERROR_RESP "450 4.3.0 Error: command failed"
|
||||
#define HARD_ERROR_RESP "500 5.3.0 Error: command failed"
|
||||
|
||||
/* hard_err_resp - generic hard error response */
|
||||
|
||||
static void hard_err_resp(SINK_STATE *state)
|
||||
{
|
||||
smtp_printf(state->stream, HARD_ERROR_RESP);
|
||||
smtp_flush(state->stream);
|
||||
}
|
||||
|
||||
/* soft_err_resp - generic soft error response */
|
||||
|
||||
static void soft_err_resp(SINK_STATE *state)
|
||||
{
|
||||
smtp_printf(state->stream, SOFT_ERROR_RESP);
|
||||
smtp_flush(state->stream);
|
||||
}
|
||||
|
||||
/* ehlo_response - respond to EHLO command */
|
||||
|
||||
static void ehlo_response(SINK_STATE *state)
|
||||
@@ -244,6 +284,32 @@ static void data_event(int unused_event, char *context)
|
||||
data_response(state);
|
||||
}
|
||||
|
||||
/* dot_resp_hard - hard error response to . command */
|
||||
|
||||
static void dot_resp_hard(SINK_STATE *state)
|
||||
{
|
||||
if (enable_lmtp) {
|
||||
while (state->rcpts-- > 0) /* XXX this could block */
|
||||
smtp_printf(state->stream, HARD_ERROR_RESP);
|
||||
} else {
|
||||
smtp_printf(state->stream, HARD_ERROR_RESP);
|
||||
}
|
||||
smtp_flush(state->stream);
|
||||
}
|
||||
|
||||
/* dot_resp_soft - soft error response to . command */
|
||||
|
||||
static void dot_resp_soft(SINK_STATE *state)
|
||||
{
|
||||
if (enable_lmtp) {
|
||||
while (state->rcpts-- > 0) /* XXX this could block */
|
||||
smtp_printf(state->stream, SOFT_ERROR_RESP);
|
||||
} else {
|
||||
smtp_printf(state->stream, SOFT_ERROR_RESP);
|
||||
}
|
||||
smtp_flush(state->stream);
|
||||
}
|
||||
|
||||
/* dot_response - response to . command */
|
||||
|
||||
static void dot_response(SINK_STATE *state)
|
||||
@@ -312,9 +378,7 @@ static int data_read(SINK_STATE *state)
|
||||
else
|
||||
state->data_state = ST_ANY;
|
||||
if (state->data_state == ST_CR_LF_DOT_CR_LF) {
|
||||
if (msg_verbose)
|
||||
msg_info(".");
|
||||
dot_response(state);
|
||||
PUSH_BACK_SET(state, ".\r\n");
|
||||
state->read_fn = command_read;
|
||||
state->data_state = ST_ANY;
|
||||
break;
|
||||
@@ -337,6 +401,8 @@ static int data_read(SINK_STATE *state)
|
||||
typedef struct SINK_COMMAND {
|
||||
char *name;
|
||||
void (*response) (SINK_STATE *);
|
||||
void (*hard_response) (SINK_STATE *);
|
||||
void (*soft_response) (SINK_STATE *);
|
||||
int flags;
|
||||
} SINK_COMMAND;
|
||||
|
||||
@@ -347,19 +413,20 @@ typedef struct SINK_COMMAND {
|
||||
#define FLAG_DISCONNECT (1<<4) /* disconnect */
|
||||
|
||||
static SINK_COMMAND command_table[] = {
|
||||
"helo", helo_response, 0,
|
||||
"ehlo", ehlo_response, 0,
|
||||
"lhlo", ehlo_response, 0,
|
||||
"xclient", ok_response, FLAG_ENABLE,
|
||||
"xforward", ok_response, FLAG_ENABLE,
|
||||
"auth", ok_response, FLAG_ENABLE,
|
||||
"mail", mail_response, FLAG_ENABLE,
|
||||
"rcpt", rcpt_response, FLAG_ENABLE,
|
||||
"data", data_response, FLAG_ENABLE,
|
||||
"rset", ok_response, FLAG_ENABLE,
|
||||
"noop", ok_response, FLAG_ENABLE,
|
||||
"vrfy", ok_response, FLAG_ENABLE,
|
||||
"quit", quit_response, FLAG_ENABLE,
|
||||
"helo", helo_response, hard_err_resp, soft_err_resp, 0,
|
||||
"ehlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
|
||||
"lhlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
|
||||
"xclient", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"xforward", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"auth", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"mail", mail_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"rcpt", rcpt_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"data", data_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
".", dot_response, dot_resp_hard, dot_resp_soft, FLAG_ENABLE,
|
||||
"rset", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"noop", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"vrfy", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"quit", quit_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
0,
|
||||
};
|
||||
|
||||
@@ -428,8 +495,11 @@ static int command_read(SINK_STATE *state)
|
||||
* A read may result in EOF, but is never supposed to time out - a time
|
||||
* out means that we were trying to read when no data was available.
|
||||
*/
|
||||
#define NEXT_CHAR(state) \
|
||||
(PUSH_BACK_PEEK(state) ? PUSH_BACK_GET(state) : VSTREAM_GETC(state->stream))
|
||||
|
||||
for (;;) {
|
||||
if ((ch = VSTREAM_GETC(state->stream)) == VSTREAM_EOF)
|
||||
if ((ch = NEXT_CHAR(state)) == VSTREAM_EOF)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
@@ -467,7 +537,7 @@ static int command_read(SINK_STATE *state)
|
||||
* instead of peek_fd() (which uses ioctl FIONREAD). Workaround added
|
||||
* 20020604.
|
||||
*/
|
||||
if (vstream_peek(state->stream) <= 0
|
||||
if (PUSH_BACK_PEEK(state) == 0 && vstream_peek(state->stream) <= 0
|
||||
&& readable(vstream_fileno(state->stream)) <= 0)
|
||||
return (0);
|
||||
}
|
||||
@@ -501,21 +571,19 @@ static int command_read(SINK_STATE *state)
|
||||
smtp_flush(state->stream);
|
||||
return (0);
|
||||
}
|
||||
if (cmdp->flags & FLAG_DISCONNECT)
|
||||
return (-1);
|
||||
if (cmdp->flags & FLAG_HARD_ERR) {
|
||||
smtp_printf(state->stream, "500 5.3.0 Error: command failed");
|
||||
smtp_flush(state->stream);
|
||||
return (0);
|
||||
}
|
||||
if (cmdp->flags & FLAG_SOFT_ERR) {
|
||||
smtp_printf(state->stream, "450 4.3.0 Error: command failed");
|
||||
smtp_flush(state->stream);
|
||||
return (0);
|
||||
}
|
||||
/* We use raw syslog. Sanitize data content and length. */
|
||||
if (cmdp->flags & FLAG_SYSLOG)
|
||||
syslog(LOG_INFO, "%s %.100s", command, printable(ptr, '?'));
|
||||
if (cmdp->flags & FLAG_DISCONNECT)
|
||||
return (-1);
|
||||
if (cmdp->flags & FLAG_HARD_ERR) {
|
||||
cmdp->hard_response(state);
|
||||
return (0);
|
||||
}
|
||||
if (cmdp->flags & FLAG_SOFT_ERR) {
|
||||
cmdp->soft_response(state);
|
||||
return (0);
|
||||
}
|
||||
if (cmdp->response == data_response && fixed_delay > 0) {
|
||||
event_request_timer(data_event, (char *) state, fixed_delay);
|
||||
} else {
|
||||
@@ -582,7 +650,7 @@ static void read_event(int unused_event, char *context)
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (vstream_peek(state->stream) > 0);
|
||||
} while (PUSH_BACK_PEEK(state) != 0 || vstream_peek(state->stream) > 0);
|
||||
|
||||
/*
|
||||
* Reset the idle timer. Wait until the next input event, or until the
|
||||
@@ -633,6 +701,7 @@ static void connect_event(int unused_event, char *context)
|
||||
state->buffer = vstring_alloc(1024);
|
||||
state->read_fn = command_read;
|
||||
state->data_state = ST_ANY;
|
||||
PUSH_BACK_SET(state, "");
|
||||
smtp_timeout_setup(state->stream, var_tmout);
|
||||
|
||||
/*
|
||||
|
@@ -56,7 +56,8 @@
|
||||
/* length, and an attribute value pointer.
|
||||
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
|
||||
/* This argument is followed by a function pointer and generic data
|
||||
/* pointer.
|
||||
/* pointer. The caller-specified function returns whatever the
|
||||
/* specified attribute printing function returns.
|
||||
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
|
||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||
/* The content of the table is sent as a sequence of string-valued
|
||||
|
@@ -51,6 +51,10 @@
|
||||
/* .IP "ATTR_TYPE_STR (char *, char *)"
|
||||
/* This argument is followed by an attribute name and a null-terminated
|
||||
/* string.
|
||||
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
|
||||
/* This argument is followed by a function pointer and generic data
|
||||
/* pointer. The caller-specified function returns whatever the
|
||||
/* specified attribute printing function returns.
|
||||
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
|
||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||
/* The content of the table is sent as a sequence of string-valued
|
||||
@@ -142,6 +146,8 @@ int attr_vprint64(VSTREAM *fp, int flags, va_list ap)
|
||||
HTABLE_INFO **ht_info_list;
|
||||
HTABLE_INFO **ht;
|
||||
int len_val;
|
||||
ATTR_PRINT_SLAVE_FN print_fn;
|
||||
void *print_arg;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
@@ -196,6 +202,11 @@ int attr_vprint64(VSTREAM *fp, int flags, va_list ap)
|
||||
if (msg_verbose)
|
||||
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
|
||||
break;
|
||||
case ATTR_TYPE_FUNC:
|
||||
print_fn = va_arg(ap, ATTR_PRINT_SLAVE_FN);
|
||||
print_arg = va_arg(ap, void *);
|
||||
print_fn(attr_print64, fp, flags | ATTR_FLAG_MORE, print_arg);
|
||||
break;
|
||||
case ATTR_TYPE_HASH:
|
||||
ht_info_list = htable_list(va_arg(ap, HTABLE *));
|
||||
for (ht = ht_info_list; *ht; ht++) {
|
||||
|
@@ -54,6 +54,10 @@
|
||||
/* .IP "ATTR_TYPE_DATA (char *, int, char *)"
|
||||
/* This argument is followed by an attribute name, an attribute value
|
||||
/* length, and a pointer to attribute value.
|
||||
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
|
||||
/* This argument is followed by a function pointer and generic data
|
||||
/* pointer. The caller-specified function returns whatever the
|
||||
/* specified attribute printing function returns.
|
||||
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
|
||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||
/* The content of the table is sent as a sequence of string-valued
|
||||
@@ -112,6 +116,8 @@ int attr_vprint_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
HTABLE_INFO **ht;
|
||||
static VSTRING *base64_buf;
|
||||
int len_val;
|
||||
ATTR_PRINT_SLAVE_FN print_fn;
|
||||
void *print_arg;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
@@ -157,6 +163,11 @@ int attr_vprint_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
if (msg_verbose)
|
||||
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
|
||||
break;
|
||||
case ATTR_TYPE_FUNC:
|
||||
print_fn = va_arg(ap, ATTR_PRINT_SLAVE_FN);
|
||||
print_arg = va_arg(ap, void *);
|
||||
print_fn(attr_print_plain, fp, flags | ATTR_FLAG_MORE, print_arg);
|
||||
break;
|
||||
case ATTR_TYPE_HASH:
|
||||
ht_info_list = htable_list(va_arg(ap, HTABLE *));
|
||||
for (ht = ht_info_list; *ht; ht++) {
|
||||
|
@@ -95,7 +95,8 @@
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
|
||||
/* This argument is followed by a function pointer and a generic data
|
||||
/* pointer.
|
||||
/* pointer. The caller-specified function returns < 0 in case of
|
||||
/* error.
|
||||
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
|
||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||
/* All further input attributes are processed as string attributes.
|
||||
|
@@ -47,7 +47,7 @@
|
||||
/* characters. The formatting rules aim to make implementations in PERL
|
||||
/* and other languages easy.
|
||||
/*
|
||||
/* Normally, attributes must be received in the sequence as specified with
|
||||
/* Normally, attributes must be received in the sequence as specified with
|
||||
/* the attr_scan64() argument list. The input stream may contain additional
|
||||
/* attributes at any point in the input stream, including additional
|
||||
/* instances of requested attributes.
|
||||
@@ -95,6 +95,10 @@
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
|
||||
/* This argument is followed by a function pointer and a generic data
|
||||
/* pointer. The caller-specified function returns < 0 in case of
|
||||
/* error.
|
||||
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
|
||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||
/* All further input attributes are processed as string attributes.
|
||||
@@ -165,9 +169,11 @@
|
||||
static int attr_scan64_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
|
||||
{
|
||||
static VSTRING *base64_buf = 0;
|
||||
|
||||
#if 0
|
||||
extern int var_line_limit; /* XXX */
|
||||
int limit = var_line_limit * 4;
|
||||
|
||||
#endif
|
||||
int ch;
|
||||
|
||||
@@ -254,6 +260,8 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
||||
HTABLE *hash_table;
|
||||
int ch;
|
||||
int conversions;
|
||||
ATTR_SCAN_SLAVE_FN scan_fn;
|
||||
void *scan_arg;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
@@ -295,7 +303,7 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
||||
if (va_arg(ap, int) !=ATTR_TYPE_END)
|
||||
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
|
||||
myname);
|
||||
} else {
|
||||
} else if (wanted_type != ATTR_TYPE_FUNC) {
|
||||
wanted_name = va_arg(ap, char *);
|
||||
}
|
||||
}
|
||||
@@ -303,7 +311,7 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
||||
/*
|
||||
* Locate the next attribute of interest in the input stream.
|
||||
*/
|
||||
for (;;) {
|
||||
while (wanted_type != ATTR_TYPE_FUNC) {
|
||||
|
||||
/*
|
||||
* Get the name of the next attribute. Hitting EOF is always bad.
|
||||
@@ -419,6 +427,12 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
case ATTR_TYPE_FUNC:
|
||||
scan_fn = va_arg(ap, ATTR_SCAN_SLAVE_FN);
|
||||
scan_arg = va_arg(ap, void *);
|
||||
if (scan_fn(attr_scan64, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||
return (-1);
|
||||
break;
|
||||
case ATTR_TYPE_HASH:
|
||||
if (ch != ':') {
|
||||
msg_warn("missing value for string attribute %s from %s",
|
||||
|
@@ -45,7 +45,7 @@
|
||||
/* characters. The formatting rules aim to make implementations in PERL
|
||||
/* and other languages easy.
|
||||
/*
|
||||
/* Normally, attributes must be received in the sequence as specified
|
||||
/* Normally, attributes must be received in the sequence as specified
|
||||
/* with the attr_scan_plain() argument list. The input stream may
|
||||
/* contain additional attributes at any point in the input stream,
|
||||
/* including additional instances of requested attributes.
|
||||
@@ -93,6 +93,10 @@
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
|
||||
/* This argument is followed by a function pointer and a generic data
|
||||
/* pointer. The caller-specified function returns < 0 in case of
|
||||
/* error.
|
||||
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
|
||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||
/* All further input attributes are processed as string attributes.
|
||||
@@ -166,6 +170,7 @@ static int attr_scan_plain_string(VSTREAM *fp, VSTRING *plain_buf,
|
||||
#if 0
|
||||
extern int var_line_limit; /* XXX */
|
||||
int limit = var_line_limit * 4;
|
||||
|
||||
#endif
|
||||
int ch;
|
||||
|
||||
@@ -268,6 +273,8 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
HTABLE *hash_table;
|
||||
int ch;
|
||||
int conversions;
|
||||
ATTR_SCAN_SLAVE_FN scan_fn;
|
||||
void *scan_arg;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
@@ -309,7 +316,7 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
if (va_arg(ap, int) !=ATTR_TYPE_END)
|
||||
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
|
||||
myname);
|
||||
} else {
|
||||
} else if (wanted_type != ATTR_TYPE_FUNC) {
|
||||
wanted_name = va_arg(ap, char *);
|
||||
}
|
||||
}
|
||||
@@ -317,7 +324,7 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
/*
|
||||
* Locate the next attribute of interest in the input stream.
|
||||
*/
|
||||
for (;;) {
|
||||
while (wanted_type != ATTR_TYPE_FUNC) {
|
||||
|
||||
/*
|
||||
* Get the name of the next attribute. Hitting EOF is always bad.
|
||||
@@ -361,12 +368,7 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the requested conversion. If the target attribute is a
|
||||
* non-array type, disallow sending a multi-valued attribute, and
|
||||
* disallow sending no value. If the target attribute is an array
|
||||
* type, allow the sender to send a zero-element array (i.e. no value
|
||||
* at all). XXX Need to impose a bound on the number of array
|
||||
* elements.
|
||||
* Do the requested conversion.
|
||||
*/
|
||||
switch (wanted_type) {
|
||||
case ATTR_TYPE_NUM:
|
||||
@@ -413,6 +415,12 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
"input attribute value")) < 0)
|
||||
return (-1);
|
||||
break;
|
||||
case ATTR_TYPE_FUNC:
|
||||
scan_fn = va_arg(ap, ATTR_SCAN_SLAVE_FN);
|
||||
scan_arg = va_arg(ap, void *);
|
||||
if (scan_fn(attr_scan_plain, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||
return (-1);
|
||||
break;
|
||||
case ATTR_TYPE_HASH:
|
||||
if (ch != '=') {
|
||||
msg_warn("missing value for string attribute %s from %s",
|
||||
|
Reference in New Issue
Block a user