2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 21:27:57 +00:00

postfix-2.8-20110103

This commit is contained in:
Wietse Venema 2011-01-03 00:00:00 -05:00 committed by Viktor Dukhovni
parent fdd520cf24
commit 19c1ec2275
14 changed files with 245 additions and 148 deletions

View File

@ -16337,5 +16337,15 @@ Apologies for any names omitted.
TLS <=> plaintext for postscreen(8). One tlsproxy(8) process TLS <=> plaintext for postscreen(8). One tlsproxy(8) process
can translate traffic for multiple remote SMTP clients. can translate traffic for multiple remote SMTP clients.
With early testing feedback from Victor Duchovni and Christian With early testing feedback from Victor Duchovni and Christian
Roessner. Files: util/nbbio.c, tlsproxy/starttlsd.c, Roessner. Files: util/nbbio.[hc], tlsproxy/*.[hc],
tlsproxy/starttlsd_state.c. postscreen/postscreen_starttlsd.c, postscreen/postscreen_smtpd.c.
20101103
Cleanup: missing tls_level support in tlsproxy (it has no
way to send plaintext, but perhaps an informative error
message is in order anyway). File: tlsproxy/tlsproxy.c.
Cleanup: simplified the handling of throttled output (i.e.
output that can't be sent because the receiver tries to be
nasty). File: postscreen/postscreen_send.c.

View File

@ -4,7 +4,12 @@ Wish list:
anvil rate limit for sasl_username. anvil rate limit for sasl_username.
encapsulate nbbio buffer access and update by tlsproxy. Encapsulate nbbio buffer access and update by tlsproxy.
Full-duplex support for tlsproxy(8). This requires updating
events(3) and nbbio(3).
Register automagic destructor for object attached to VSTREAM.
smtpd xclient option for sasl_username. smtpd xclient option for sasl_username.

View File

@ -60,12 +60,15 @@ POSTSCREEN(8) POSTSCREEN(8)
<a href="http://tools.ietf.org/html/rfc3207">RFC 3207</a> (STARTTLS command) <a href="http://tools.ietf.org/html/rfc3207">RFC 3207</a> (STARTTLS command)
<a href="http://tools.ietf.org/html/rfc3461">RFC 3461</a> (SMTP DSN Extension) <a href="http://tools.ietf.org/html/rfc3461">RFC 3461</a> (SMTP DSN Extension)
<a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes) <a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes)
<a href="http://tools.ietf.org/html/rfc5321">RFC 5321</a> (SMTP protocol, including multi-line 220 greetings) <a href="http://tools.ietf.org/html/rfc5321">RFC 5321</a> (SMTP protocol, including multi-line 220 banners)
<b>DIAGNOSTICS</b> <b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Problems and transactions are logged to <b>syslogd</b>(8).
<b>BUGS</b> <b>BUGS</b>
The <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server does not yet implement the
<b><a href="postconf.5.html#soft_bounce">soft_bounce</a></b> feature.
The <a href="postscreen.8.html"><b>postscreen</b>(8)</a> built-in SMTP protocol engine currently The <a href="postscreen.8.html"><b>postscreen</b>(8)</a> built-in SMTP protocol engine currently
does not announce support for AUTH, XCLIENT or XFORWARD. does not announce support for AUTH, XCLIENT or XFORWARD.
Support for AUTH may be added in the future. In the mean Support for AUTH may be added in the future. In the mean

View File

@ -63,7 +63,7 @@ RFC 2920 (SMTP Pipelining)
RFC 3207 (STARTTLS command) RFC 3207 (STARTTLS command)
RFC 3461 (SMTP DSN Extension) RFC 3461 (SMTP DSN Extension)
RFC 3463 (Enhanced Status Codes) RFC 3463 (Enhanced Status Codes)
RFC 5321 (SMTP protocol, including multi-line 220 greetings) RFC 5321 (SMTP protocol, including multi-line 220 banners)
.SH DIAGNOSTICS .SH DIAGNOSTICS
.ad .ad
.fi .fi
@ -71,6 +71,9 @@ Problems and transactions are logged to \fBsyslogd\fR(8).
.SH BUGS .SH BUGS
.ad .ad
.fi .fi
The \fBpostscreen\fR(8) server does not yet implement
the \fBsoft_bounce\fR feature.
The \fBpostscreen\fR(8) built-in SMTP protocol engine The \fBpostscreen\fR(8) built-in SMTP protocol engine
currently does not announce support for AUTH, XCLIENT or currently does not announce support for AUTH, XCLIENT or
XFORWARD. XFORWARD.

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20110102" #define MAIL_RELEASE_DATE "20110103"
#define MAIL_VERSION_NUMBER "2.8" #define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@ -180,6 +180,7 @@ postscreen_send.o: ../../include/dict_cache.h
postscreen_send.o: ../../include/events.h postscreen_send.o: ../../include/events.h
postscreen_send.o: ../../include/htable.h postscreen_send.o: ../../include/htable.h
postscreen_send.o: ../../include/iostuff.h postscreen_send.o: ../../include/iostuff.h
postscreen_send.o: ../../include/mail_params.h
postscreen_send.o: ../../include/match_list.h postscreen_send.o: ../../include/match_list.h
postscreen_send.o: ../../include/match_ops.h postscreen_send.o: ../../include/match_ops.h
postscreen_send.o: ../../include/msg.h postscreen_send.o: ../../include/msg.h

View File

@ -53,10 +53,13 @@
/* RFC 3207 (STARTTLS command) /* RFC 3207 (STARTTLS command)
/* RFC 3461 (SMTP DSN Extension) /* RFC 3461 (SMTP DSN Extension)
/* RFC 3463 (Enhanced Status Codes) /* RFC 3463 (Enhanced Status Codes)
/* RFC 5321 (SMTP protocol, including multi-line 220 greetings) /* RFC 5321 (SMTP protocol, including multi-line 220 banners)
/* DIAGNOSTICS /* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8). /* Problems and transactions are logged to \fBsyslogd\fR(8).
/* BUGS /* BUGS
/* The \fBpostscreen\fR(8) server does not yet implement
/* the \fBsoft_bounce\fR feature.
/*
/* The \fBpostscreen\fR(8) built-in SMTP protocol engine /* The \fBpostscreen\fR(8) built-in SMTP protocol engine
/* currently does not announce support for AUTH, XCLIENT or /* currently does not announce support for AUTH, XCLIENT or
/* XFORWARD. /* XFORWARD.
@ -542,9 +545,10 @@ static void psc_service(VSTREAM *smtp_client_stream,
if (getpeername(vstream_fileno(smtp_client_stream), (struct sockaddr *) if (getpeername(vstream_fileno(smtp_client_stream), (struct sockaddr *)
& addr_storage, &addr_storage_len) < 0) { & addr_storage, &addr_storage_len) < 0) {
msg_warn("getpeername: %m -- dropping this connection"); msg_warn("getpeername: %m -- dropping this connection");
psc_send_reply(vstream_fileno(smtp_client_stream), /* Best effort - if this non-blocking write(2) fails, so be it. */
"unknown_address", "unknown_port", (void) write(vstream_fileno(smtp_client_stream),
"421 4.3.2 No system resources\r\n"); "421 4.3.2 No system resources\r\n",
sizeof("421 4.3.2 No system resources\r\n") - 1);
PSC_SERVICE_DISCONNECT_AND_RETURN(smtp_client_stream); PSC_SERVICE_DISCONNECT_AND_RETURN(smtp_client_stream);
} }
@ -558,9 +562,10 @@ static void psc_service(VSTREAM *smtp_client_stream,
msg_warn("cannot convert client address/port to string: %s" msg_warn("cannot convert client address/port to string: %s"
" -- dropping this connection", " -- dropping this connection",
MAI_STRERROR(aierr)); MAI_STRERROR(aierr));
psc_send_reply(vstream_fileno(smtp_client_stream), /* Best effort - if this non-blocking write(2) fails, so be it. */
"unknown_address", "unknown_port", (void) write(vstream_fileno(smtp_client_stream),
"421 4.3.2 No system resources\r\n"); "421 4.3.2 No system resources\r\n",
sizeof("421 4.3.2 No system resources\r\n") - 1);
PSC_SERVICE_DISCONNECT_AND_RETURN(smtp_client_stream); PSC_SERVICE_DISCONNECT_AND_RETURN(smtp_client_stream);
} }
if (strncasecmp("::ffff:", smtp_client_addr.buf, 7) == 0) if (strncasecmp("::ffff:", smtp_client_addr.buf, 7) == 0)

