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:
parent
fdd520cf24
commit
19c1ec2275
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 *);
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user