diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 1d5e8ce8e..61b229edd 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -219,6 +219,7 @@ -TTLS_PRNG_SRC -TTLS_SCACHE -TTLS_SCACHE_ENTRY +-TTLS_VINFO -TTLScontext_t -TTOK822 -TTRANSPORT_INFO diff --git a/postfix/HISTORY b/postfix/HISTORY index 09420d8b4..dd2a4f938 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -12148,6 +12148,21 @@ Apologies for any names omitted. null terminate the address before logging a warning. Reported by Kris Kennaway. File: global/tok822_parse.c. +20060516 + + Portability: __float80 alignment, by Albert Chin. File: + util/sys_defs.h. + + Workaround: don't bounce+delete a local submission after + it triggers a "reject 4.x.x" action in header/body_checks. + This means an SMTP client now sees "queue file write error" + instead of the text from the "reject 4.x.x text" action. + File: cleanup/cleanup_message.c. + + Workaround: OpenSSL 0.9.8[ab] with zlib support interoperability + problem. Victor Duchovni. Files: tls/tls_client.c, tls/tls_misc.c, + tls/tls_server.c. + Wish list: Don't send xforward attributes to every site that announces diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index 52ab9c09c..62a0ec7eb 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -316,6 +316,24 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context, #define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0) #define CLEANUP_ACT_DROP 0 + /* + * CLEANUP_STAT_CONT causes cleanup(8) to send bounces if + * CLEANUP_FLAG_BOUNCE is set, which causes pickup(8) to throw away the + * queue file after cleanup(8) reports success. + * + * This is wrong in the case of temporary rejects. Another problem is that + * cleanup(8) clients look at the state->reason value only when + * CLEANUP_STAT_CONT is set. + * + * We could kludge around this in the cleanup server by ignoring + * CLEANUP_FLAG_BOUNCE for temporary rejects, but that is fragile. It + * exposes clients to status codes that they until now never had to + * handle. + * + * As a safe workaround for temporary rejects we return CLEANUP_STAT_WRITE. + * But we really want to report the true cause (server configuration + * error or otherwise). + */ if (STREQUAL(value, "REJECT", command_len)) { CLEANUP_STAT_DETAIL *detail; @@ -332,7 +350,10 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context, state->reason = dsn_prepend(detail->dsn, detail->text); } } - state->errs |= CLEANUP_STAT_CONT; + if (*state->reason == '4') + state->errs = CLEANUP_STAT_WRITE; + else + state->errs |= CLEANUP_STAT_CONT; state->flags &= ~CLEANUP_FLAG_FILTER; cleanup_act_log(state, "reject", context, buf, state->reason); return (buf); diff --git a/postfix/src/qmqpd/qmqpd.c b/postfix/src/qmqpd/qmqpd.c index ee45281bc..5eacb5716 100644 --- a/postfix/src/qmqpd/qmqpd.c +++ b/postfix/src/qmqpd/qmqpd.c @@ -531,7 +531,8 @@ static void qmqpd_send_status(QMQPD_STATE *state) qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD, "Error: too many hops"); } else if ((state->err & CLEANUP_STAT_CONT) != 0) { - qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD, + qmqpd_reply(state, DO_LOG, STR(state->why_rejected)[0] == '4' ? + QMQPD_STAT_RETRY : QMQPD_STAT_HARD, "Error: %s", STR(state->why_rejected)); } else if ((state->err & CLEANUP_STAT_WRITE) != 0) { qmqpd_reply(state, DO_LOG, QMQPD_STAT_RETRY, diff --git a/postfix/src/tls/tls.h b/postfix/src/tls/tls.h index 134037071..9db5ca6fd 100644 --- a/postfix/src/tls/tls.h +++ b/postfix/src/tls/tls.h @@ -86,7 +86,7 @@ extern TLScontext_t *tls_server_start(SSL_CTX *, VSTREAM *, int, * tls_session.c */ extern void tls_session_stop(SSL_CTX *, VSTREAM *, int, int, - TLScontext_t *); + TLScontext_t *); #ifdef TLS_INTERNAL @@ -164,6 +164,8 @@ extern int TLScontext_index; extern TLScontext_t *tls_alloc_context(int, const char *); extern void tls_free_context(TLScontext_t *); +extern void tls_check_version(void); +extern long tls_bug_bits(void); extern void tls_print_errors(void); extern void tls_info_callback(const SSL *, int, int); extern long tls_bio_dump_cb(BIO *, int, const char *, int, long, long); diff --git a/postfix/src/tls/tls_client.c b/postfix/src/tls/tls_client.c index c4bcce919..79f251fb0 100644 --- a/postfix/src/tls/tls_client.c +++ b/postfix/src/tls/tls_client.c @@ -271,6 +271,11 @@ SSL_CTX *tls_client_init(int unused_verifydepth) if (var_smtp_tls_loglevel >= 2) msg_info("initializing the client-side TLS engine"); + /* + * Detect mismatch between compile-time headers and run-time library. + */ + tls_check_version(); + /* * Initialize the OpenSSL library by the book! To start with, we must * initialize the algorithms. We want cleartext error messages instead of @@ -310,7 +315,7 @@ SSL_CTX *tls_client_init(int unused_verifydepth) * defined for TLS, but we don't know what is out there. So leave things * completely open, as of today. */ - off |= SSL_OP_ALL; /* Work around all known bugs */ + off |= tls_bug_bits(); SSL_CTX_set_options(client_ctx, off); /* @@ -457,7 +462,7 @@ static int match_hostname(const char *pattern, const char *hostname) /* verify_extract_peer - verify peer name and extract peer information */ -static void verify_extract_peer(const char *peername, X509 * peercert, +static void verify_extract_peer(const char *peername, X509 *peercert, TLScontext_t *TLScontext) { int i; diff --git a/postfix/src/tls/tls_misc.c b/postfix/src/tls/tls_misc.c index b8d598039..3b45df09f 100644 --- a/postfix/src/tls/tls_misc.c +++ b/postfix/src/tls/tls_misc.c @@ -98,6 +98,17 @@ */ int TLScontext_index = -1; + /* + * Parsed OpenSSL version number. + */ +typedef struct { + int major; + int minor; + int micro; + int patch; + int status; +} TLS_VINFO; + /* tls_alloc_context - allocate TLScontext */ TLScontext_t *tls_alloc_context(int log_level, const char *peername) @@ -160,6 +171,116 @@ void tls_free_context(TLScontext_t *TLScontext) myfree((char *) TLScontext); } +static void tls_version_split(long version, TLS_VINFO *info) +{ + + /* + * OPENSSL_VERSION_NUMBER(3): + * + * OPENSSL_VERSION_NUMBER is a numeric release version identifier: + * + * MMNNFFPPS: major minor fix patch status + * + * The status nibble has one of the values 0 for development, 1 to e for + * betas 1 to 14, and f for release. Parsed OpenSSL version number. for + * example + * + * 0x000906000 == 0.9.6 dev 0x000906023 == 0.9.6b beta 3 0x00090605f == + * 0.9.6e release + * + * Versions prior to 0.9.3 have identifiers < 0x0930. Versions between + * 0.9.3 and 0.9.5 had a version identifier with this interpretation: + * + * MMNNFFRBB major minor fix final beta/patch + * + * for example + * + * 0x000904100 == 0.9.4 release 0x000905000 == 0.9.5 dev + * + * Version 0.9.5a had an interim interpretation that is like the current + * one, except the patch level got the highest bit set, to keep continu- + * ity. The number was therefore 0x0090581f. + */ + + if (version < 0x0930) { + info->status = 0; + info->patch = version & 0x0f; + version >>= 4; + info->micro = version & 0x0f; + version >>= 4; + info->minor = version & 0x0f; + version >>= 4; + info->major = version & 0x0f; + } else if (version < 0x00905800L) { + info->patch = version & 0xff; + version >>= 8; + info->status = version & 0xf; + version >>= 4; + info->micro = version & 0xff; + version >>= 8; + info->minor = version & 0xff; + version >>= 8; + info->major = version & 0xff; + } else { + info->status = version & 0xf; + version >>= 4; + info->patch = version & 0xff; + version >>= 8; + info->micro = version & 0xff; + version >>= 8; + info->minor = version & 0xff; + version >>= 8; + info->major = version & 0xff; + if (version < 0x00906000L) + info->patch &= ~0x80; + } +} + +/* tls_check_version - Detect mismatch between headers and library. */ + +void tls_check_version(void) +{ + TLS_VINFO hdr_info; + TLS_VINFO lib_info; + + tls_version_split(OPENSSL_VERSION_NUMBER, &hdr_info); + tls_version_split(SSLeay(), &lib_info); + + if (lib_info.major != hdr_info.major + || lib_info.minor != hdr_info.minor + || lib_info.micro != hdr_info.micro) + msg_warn("run-time library vs. compile-time header version mismatch: " + "OpenSSL %d.%d.%d may not be compatible with OpenSSL %d.%d.%d", + lib_info.major, lib_info.minor, lib_info.micro, + hdr_info.major, hdr_info.minor, hdr_info.micro); +} + +/* tls_bug_bits - SSL bug compatibility bits for this OpenSSL version */ + +long tls_bug_bits(void) +{ + long bits = SSL_OP_ALL; /* Work around all known bugs */ + +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + long lib_version = SSLeay(); + + /* + * In OpenSSL 0.9.8[ab], enabling zlib compression breaks the padding bug + * work-around, leading to false positives and failed connections. We may + * not interoperate with systems with the bug, but this better than + * breaking on all 0.9.8[ab] systems that have zlib support enabled. + */ + if (lib_version >= 0x00908000L && lib_version <= 0x0090802fL) { + STACK_OF(SSL_COMP) * comp_methods; + + comp_methods = SSL_COMP_get_compression_methods(); + if (comp_methods != 0 && sk_SSL_COMP_num(comp_methods) > 0) + bits &= ~SSL_OP_TLS_BLOCK_PADDING_BUG; + } +#endif + return (bits); +} + /* tls_print_errors - print and clear the error stack */ void tls_print_errors(void) diff --git a/postfix/src/tls/tls_server.c b/postfix/src/tls/tls_server.c index 91122a0a3..e2642bf83 100644 --- a/postfix/src/tls/tls_server.c +++ b/postfix/src/tls/tls_server.c @@ -239,6 +239,11 @@ SSL_CTX *tls_server_init(int unused_verifydepth, int askcert) if (var_smtpd_tls_loglevel >= 2) msg_info("initializing the server-side TLS engine"); + /* + * Detect mismatch between compile-time headers and run-time library. + */ + tls_check_version(); + /* * Initialize the OpenSSL library by the book! To start with, we must * initialize the algorithms. We want cleartext error messages instead of @@ -280,7 +285,7 @@ SSL_CTX *tls_server_init(int unused_verifydepth, int askcert) * defined for TLS, but we also want to accept Netscape communicator * requests, and it only supports SSLv3. */ - off |= SSL_OP_ALL; /* Work around all known bugs */ + off |= tls_bug_bits(); SSL_CTX_set_options(server_ctx, off); /* diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index a66c803e8..184f90e1d 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -1230,7 +1230,9 @@ typedef int pid_t; * doubles. */ #ifndef ALIGN_TYPE -# ifdef __ia64__ +# if defined(__hpux) && defined(__ia64) +# define ALIGN_TYPE __float80 +# elif defined(__ia64__) # define ALIGN_TYPE long double # else # define ALIGN_TYPE double