2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +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
can translate traffic for multiple remote SMTP clients.
With early testing feedback from Victor Duchovni and Christian
Roessner. Files: util/nbbio.c, tlsproxy/starttlsd.c,
tlsproxy/starttlsd_state.c.
Roessner. Files: util/nbbio.[hc], tlsproxy/*.[hc],
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.
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.

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/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/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>
Problems and transactions are logged to <b>syslogd</b>(8).
<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
does not announce support for AUTH, XCLIENT or XFORWARD.
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 3461 (SMTP DSN Extension)
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
.ad
.fi
@ -71,6 +71,9 @@ Problems and transactions are logged to \fBsyslogd\fR(8).
.SH BUGS
.ad
.fi
The \fBpostscreen\fR(8) server does not yet implement
the \fBsoft_bounce\fR feature.
The \fBpostscreen\fR(8) built-in SMTP protocol engine
currently does not announce support for AUTH, XCLIENT or
XFORWARD.

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 "20110102"
#define MAIL_RELEASE_DATE "20110103"
#define MAIL_VERSION_NUMBER "2.8"
#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/htable.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_ops.h
postscreen_send.o: ../../include/msg.h

View File

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

View File

@ -44,6 +44,7 @@ typedef struct {
char *smtp_client_port; /* client port */
int client_concurrency; /* per-client */
const char *final_reply; /* cause for hanging up */
VSTRING *send_buf; /* pending output */
/* Test context. */
struct timeval start_time; /* start 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
*/
#define PSC_SEND_REPLY(state, text) \
psc_send_reply(vstream_fileno((state)->smtp_client_stream), \
(state)->smtp_client_addr, \
(state)->smtp_client_port, \
(text))
extern int psc_send_reply(int, const char *, const char *, const char *);
#define PSC_SEND_REPLY psc_send_reply /* legacy macro */
extern int psc_send_reply(PSC_STATE *, const char *);
extern void psc_send_socket(PSC_STATE *);
/*

View File

@ -6,13 +6,12 @@
/* SYNOPSIS
/* #include <postscreen.h>
/*
/* int psc_send_reply(client_fd, client_addr, client_port, text)
/* int client_fd;
/* const char *client_addr;
/* const char *client_port;
/* int psc_send_reply(state, text)
/* PSC_STATE *state;
/* const char *text;
/*
/* int PSC_SEND_REPLY(state, text)
/* PSC_STATE *state;
/* const char *text;
/*
/* void psc_send_socket(state)
@ -23,9 +22,8 @@
/* a warning (except EPIPE) with the client address and port,
/* and returns a non-zero result (all errors including EPIPE).
/*
/* PSC_SEND_REPLY() is a convenience wrapper for psc_send_reply().
/* It is an unsafe macro that evaluates its arguments multiple
/* times.
/* PSC_SEND_REPLY() is a legacy wrapper for psc_send_reply().
/* It will eventually be replaced by its expansion.
/*
/* psc_send_socket() sends the specified socket to the real
/* Postfix SMTP server. The socket is delivered in the background.
@ -57,6 +55,10 @@
#include <iostuff.h>
#include <connect.h>
/* Global library. */
#include <mail_params.h>
/* Application-specific. */
#include <postscreen.h>
@ -67,28 +69,53 @@
*/
#define PSC_SEND_SOCK_CONNECT_TIMEOUT 1
#define PSC_SEND_SOCK_NOTIFY_TIMEOUT 100
#define PSC_SEND_TEXT_TIMEOUT 1
/* psc_send_reply - send reply to remote SMTP client */
int psc_send_reply(int smtp_client_fd, const char *smtp_client_addr,
const char *smtp_client_port, const char *text)
int psc_send_reply(PSC_STATE *state, const char *text)
{
int start;
int ret;
if (msg_verbose)
msg_info("> [%s]:%s: %.*s", smtp_client_addr, smtp_client_port,
(int) strlen(text) - 2, text);
msg_info("> [%s]:%s: %.*s", state->smtp_client_addr,
state->smtp_client_port, (int) strlen(text) - 2, text);
/*
* XXX Need to make sure that the TCP send buffer is large enough for any
* response, so that a nasty client can't cause this process to block.
* Append the new text to earlier text that could not be sent because the
* output was throttled.
*/
ret = (write_buf(smtp_client_fd, text, strlen(text),
PSC_SEND_TEXT_TIMEOUT) < 0);
if (ret != 0 && errno != EPIPE)
msg_warn("write [%s]:%s: %m", smtp_client_addr, smtp_client_port);
return (ret);
start = VSTRING_LEN(state->send_buf);
vstring_strcat(state->send_buf, text);
/*
* 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 */

View File

@ -260,7 +260,8 @@ static int psc_helo_cmd(PSC_STATE *state, char *args)
/* 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";
int saved_len = 0;
@ -1063,6 +1064,9 @@ void psc_smtpd_init(void)
case TLS_LEV_SECURE:
case TLS_LEV_VERIFY:
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:
var_psc_enforce_tls = var_psc_use_tls = 1;
break;

View File

@ -153,6 +153,7 @@ PSC_STATE *psc_new_session_state(VSTREAM *stream,
state->smtp_server_fd = (-1);
state->smtp_client_addr = mystrdup(addr);
state->smtp_client_port = mystrdup(port);
state->send_buf = vstring_alloc(100);
state->test_name = "TEST NAME HERE";
state->dnsbl_reply = 0;
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);
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_port);
if (state->dnsbl_reply)

View File

@ -293,6 +293,7 @@ int var_tlsp_watchdog;
static TLS_APPL_STATE *tlsp_server_ctx;
static int ask_client_cert;
static int enforce_tls;
static int tlsp_tls_enforce_tls;
/*
* SLMs.
@ -625,6 +626,10 @@ static void tlsp_ciphertext_event(int event, char *context)
if (event == EVENT_READ || event == EVENT_WRITE) {
tlsp_strategy(state);
} 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",
event == EVENT_TIME ? "timeout" : "error",
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
* 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.
@ -680,7 +683,7 @@ static void tlsp_start_tls(TLSP_STATE *state)
log_level = var_tlsp_tls_loglevel,
timeout = 0, /* unused */
requirecert = (var_tlsp_tls_req_ccert
&& state->tls_enforce_tls),
&& tlsp_tls_enforce_tls),
serverid = state->service,
namaddr = state->remote_endpt,
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
* going to sanitize this because doing so surely will break things in
* 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.
*
* 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 */
TLS_SESS_STATE *tls_context; /* llibtls 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;
#define TLSP_FLAG_DO_HANDSHAKE (1<<0)

View File

@ -173,7 +173,8 @@
/* arguments more than once. The result is NOT null-terminated.
/*
/* 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.
/*
/* 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)
{
if (len < 0)
msg_panic("vstring_truncate: bad length %ld", (long) len);
ssize_t move;
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))
VSTRING_AT_OFFSET(vp, len);
return (vp);