-TTLS_PRNG_SRC
-TTLS_SCACHE
-TTLS_SCACHE_ENTRY
+-TTLS_VINFO
-TTLScontext_t
-TTOK822
-TTRANSPORT_INFO
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
#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;
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);
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,
* tls_session.c
*/
extern void tls_session_stop(SSL_CTX *, VSTREAM *, int, int,
- TLScontext_t *);
+ TLScontext_t *);
#ifdef TLS_INTERNAL
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);
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
* 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);
/*
/* 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;
*/
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)
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)
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
* 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);
/*
* 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