2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 13:48:06 +00:00

postfix-2.6-20081203

This commit is contained in:
Wietse Venema
2008-12-03 00:00:00 -05:00
committed by Viktor Dukhovni
parent 3aba869192
commit c1d7325cd1
16 changed files with 163 additions and 83 deletions

View File

@@ -14745,8 +14745,8 @@ Apologies for any names omitted.
Feature: smtp_sasl_tls_verified_security_options is no
longer #ifdef SNAPSHOT.
Feature: elliptic curve support. This requires OpenSSL version
0.9.9 or later. Victor Duchovni. Files: TLS_README,
Feature: elliptic curve support. This requires OpenSSL
version 0.9.9 or later. Victor Duchovni. Files: TLS_README,
smtpd/smtpd.c, smtp/smtp.c, tls/tls_dh.c, tls/tls_certkey.c,
tls/tls_server.c, tls/tls_client.c, tls/tls.h, tls/tls_misc.c.
@@ -14757,3 +14757,29 @@ Apologies for any names omitted.
20081109
Cleanup: confusing names of variables. File: smtpd/smtpd.c.
20081126
Bugfix: pcre_table(5) incorrectly claimed that the 'x' flag
supports #comment after text. File: proto/pcre_table.
20081202
Cleanup: vstream_bufstat() provides a more systematic
approach to get information about VSTREAM buffers. The
vstream_peek() function is now a backwards compatibility
wrapper. Files: util/vstream.[hc].
Cleanup: the SMTP server should warn about "lost connection
after QUIT" only when the "." reply was pipelined together
with the "QUIT" reply. File: smtpd/smtpd.c.
Cleanup: the SMTP client's code was duplicating buffer
management that was already done in the VSTREAM module.
File: smtp/smtp_proto.c.
20081203
Cleanup: adjust the VSTREAM buffer strategy when reusing
an SMTP connection with a large TCP MSS value. File:
smtp/smtp_proto.c.

View File

@@ -4,10 +4,10 @@ PPoossttffiixx AArrcchhiitteeccttuurree OOvveerrvviiee
IInnttrroodduuccttiioonn
This document presents an overview of the Postfix architecture, and is the
place where you find a pointer to every Postfix command or server program. The
text gives the general context in which each command or server program is used,
and provides pointers to documents with specific usage examples and background
This document presents an overview of the Postfix architecture, and provides
pointers to descriptions of every Postfix command or server program. The text
gives the general context in which each command or server program is used, and
provides pointers to documents with specific usage examples and background
information.
Topics covered by this document:
@@ -63,7 +63,7 @@ programs, while unnumbered names inside shaded areas represent Postfix queues.
section), and postmaster notifications about problems with Postfix.
* The cleanup(8) server implements the final processing stage before mail is
queued. It adds missing From: and other message headers, transforms
queued. It adds missing From: and other message headers, and transforms
addresses as described in the ADDRESS_REWRITING_README document.
Optionally, the cleanup(8) server can be configured to do light-weight
content inspection with regular expressions as described in the

View File

@@ -21,7 +21,7 @@ Architecture Overview </h1>
<h2> Introduction </h2>
<p> This document presents an overview of the Postfix architecture,
and is the place where you find a pointer to every Postfix command
and provides pointers to descriptions of every Postfix command
or server program. The text gives the general context in which
each command or server program is used, and provides pointers to
documents with specific usage examples and background information.
@@ -173,7 +173,8 @@ notifications about problems with Postfix. </p>
<li> <p> The <a href="cleanup.8.html">cleanup(8)</a> server implements the final processing
stage before mail is queued. It adds missing From: and other message
headers, transforms addresses as described in the <a href="ADDRESS_REWRITING_README.html">ADDRESS_REWRITING_README</a>
headers, and transforms addresses as described in the
<a href="ADDRESS_REWRITING_README.html">ADDRESS_REWRITING_README</a>
document. Optionally, the <a href="cleanup.8.html">cleanup(8)</a> server can be configured to
do light-weight content inspection with regular expressions as
described in the <a href="BUILTIN_FILTER_README.html">BUILTIN_FILTER_README</a> document. The <a href="cleanup.8.html">cleanup(8)</a>

View File