View File

@ -44,6 +44,7 @@ typedef struct {
char *smtp_client_port; /* client port */ char *smtp_client_port; /* client port */
int client_concurrency; /* per-client */ int client_concurrency; /* per-client */
const char *final_reply; /* cause for hanging up */ const char *final_reply; /* cause for hanging up */
VSTRING *send_buf; /* pending output */
/* Test context. */ /* Test context. */
struct timeval start_time; /* start of current test */ struct timeval start_time; /* start of current test */
const char *test_name; /* name of current test */ const char *test_name; /* name of current test */
@ -438,12 +439,8 @@ extern void psc_hangup_event(PSC_STATE *);
/* /*
* postscreen_send.c * postscreen_send.c
*/ */
#define PSC_SEND_REPLY(state, text) \ #define PSC_SEND_REPLY psc_send_reply /* legacy macro */
psc_send_reply(vstream_fileno((state)->smtp_client_stream), \ extern int psc_send_reply(PSC_STATE *, const char *);
(state)->smtp_client_addr, \
(state)->smtp_client_port, \
(text))
extern int psc_send_reply(int, const char *, const char *, const char *);
extern void psc_send_socket(PSC_STATE *); extern void psc_send_socket(PSC_STATE *);
/* /*

View File

@ -6,13 +6,12 @@
/* SYNOPSIS /* SYNOPSIS
/* #include <postscreen.h> /* #include <postscreen.h>
/* /*
/* int psc_send_reply(client_fd, client_addr, client_port, text) /* int psc_send_reply(state, text)
/* int client_fd; /* PSC_STATE *state;
/* const char *client_addr;
/* const char *client_port;
/* const char *text; /* const char *text;
/* /*
/* int PSC_SEND_REPLY(state, text) /* int PSC_SEND_REPLY(state, text)
/* PSC_STATE *state;
/* const char *text; /* const char *text;
/* /*
/* void psc_send_socket(state) /* void psc_send_socket(state)
@ -23,9 +22,8 @@
/* a warning (except EPIPE) with the client address and port, /* a warning (except EPIPE) with the client address and port,
/* and returns a non-zero result (all errors including EPIPE). /* and returns a non-zero result (all errors including EPIPE).
/* /*
/* PSC_SEND_REPLY() is a convenience wrapper for psc_send_reply(). /* PSC_SEND_REPLY() is a legacy wrapper for psc_send_reply().
/* It is an unsafe macro that evaluates its arguments multiple /* It will eventually be replaced by its expansion.
/* times.
/* /*
/* psc_send_socket() sends the specified socket to the real /* psc_send_socket() sends the specified socket to the real
/* Postfix SMTP server. The socket is delivered in the background. /* Postfix SMTP server. The socket is delivered in the background.
@ -57,6 +55,10 @@
#include <iostuff.h> #include <iostuff.h>
#include <connect.h> #include <connect.h>
/* Global library. */
#include <mail_params.h>
/* Application-specific. */ /* Application-specific. */
#include <postscreen.h> #include <postscreen.h>
@ -67,28 +69,53 @@
*/ */
#define PSC_SEND_SOCK_CONNECT_TIMEOUT 1 #define PSC_SEND_SOCK_CONNECT_TIMEOUT 1
#define PSC_SEND_SOCK_NOTIFY_TIMEOUT 100 #define PSC_SEND_SOCK_NOTIFY_TIMEOUT 100
#define PSC_SEND_TEXT_TIMEOUT 1
/* psc_send_reply - send reply to remote SMTP client */ /* psc_send_reply - send reply to remote SMTP client */
int psc_send_reply(int smtp_client_fd, const char *smtp_client_addr, int psc_send_reply(PSC_STATE *state, const char *text)
const char *smtp_client_port, const char *text)
{ {
int start;
int ret; int ret;
if (msg_verbose) if (msg_verbose)
msg_info("> [%s]:%s: %.*s", smtp_client_addr, smtp_client_port, msg_info("> [%s]:%s: %.*s", state->smtp_client_addr,
(int) strlen(text) - 2, text); state->smtp_client_port, (int) strlen(text) - 2, text);
/* /*
* XXX Need to make sure that the TCP send buffer is large enough for any * Append the new text to earlier text that could not be sent because the
* response, so that a nasty client can't cause this process to block. * output was throttled.
*/ */
ret = (write_buf(smtp_client_fd, text, strlen(text), start = VSTRING_LEN(state->send_buf);
PSC_SEND_TEXT_TIMEOUT) < 0); vstring_strcat(state->send_buf, text);
if (ret != 0 && errno != EPIPE)
msg_warn("write [%s]:%s: %m", smtp_client_addr, smtp_client_port); /*
return (ret); * XXX For soft_bounce support, it is not sufficient to fix replies here.
* We also need to fix the REJECT messages that are logged by the dummy
* SMTP engine. Those messages are set with the PSC_DROP_SESSION_STATE
* and PSC_ENFORCE_SESSION_STATE macros, and we should not mess up all
* the code that invokes those macros.
*/
#if 0
if (var_soft_bounce) {
if (text[0] == '5')
STR(state->send_buf)[start + 0] = '4';
if (text[4] == '5')
STR(state->send_buf)[start + 4] = '4';
}
#endif
/*
* Do a best effort sending text, but don't block when the output is
* throttled by a hostile peer.
*/
ret = write(vstream_fileno(state->smtp_client_stream),
STR(state->send_buf), LEN(state->send_buf));
if (ret > 0)
vstring_truncate(state->send_buf, ret - LEN(state->send_buf));
if (ret < 0 && errno != EAGAIN && errno != EPIPE)
msg_warn("write [%s]:%s: %m", state->smtp_client_addr,
state->smtp_client_port);
return (ret < 0 && errno != EAGAIN);
} }
/* psc_send_socket_close_event - file descriptor has arrived or timeout */ /* psc_send_socket_close_event - file descriptor has arrived or timeout */

View File

@ -260,7 +260,8 @@ static int psc_helo_cmd(PSC_STATE *state, char *args)
/* psc_smtpd_format_ehlo_reply - format EHLO response */ /* psc_smtpd_format_ehlo_reply - format EHLO response */
static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask) static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask
/*, const char *sasl_mechanism_list */)
{ {
const char *myname = "psc_smtpd_format_ehlo_reply"; const char *myname = "psc_smtpd_format_ehlo_reply";
int saved_len = 0; int saved_len = 0;
@ -1063,6 +1064,9 @@ void psc_smtpd_init(void)
case TLS_LEV_SECURE: case TLS_LEV_SECURE:
case TLS_LEV_VERIFY: case TLS_LEV_VERIFY:
case TLS_LEV_FPRINT: case TLS_LEV_FPRINT:
msg_warn("%s: unsupported TLS level \"%s\", using \"encrypt\"",
VAR_PSC_TLS_LEVEL, var_psc_tls_level);
/* FALLTHROUGH */
case TLS_LEV_ENCRYPT: case TLS_LEV_ENCRYPT:
var_psc_enforce_tls = var_psc_use_tls = 1; var_psc_enforce_tls = var_psc_use_tls = 1;
break; break;

View File

@ -153,6 +153,7 @@ PSC_STATE *psc_new_session_state(VSTREAM *stream,
state->smtp_server_fd = (-1); state->smtp_server_fd = (-1);
state->smtp_client_addr = mystrdup(addr); state->smtp_client_addr = mystrdup(addr);
state->smtp_client_port = mystrdup(port); state->smtp_client_port = mystrdup(port);
state->send_buf = vstring_alloc(100);
state->test_name = "TEST NAME HERE"; state->test_name = "TEST NAME HERE";
state->dnsbl_reply = 0; state->dnsbl_reply = 0;
state->final_reply = "421 4.3.2 Service currently unavailable\r\n"; state->final_reply = "421 4.3.2 Service currently unavailable\r\n";
@ -212,6 +213,8 @@ void psc_free_session_state(PSC_STATE *state)
close(state->smtp_server_fd); close(state->smtp_server_fd);
psc_post_queue_length--; psc_post_queue_length--;
} }
if (state->send_buf != 0)
state->send_buf = vstring_free(state->send_buf);
myfree(state->smtp_client_addr); myfree(state->smtp_client_addr);
myfree(state->smtp_client_port); myfree(state->smtp_client_port);
if (state->dnsbl_reply) if (state->dnsbl_reply)

View File

@ -293,6 +293,7 @@ int var_tlsp_watchdog;
static TLS_APPL_STATE *tlsp_server_ctx; static TLS_APPL_STATE *tlsp_server_ctx;
static int ask_client_cert; static int ask_client_cert;
static int enforce_tls; static int enforce_tls;
static int tlsp_tls_enforce_tls;
/* /*
* SLMs. * SLMs.
@ -625,6 +626,10 @@ static void tlsp_ciphertext_event(int event, char *context)
if (event == EVENT_READ || event == EVENT_WRITE) { if (event == EVENT_READ || event == EVENT_WRITE) {
tlsp_strategy(state); tlsp_strategy(state);
} else { } else {
if (event == EVENT_TIME && state->ssl_last_err == SSL_ERROR_NONE)
msg_warn("deadlock on plaintext stream for %s",
state->remote_endpt);
else
msg_warn("read/write %s for %s", msg_warn("read/write %s for %s",
event == EVENT_TIME ? "timeout" : "error", event == EVENT_TIME ? "timeout" : "error",
state->remote_endpt); state->remote_endpt);
@ -645,8 +650,6 @@ static void tlsp_start_tls(TLSP_STATE *state)
* going to sanitize this because doing so surely will break things in * going to sanitize this because doing so surely will break things in
* unexpected ways. * unexpected ways.
*/ */
state->tls_use_tls = var_tlsp_use_tls | var_tlsp_enforce_tls;
state->tls_enforce_tls = var_tlsp_enforce_tls;
/* /*
* Perform the before-handshake portion of the per-session initalization. * Perform the before-handshake portion of the per-session initalization.
@ -680,7 +683,7 @@ static void tlsp_start_tls(TLSP_STATE *state)
log_level = var_tlsp_tls_loglevel, log_level = var_tlsp_tls_loglevel,
timeout = 0, /* unused */ timeout = 0, /* unused */
requirecert = (var_tlsp_tls_req_ccert requirecert = (var_tlsp_tls_req_ccert
&& state->tls_enforce_tls), && tlsp_tls_enforce_tls),
serverid = state->service, serverid = state->service,
namaddr = state->remote_endpt, namaddr = state->remote_endpt,
cipher_grade = cipher_grade, cipher_grade = cipher_grade,
@ -894,7 +897,39 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
* The code in this routine is pasted literally from smtpd(8). I am not * The code in this routine is pasted literally from smtpd(8). I am not
* going to sanitize this because doing so surely will break things in * going to sanitize this because doing so surely will break things in
* unexpected ways. * unexpected ways.
* */
if (*var_tlsp_tls_level) {
switch (tls_level_lookup(var_tlsp_tls_level)) {
default:
msg_fatal("Invalid TLS level \"%s\"", var_tlsp_tls_level);
/* NOTREACHED */
break;
case TLS_LEV_SECURE:
case TLS_LEV_VERIFY:
case TLS_LEV_FPRINT:
msg_warn("%s: unsupported TLS level \"%s\", using \"encrypt\"",
VAR_TLSP_TLS_LEVEL, var_tlsp_tls_level);
/* FALLTHROUGH */
case TLS_LEV_ENCRYPT:
var_tlsp_enforce_tls = var_tlsp_use_tls = 1;
break;
case TLS_LEV_MAY:
var_tlsp_enforce_tls = 0;
var_tlsp_use_tls = 1;
break;
case TLS_LEV_NONE:
var_tlsp_enforce_tls = var_tlsp_use_tls = 0;
break;
}
}
tlsp_tls_enforce_tls = var_tlsp_enforce_tls;
if (!(var_tlsp_use_tls || var_tlsp_enforce_tls)) {
msg_warn("TLS service is requested, but disabled with %s or %s",
VAR_TLSP_TLS_LEVEL, VAR_TLSP_USE_TLS);
return;
}
/*
* Load TLS keys before dropping privileges. * Load TLS keys before dropping privileges.
* *
* Can't use anonymous ciphers if we want client certificates. Must use * Can't use anonymous ciphers if we want client certificates. Must use

View File

@ -33,8 +33,6 @@ typedef struct {
char *remote_endpt; /* printable remote endpoint */ char *remote_endpt; /* printable remote endpoint */
TLS_SESS_STATE *tls_context; /* llibtls state */ TLS_SESS_STATE *tls_context; /* llibtls state */
int ssl_last_err; /* TLS I/O state */ int ssl_last_err; /* TLS I/O state */
int tls_use_tls; /* legacy libtls API */
int tls_enforce_tls; /* legacy libtls API */
} TLSP_STATE; } TLSP_STATE;
#define TLSP_FLAG_DO_HANDSHAKE (1<<0) #define TLSP_FLAG_DO_HANDSHAKE (1<<0)

