# define EXIM_HAVE_OPENSSL_CHECKHOST
# define EXIM_HAVE_OPENSSL_DH_BITS
# define EXIM_HAVE_OPENSSL_TLS_METHOD
+# define EXIM_HAVE_OPENSSL_KEYLOG
# else
# define EXIM_NEED_OPENSSL_INIT
# endif
# endif
#endif
+#ifndef LIBRESSL_VERSION_NUMBER
+# if OPENSSL_VERSION_NUMBER >= 0x010101000L
+# define OPENSSL_HAVE_KEYLOG_CB
+# define OPENSSL_HAVE_NUM_TICKETS
+# endif
+#endif
+
#if !defined(EXIM_HAVE_OPENSSL_TLSEXT) && !defined(DISABLE_OCSP)
# warning "OpenSSL library version too old; define DISABLE_OCSP in Makefile"
# define DISABLE_OCSP
}
}
+#ifdef OPENSSL_HAVE_KEYLOG_CB
+static void
+keylog_callback(const SSL *ssl, const char *line)
+{
+DEBUG(D_tls) debug_printf("%.200s\n", line);
+}
+#endif
+
/*************************************************
level. */
DEBUG(D_tls) SSL_CTX_set_info_callback(ctx, (void (*)())info_callback);
+#ifdef OPENSSL_HAVE_KEYLOG_CB
+DEBUG(D_tls) SSL_CTX_set_keylog_callback(ctx, (void (*)())keylog_callback);
+#endif
/* Automatically re-try reads/writes after renegotiation. */
(void) SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
else
DEBUG(D_tls) debug_printf("no SSL CTX options to set\n");
+#ifdef OPENSSL_HAVE_NUM_TICKETS
+SSL_CTX_set_num_tickets(ctx, 0); /* send no TLS1.3 stateful-tickets */
+#endif
+
/* We'd like to disable session cache unconditionally, but foolish Outlook
Express clients then give up the first TLS connection and make a second one
(which works). Only when there is an IMAP service on the same machine.
peer_cert(server_ssl, &tls_in, peerdn, sizeof(peerdn));
-construct_cipher_name(server_ssl, cipherbuf, sizeof(cipherbuf), &tls_in.bits);
-tls_in.cipher = cipherbuf;
-
DEBUG(D_tls)
{
uschar buf[2048];
if (SSL_get_shared_ciphers(server_ssl, CS buf, sizeof(buf)) != NULL)
debug_printf("Shared ciphers: %s\n", buf);
+
+#ifdef EXIM_HAVE_OPENSSL_KEYLOG
+ {
+ BIO * bp = BIO_new(BIO_s_mem());
+ uschar * s;
+ int len;
+ SSL_SESSION_print_keylog(bp, SSL_get_session(server_ssl));
+ len = (int) BIO_get_mem_data(bp, CSS &s);
+ debug_printf("%.*s", len, s);
+ BIO_free(bp);
}
+#endif
+ }
+
+construct_cipher_name(server_ssl, cipherbuf, sizeof(cipherbuf), &tls_in.bits);
+tls_in.cipher = cipherbuf;
/* Record the certificate we presented */
{
return NULL;
}
-DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
+DEBUG(D_tls)
+ {
+ debug_printf("SSL_connect succeeded\n");
+#ifdef EXIM_HAVE_OPENSSL_KEYLOG
+ {
+ BIO * bp = BIO_new(BIO_s_mem());
+ uschar * s;
+ int len;
+ SSL_SESSION_print_keylog(bp, SSL_get_session(server_ssl));
+ len = (int) BIO_get_mem_data(bp, CSS &s);
+ debug_printf("%.*s", len, s);
+ BIO_free(bp);
+ }
+#endif
+ }
peer_cert(exim_client_ctx->ssl, tlsp, peerdn, sizeof(peerdn));
int
tls_write(void * ct_ctx, const uschar *buff, size_t len, BOOL more)
{
+size_t olen = len;
int outbytes, error;
SSL * ssl = ct_ctx ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl;
static gstring * corked = NULL;
"more" is notified. This hack is only ok if small amounts are involved AND only
one stream does it, in one context (i.e. no store reset). Currently it is used
for the responses to the received SMTP MAIL , RCPT, DATA sequence, only. */
-/*XXX + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's
-a store reset there. */
+/* + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's
+a store reset there, so use POOL_PERM. */
+/* + if CHUNKING, cmds EHLO,MAIL,RCPT(s),BDAT */
-if (!ct_ctx && (more || corked))
+if ((more || corked))
{
#ifdef EXPERIMENTAL_PIPE_CONNECT
int save_pool = store_pool;
return -1;
}
}
-return len;
+return olen;
}