@@ -110,12 +110,12 @@ PCRE_TABLE(5) PCRE_TABLE(5)
<b>x</b> (default: off)
Toggles the pcre extended flag. When this flag is
on, whitespace in the pattern (other than in a
character class) and characters between a <b>#</b> outside
a character class and the next newline character
are ignored. An escaping backslash can be used to
include a whitespace or <b>#</b> character as part of the
pattern.
on, whitespace characters in the pattern (other
than in a character class) are ignored. To include
a whitespace character as part of the pattern,
escape it with backslash.
Note: do not use <b>#</b><i>comment</i> after patterns.
<b>A</b> (default: off)
Toggles the PCRE_ANCHORED flag. When this flag is

View File

@@ -100,11 +100,11 @@ default, which is inconvenient for multi-line message header
matching.
.IP "\fBx\fR (default: off)"
Toggles the pcre extended flag. When this flag is on, whitespace
in the pattern (other than in a character class) and
characters between a \fB#\fR outside a character class and
the next newline character are ignored. An escaping backslash
can be used to include a whitespace or \fB#\fR character
as part of the pattern.
characters in the pattern (other than in a character class)
are ignored. To include a whitespace character as part of
the pattern, escape it with backslash.
.sp
Note: do not use \fB#\fIcomment\fR after patterns.
.IP "\fBA\fR (default: off)"
Toggles the PCRE_ANCHORED flag. When this flag is on,
the pattern is forced to be "anchored", that is, it is

View File

@@ -21,7 +21,7 @@ Architecture Overview </h1>
<h2> Introduction </h2>
<p> This document presents an overview of the Postfix architecture,
and is the place where you find a pointer to every Postfix command
and provides pointers to descriptions of every Postfix command
or server program. The text gives the general context in which
each command or server program is used, and provides pointers to
documents with specific usage examples and background information.
@@ -173,7 +173,8 @@ notifications about problems with Postfix. </p>
<li> <p> The cleanup(8) server implements the final processing
stage before mail is queued. It adds missing From: and other message
headers, transforms addresses as described in the ADDRESS_REWRITING_README
headers, and transforms addresses as described in the
ADDRESS_REWRITING_README
document. Optionally, the cleanup(8) server can be configured to
do light-weight content inspection with regular expressions as
described in the BUILTIN_FILTER_README document. The cleanup(8)

View File

@@ -90,11 +90,11 @@
# matching.
# .IP "\fBx\fR (default: off)"
# Toggles the pcre extended flag. When this flag is on, whitespace
# in the pattern (other than in a character class) and
# characters between a \fB#\fR outside a character class and
# the next newline character are ignored. An escaping backslash
# can be used to include a whitespace or \fB#\fR character
# as part of the pattern.
# characters in the pattern (other than in a character class)
# are ignored. To include a whitespace character as part of
# the pattern, escape it with backslash.
# .sp
# Note: do not use \fB#\fIcomment\fR after patterns.
# .IP "\fBA\fR (default: off)"
# Toggles the PCRE_ANCHORED flag. When this flag is on,
# the pattern is forced to be "anchored", that is, it is

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 "20081109"
#define MAIL_RELEASE_DATE "20081203"
#define MAIL_VERSION_NUMBER "2.6"
#ifdef SNAPSHOT

View File

