#else
# if defined SSL_CTRL_SET_ECDH_AUTO
DEBUG(D_tls) debug_printf(
- "ECDH OpenSSL 1.0.2+ temp key parameter settings: autoselection\n");
+ "ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n");
SSL_CTX_set_ecdh_auto(sctx, 1);
return TRUE;
# else
DEBUG(D_tls) debug_printf(
- "ECDH OpenSSL 1.1.0+ temp key parameter settings: default selection\n");
+ "ECDH OpenSSL 1.1.0+: temp key parameter settings: default selection\n");
return TRUE;
# endif
#endif
/* Create and install a selfsigned certificate, for use in server mode */
+/*XXX we could arrange to call this during prelo for a null tls_certificate option.
+The normal cache inval + relo will suffice.
+Just need a timer for inval. */
static int
tls_install_selfsign(SSL_CTX * sctx, uschar ** errstr)
X509_NAME * name;
uschar * where;
+DEBUG(D_tls) debug_printf("TLS: generating selfsigned server cert\n");
where = US"allocating pkey";
if (!(pkey = EVP_PKEY_new()))
goto err;
X509_set_version(x509, 2); /* N+1 - version 3 */
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
X509_gmtime_adj(X509_get_notBefore(x509), 0);
-X509_gmtime_adj(X509_get_notAfter(x509), (long)60 * 60); /* 1 hour */
+X509_gmtime_adj(X509_get_notAfter(x509), (long)2 * 60 * 60); /* 2 hour */
X509_set_pubkey(x509, pkey);
name = X509_get_subject_name(x509);
}
-static void
+static unsigned
tls_server_creds_init(void)
{
SSL_CTX * ctx;
uschar * dummy_errstr;
+unsigned lifetime = 0;
tls_openssl_init();
state_server.lib_state = null_tls_preload;
if (lib_ctx_new(&ctx, NULL, &dummy_errstr) != OK)
- return;
+ return 0;
state_server.lib_state.lib_ctx = ctx;
/* Preload DH params and EC curve */
state_server.lib_state.conn_certs = TRUE;
}
}
+else if ( !tls_certificate && !tls_privatekey
+# ifndef DISABLE_OCSP
+ && !tls_ocsp_file
+#endif
+ )
+ { /* Generate & preload a selfsigned cert. No files to watch. */
+ if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK)
+ {
+ state_server.lib_state.conn_certs = TRUE;
+ lifetime = f.running_in_test_harness ? 2 : 60 * 60; /* 1 hour */
+ }
+ }
else
DEBUG(D_tls) debug_printf("TLS: not preloading server certs\n");
}
else
DEBUG(D_tls) debug_printf("TLS: not preloading cipher list for server\n");
+return lifetime;
}
void
-tls_get_cache()
+tls_get_cache(void)
{
#ifndef DISABLE_DKIM
int n = ssl_xfer_buffer_hwm - ssl_xfer_buffer_lwm;
tls_could_read(void)
{
return ssl_xfer_buffer_lwm < ssl_xfer_buffer_hwm
- || SSL_pending(state_server.lib_state.lib_ssl) > 0;
+ || SSL_pending(state_server.lib_state.lib_ssl) > 0;
}
{
if (!len) buff = US &error; /* dummy just so that string_catn is ok */
-#ifndef DISABLE_PIPE_CONNECT
int save_pool = store_pool;
store_pool = POOL_PERM;
-#endif
corked = string_catn(corked, buff, len);
-#ifndef DISABLE_PIPE_CONNECT
store_pool = save_pool;
-#endif
if (more)
{
+/*
+Arguments:
+ ct_ctx client TLS context pointer, or NULL for the one global server context
+*/
+
+void
+tls_shutdown_wr(void * ct_ctx)
+{
+exim_openssl_client_tls_ctx * o_ctx = ct_ctx;
+SSL ** sslp = o_ctx ? &o_ctx->ssl : (SSL **) &state_server.lib_state.lib_ssl;
+int * fdp = o_ctx ? &tls_out.active.sock : &tls_in.active.sock;
+int rc;
+
+if (*fdp < 0) return; /* TLS was not active */
+
+tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */
+
+HDEBUG(D_transport|D_tls|D_acl|D_v) debug_printf_indent(" SMTP(TLS shutdown)>>\n");
+rc = SSL_shutdown(*sslp);
+if (rc < 0) DEBUG(D_tls)
+ {
+ ERR_error_string_n(ERR_get_error(), ssl_errstring, sizeof(ssl_errstring));
+ debug_printf("SSL_shutdown: %s\n", ssl_errstring);
+ }
+}
+
/*************************************************
* Close down a TLS session *
*************************************************/
Arguments:
ct_ctx client TLS context pointer, or NULL for the one global server context
- shutdown 1 if TLS close-alert is to be sent,
+ do_shutdown 0 no data-flush or TLS close-alert
+ 1 if TLS close-alert is to be sent,
2 if also response to be waited for
Returns: nothing
*/
void
-tls_close(void * ct_ctx, int shutdown)
+tls_close(void * ct_ctx, int do_shutdown)
{
exim_openssl_client_tls_ctx * o_ctx = ct_ctx;
-SSL **sslp = o_ctx ? &o_ctx->ssl : (SSL **) &state_server.lib_state.lib_ssl;
-int *fdp = o_ctx ? &tls_out.active.sock : &tls_in.active.sock;
+SSL ** sslp = o_ctx ? &o_ctx->ssl : (SSL **) &state_server.lib_state.lib_ssl;
+int * fdp = o_ctx ? &tls_out.active.sock : &tls_in.active.sock;
if (*fdp < 0) return; /* TLS was not active */
-if (shutdown)
+if (do_shutdown)
{
int rc;
DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS%s\n",
- shutdown > 1 ? " (with response-wait)" : "");
+ do_shutdown > 1 ? " (with response-wait)" : "");
+
+ tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */
if ( (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */
- && shutdown > 1)
+ && do_shutdown > 1)
{
ALARM(2);
rc = SSL_shutdown(*sslp); /* wait for response */