View File

@ -173,7 +173,8 @@
/* arguments more than once. The result is NOT null-terminated. /* arguments more than once. The result is NOT null-terminated.
/* /*
/* vstring_truncate() truncates the named string to the specified /* vstring_truncate() truncates the named string to the specified
/* length. The operation has no effect when the string is shorter. /* length. If length is negative, the trailing portion is kept.
/* The operation has no effect when the string is shorter.
/* The string is not null-terminated. /* The string is not null-terminated.
/* /*
/* VSTRING_RESET() is a macro that resets the write position of its /* VSTRING_RESET() is a macro that resets the write position of its
@ -393,8 +394,13 @@ void vstring_ctl(VSTRING *vp,...)
VSTRING *vstring_truncate(VSTRING *vp, ssize_t len) VSTRING *vstring_truncate(VSTRING *vp, ssize_t len)
{ {
if (len < 0) ssize_t move;
msg_panic("vstring_truncate: bad length %ld", (long) len);
if (len < 0) {
len = (-len);
if ((move = VSTRING_LEN(vp) - len) > 0)
memmove(vstring_str(vp), vstring_str(vp) + move, len);
}
if (len < VSTRING_LEN(vp)) if (len < VSTRING_LEN(vp))
VSTRING_AT_OFFSET(vp, len); VSTRING_AT_OFFSET(vp, len);
return (vp); return (vp);