@@ -208,7 +208,6 @@ typedef struct SMTP_SESSION {
int error_mask; /* error classes */
struct MIME_STATE *mime_state; /* mime state machine */
int sndbufsize; /* PIPELINING buffer size */
int send_proto_helo; /* XFORWARD support */
time_t expire_time; /* session reuse expiration time */

View File

@@ -274,6 +274,7 @@ int smtp_helo(SMTP_STATE *state)
0, 0,
};
SOCKOPT_SIZE optlen;
int sndbufsize;
const char *ehlo_words;
int discard_mask;
static const NAME_MASK pix_bug_table[] = {
@@ -559,27 +560,24 @@ int smtp_helo(SMTP_STATE *state)
* if we do.
*/
if (session->features & SMTP_FEATURE_PIPELINING) {
optlen = sizeof(session->sndbufsize);
optlen = sizeof(sndbufsize);
if (getsockopt(vstream_fileno(session->stream), SOL_SOCKET,
SO_SNDBUF, (char *) &session->sndbufsize, &optlen) < 0)
SO_SNDBUF, (char *) &sndbufsize, &optlen) < 0)
msg_fatal("%s: getsockopt: %m", myname);
if (session->sndbufsize > VSTREAM_BUFSIZE)
session->sndbufsize = VSTREAM_BUFSIZE;
if (session->sndbufsize == 0) {
session->sndbufsize = VSTREAM_BUFSIZE;
if (sndbufsize > VSTREAM_BUFSIZE)
sndbufsize = VSTREAM_BUFSIZE;
if (sndbufsize < VSTREAM_BUFSIZE) {
sndbufsize = VSTREAM_BUFSIZE;
if (setsockopt(vstream_fileno(session->stream), SOL_SOCKET,
SO_SNDBUF, (char *) &session->sndbufsize, optlen) < 0)
SO_SNDBUF, (char *) &sndbufsize, optlen) < 0)
msg_fatal("%s: setsockopt: %m", myname);
}
if (msg_verbose)
msg_info("Using %s PIPELINING, TCP send buffer size is %d",
(state->misc_flags &
SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP",
session->sndbufsize);
} else {
session->sndbufsize = 0;
sndbufsize);
}
#ifdef USE_TLS
/*
@@ -1081,7 +1079,6 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
int except;
int rec_type;
NOCLOBBER int prev_type = 0;
NOCLOBBER int sndbuffree;
NOCLOBBER int mail_from_rejected;
NOCLOBBER int downgrading;
int mime_errs;
@@ -1131,20 +1128,6 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
#define CANT_RSET_THIS_SESSION \
(session->features |= SMTP_FEATURE_RSET_REJECTED)
/*
* Sanity check. We don't want smtp_chat() to inadvertently flush the
* output buffer. That means someone broke pipelining support.
*/
if (session->sndbufsize > VSTREAM_BUFSIZE)
msg_panic("bad sndbufsize %d > VSTREAM_BUFSIZE %d",
session->sndbufsize, VSTREAM_BUFSIZE);
/*
* Miscellaneous initialization. Some of this might be done in
* smtp_xfer() but that just complicates interfaces and data structures.
*/
sndbuffree = session->sndbufsize;
/*
* Pipelining support requires two loops: one loop for sending and one
* for receiving. Each loop has its own independent state. Most of the
@@ -1432,8 +1415,12 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
*/
if (SENDER_IN_WAIT_STATE
|| (SENDER_IS_AHEAD
&& (VSTRING_LEN(next_command) + 2 > sndbuffree
|| time((time_t *) 0) - vstream_ftime(session->stream) > 10))) {
&& ((session->features & SMTP_FEATURE_PIPELINING) == 0
|| (VSTRING_LEN(next_command) + 2
+ vstream_bufstat(session->stream, VSTREAM_BST_OUT_PEND)
> VSTREAM_BUFSIZE)
|| time((time_t *) 0)
- vstream_ftime(session->stream) > 10))) {
while (SENDER_IS_AHEAD) {
/*
@@ -1707,10 +1694,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
}
/*
* At this point, the sender and receiver are fully synchronized,
* so that the entire TCP send buffer becomes available again.
* At this point, the sender and receiver are fully synchronized.
*/
sndbuffree = session->sndbufsize;
/*
* We know the server response to every command that was sent.
@@ -1874,8 +1859,6 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
* Copy the next command to the buffer and update the sender state.
*/
if (except == 0) {
if (sndbuffree > 0)
sndbuffree -= VSTRING_LEN(next_command) + 2;
smtp_chat_cmd(session, "%s", vstring_str(next_command));
} else {
DONT_CACHE_THIS_SESSION;

View File

@@ -213,6 +213,11 @@ static SMTP_SESSION *smtp_reuse_common(SMTP_STATE *state, int fd,
return (state->session = 0);
}
/*
* Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE.
*/
vstream_tweak_sock(session->stream);
/*
* Update the list of used cached addresses.
*/

View File

@@ -585,7 +585,6 @@ SMTP_SESSION *smtp_session_alloc(VSTREAM *stream, const char *dest,
} else
session->namaddrport = mystrdup(session->namaddr);
session->sndbufsize = 0;
session->send_proto_helo = 0;
if (flags & SMTP_MISC_FLAG_CONN_STORE)
@@ -695,13 +694,12 @@ int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
* XXX Be sure to use unsigned types in the format string. Sign characters
* would be rejected by the alldig() test on the reading end.
*/
vstring_sprintf(endp_prop, "%u\n%s\n%s\n%s\n%u\n%u\n%lu\n%u",
vstring_sprintf(endp_prop, "%u\n%s\n%s\n%s\n%u\n%u\n%lu",
session->reuse_count,
session->dest, session->host,
session->addr, session->port,
session->features & SMTP_FEATURE_ENDPOINT_MASK,
(long) session->expire_time,
session->sndbufsize);
(long) session->expire_time);
/*
* Append the passivated SASL attributes.
@@ -740,7 +738,6 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
unsigned features; /* server features */
time_t expire_time; /* session re-use expiration time */
unsigned reuse_count; /* # times reused */
unsigned sndbufsize; /* PIPELINING buffer size */
/*
* XXX it would be nice to have a VSTRING to VSTREAM adapter so that we
@@ -790,12 +787,6 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
expire_time = strtoul(prop, 0, 10);
#endif
if ((prop = mystrtok(&endp_props, "\n")) == 0 || !alldig(prop)) {
msg_warn("%s: bad cached session sndbufsize property", myname);
return (0);
}
sndbufsize = atoi(prop);
if (dest_prop && VSTRING_LEN(dest_prop)) {
dest_props = STR(dest_prop);
if ((prop = mystrtok(&dest_props, "\n")) == 0 || !alldig(prop)) {
@@ -815,14 +806,12 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
session->features = (features | SMTP_FEATURE_FROM_CACHE);
CACHE_THIS_SESSION_UNTIL(expire_time);
session->reuse_count = ++reuse_count;
session->sndbufsize = sndbufsize;
if (msg_verbose)
msg_info("%s: dest=%s host=%s addr=%s port=%u features=0x%x, "
"ttl=%ld, reuse=%d, sndbuf=%u",
"ttl=%ld, reuse=%d",
myname, dest, host, addr, ntohs(port), features,
(long) (expire_time - time((time_t *) 0)), reuse_count,
sndbufsize);
(long) (expire_time - time((time_t *) 0)), reuse_count);
/*
* Re-activate the SASL attributes.

View File

@@ -1266,7 +1266,7 @@ MILTERS *smtpd_milters;
* TLS initialization status.
*/
static TLS_APPL_STATE *smtpd_tls_ctx;
static int require_server_cert;
static int ask_client_cert;
#endif
@@ -3286,7 +3286,8 @@ static int quit_cmd(SMTPD_STATE *state, int unused_argc, SMTPD_TOKEN *unused_arg
* 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.
*/
smtp_flush(state->client);
if (vstream_bufstat(state->client, VSTREAM_BST_OUT_PEND) > 0)
smtp_flush(state->client);
return (0);
}
@@ -3857,7 +3858,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
ADD_EXCLUDE(cipher_exclusions, var_smtpd_tls_excl_ciph);
if (enforce_tls)
ADD_EXCLUDE(cipher_exclusions, var_smtpd_tls_mand_excl);
if (require_server_cert)
if (ask_client_cert)
ADD_EXCLUDE(cipher_exclusions, "aNULL");
}
@@ -4645,7 +4646,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
const char *cert_file;
int have_server_cert;
int no_server_cert_ok;
int ask_client_cert;
int require_server_cert;
/*
* Can't use anonymous ciphers if we want client certificates.

View File

@@ -130,6 +130,13 @@ extern char *gai_strerror(int);
* Routines and data structures to hide some of the complexity of the
* addrinfo API. They still don't hide that we may get results for address
* families that we aren't interested in.
*
* Note: the getnameinfo() and inet_ntop() system library functions use unsafe
* APIs with separate pointer and length arguments. To avoid buffer overflow
* problems with these functions, Postfix uses pointers to structures
* internally. This way the compiler can enforce that callers provide
* buffers with the appropriate length, instead of having to trust that
* callers will never mess up some length calculation.
*/
typedef struct {
char buf[MAI_HOSTNAME_STRSIZE];

View File

@@ -101,6 +101,10 @@
/* const char *format;
/* va_list *ap;
/*
/* ssize_t vstream_bufstat(stream, command)
/* VSTREAM *stream;
/* int command;
/*
/* ssize_t vstream_peek(stream)
/* VSTREAM *stream;
/*
@@ -320,8 +324,18 @@
/* vstream_vfprintf() provides an alternate interface
/* for formatting an argument list according to a format string.
/*
/* vstream_bufstat() provides input and output buffer status
/* information. The command is one of the following:
/* .IP VSTREAM_BST_IN_PEND
/* Return the number of characters that can be read without
/* refilling the read buffer.
/* .IP VSTREAM_BST_OUT_PEND
/* Return the number of characters that are waiting in the
/* write buffer.
/* .PP
/* vstream_peek() returns the number of characters that can be
/* read from the named stream without refilling the read buffer.
/* This is an alias for vstream_bufstat(stream, VSTREAM_BST_IN_PEND).
/*
/* vstream_setjmp() saves processing context and makes that context
/* available for use with vstream_longjmp(). Normally, vstream_setjmp()
@@ -703,8 +717,10 @@ static int vstream_buf_get_ready(VBUF *bp)
* allocation gives the application a chance to override the default
* buffering policy.
*/
if (bp->data == 0)
vstream_buf_alloc(bp, VSTREAM_BUFSIZE);
if (stream->req_bufsize == 0)
stream->req_bufsize = VSTREAM_BUFSIZE;
if (bp->len < stream->req_bufsize)
vstream_buf_alloc(bp, stream->req_bufsize);
/*
* If the stream is double-buffered and the write buffer is not empty,
@@ -1306,6 +1322,47 @@ VSTREAM *vstream_vfprintf(VSTREAM *vp, const char *format, va_list ap)
return (vp);
}
/* vstream_bufstat - get stream buffer status */
ssize_t vstream_bufstat(VSTREAM *vp, int command)
{
VBUF *bp;
switch (command & VSTREAM_BST_MASK_DIR) {
case VSTREAM_BST_FLAG_IN:
if (vp->buf.flags & VSTREAM_FLAG_READ) {
bp = &vp->buf;
} else if (vp->buf.flags & VSTREAM_FLAG_DOUBLE) {
bp = &vp->read_buf;
} else {
bp = 0;
}
switch (command & ~VSTREAM_BST_MASK_DIR) {
case VSTREAM_BST_FLAG_PEND:
return (bp ? -bp->cnt : 0);
/* Add other requests below. */
}
break;
case VSTREAM_BST_FLAG_OUT:
if (vp->buf.flags & VSTREAM_FLAG_WRITE) {
bp = &vp->buf;
} else if (vp->buf.flags & VSTREAM_FLAG_DOUBLE) {
bp = &vp->write_buf;
} else {
bp = 0;
}
switch (command & ~VSTREAM_BST_MASK_DIR) {
case VSTREAM_BST_FLAG_PEND:
return (bp ? bp->len - bp->cnt : 0);
/* Add other requests below. */
}
break;
}
msg_panic("vstream_bufstat: unknown command: %d", command);
}
#undef vstream_peek /* API binary compatibility. */
/* vstream_peek - peek at a stream */
ssize_t vstream_peek(VSTREAM *vp)

View File

@@ -154,6 +154,17 @@ extern int vstream_pclose(VSTREAM *);
extern VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list);
extern ssize_t vstream_peek(VSTREAM *);
extern ssize_t vstream_bufstat(VSTREAM *, int);
#define VSTREAM_BST_FLAG_IN (1<<0)
#define VSTREAM_BST_FLAG_OUT (1<<1)
#define VSTREAM_BST_FLAG_PEND (1<<2)
#define VSTREAM_BST_MASK_DIR (VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_OUT)
#define VSTREAM_BST_IN_PEND (VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_PEND)
#define VSTREAM_BST_OUT_PEND (VSTREAM_BST_FLAG_OUT | VSTREAM_BST_FLAG_PEND)
#define vstream_peek(vp) vstream_bufstat((vp), VSTREAM_BST_IN_PEND)
/*
* Exception handling. We use pointer to jmp_buf to avoid a lot of unused