old_cert = tlsp->peercert;
tlsp->peercert = X509_dup(cert);
/* NB we do not bother setting peerdn */
- if ((yield = event_raise(ev, US"tls:cert", string_sprintf("%d", depth))))
+ if ((yield = event_raise(ev, US"tls:cert", string_sprintf("%d", depth), &errno)))
{
log_write(0, LOG_MAIN, "[%s] %s verify denied by event-action: "
"depth=%d cert=%s: %s",
ocsp_resplist ** op = &state->u_ocsp.server.olist, * oentry;
while (oentry = *op)
op = &oentry->next;
- *op = oentry = store_get(sizeof(ocsp_resplist), FALSE);
+ *op = oentry = store_get(sizeof(ocsp_resplist), GET_UNTAINTED);
oentry->next = NULL;
oentry->resp = resp;
}
/* Make the extension value available for expansion */
store_pool = POOL_PERM;
-tls_in.sni = string_copy_taint(US servername, TRUE);
+tls_in.sni = string_copy_taint(US servername, GET_TAINTED);
store_pool = old_pool;
if (!reexpand_tls_files_for_sni)
STACK_OF(OCSP_SINGLERESP) * sresp = bs->tbsResponseData->responses;
#endif
- DEBUG(D_tls) bp = BIO_new_fp(debug_file, BIO_NOCLOSE);
+ DEBUG(D_tls) bp = BIO_new(BIO_s_mem());
/*OCSP_RESPONSE_print(bp, rsp, 0); extreme debug: stapling content */
if (LOGGING(tls_cipher)) log_write(0, LOG_MAIN,
"Received TLS cert status response, itself unverifiable: %s",
ERR_reason_error_string(ERR_peek_error()));
- BIO_printf(bp, "OCSP response verify failure\n");
- ERR_print_errors(bp);
- OCSP_RESPONSE_print(bp, rsp, 0);
+ DEBUG(D_tls)
+ {
+ BIO_printf(bp, "OCSP response verify failure\n");
+ ERR_print_errors(bp);
+ OCSP_RESPONSE_print(bp, rsp, 0);
+ }
goto failed;
}
else
status = OCSP_single_get0_status(single, &reason, &rev,
&thisupd, &nextupd);
- DEBUG(D_tls) time_print(bp, "This OCSP Update", thisupd);
- DEBUG(D_tls) if(nextupd) time_print(bp, "Next OCSP Update", nextupd);
+ DEBUG(D_tls)
+ {
+ time_print(bp, "This OCSP Update", thisupd);
+ if (nextupd) time_print(bp, "Next OCSP Update", nextupd);
+ }
if (!OCSP_check_validity(thisupd, nextupd,
EXIM_OCSP_SKEW_SECONDS, EXIM_OCSP_MAX_AGE))
{
tls_out.ocsp = OCSP_FAILED;
i = cbinfo->u_ocsp.client.verify_required ? 0 : 1;
good:
+ {
+ uschar * s = NULL;
+ int len = (int) BIO_get_mem_data(bp, CSS &s);
+ if (len > 0) debug_printf("%.*s", len, s);
+ }
BIO_free(bp);
}
+static void
+tls_dump_keylog(SSL * ssl)
+{
+#ifdef EXIM_HAVE_OPENSSL_KEYLOG
+ BIO * bp = BIO_new(BIO_s_mem());
+ uschar * s = NULL;
+ int len;
+ SSL_SESSION_print_keylog(bp, SSL_get_session(ssl));
+ len = (int) BIO_get_mem_data(bp, CSS &s);
+ if (len > 0) debug_printf("%.*s", len, s);
+ BIO_free(bp);
+#endif
+}
+
+
/*************************************************
* Start a TLS session in a server *
*************************************************/
case SSL_ERROR_ZERO_RETURN:
DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
(void) tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : NULL, errstr);
+ (void) event_raise(event_action, US"tls:fail:connect", *errstr, NULL);
if (SSL_get_shutdown(ssl) == SSL_RECEIVED_SHUTDOWN)
- SSL_shutdown(ssl);
+ SSL_shutdown(ssl);
tls_close(NULL, TLS_NO_SHUTDOWN);
return FAIL;
|| r == SSL_R_VERSION_TOO_LOW
#endif
|| r == SSL_R_UNKNOWN_PROTOCOL || r == SSL_R_UNSUPPORTED_PROTOCOL)
- s = string_sprintf("%s (%s)", s, SSL_get_version(ssl));
+ s = string_sprintf("(%s)", SSL_get_version(ssl));
(void) tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : s, errstr);
+ (void) event_raise(event_action, US"tls:fail:connect", *errstr, NULL);
return FAIL;
}
if (!errno)
{
*errstr = US"SSL_accept: TCP connection closed by peer";
+ (void) event_raise(event_action, US"tls:fail:connect", *errstr, NULL);
return FAIL;
}
DEBUG(D_tls) debug_printf(" - syscall %s\n", strerror(errno));
sigalrm_seen ? US"timed out"
: ERR_peek_error() ? NULL : string_sprintf("ret %d", error),
errstr);
+ (void) event_raise(event_action, US"tls:fail:connect", *errstr, NULL);
return FAIL;
}
}
if (SSL_get_shared_ciphers(ssl, CS buf, sizeof(buf)))
debug_printf("Shared ciphers: %s\n", buf);
-#ifdef EXIM_HAVE_OPENSSL_KEYLOG
- {
- BIO * bp = BIO_new_fp(debug_file, BIO_NOCLOSE);
- SSL_SESSION_print_keylog(bp, SSL_get_session(ssl));
- BIO_free(bp);
- }
-#endif
+ tls_dump_keylog(ssl);
#ifdef EXIM_HAVE_SESSION_TICKET
{
size_t len = SSL_get_peer_finished(ssl, &c, 0);
int old_pool = store_pool;
- SSL_get_peer_finished(ssl, s = store_get((int)len, FALSE), len);
+ SSL_get_peer_finished(ssl, s = store_get((int)len, GET_UNTAINTED), len);
store_pool = POOL_PERM;
- tls_in.channelbinding = b64encode_taint(CUS s, (int)len, FALSE);
+ tls_in.channelbinding = b64encode_taint(CUS s, (int)len, GET_UNTAINTED);
store_pool = old_pool;
DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage %p\n", tls_in.channelbinding);
}
{
int len = i2d_SSL_SESSION(ss, NULL);
int dlen = sizeof(dbdata_tls_session) + len;
- dbdata_tls_session * dt = store_get(dlen, TRUE);
+ dbdata_tls_session * dt = store_get(dlen, GET_TAINTED);
uschar * s = dt->session;
open_db dbblock, * dbm_file;
but it's little extra code complexity in the client. */
const uschar * list = exp_alpn;
- uschar * p = store_get(Ustrlen(exp_alpn), is_tainted(exp_alpn)), * s, * t;
+ uschar * p = store_get(Ustrlen(exp_alpn), exp_alpn), * s, * t;
int sep = 0;
uschar len;
rc = store_pool;
store_pool = POOL_PERM;
-exim_client_ctx = store_get(sizeof(exim_openssl_client_tls_ctx), FALSE);
+exim_client_ctx = store_get(sizeof(exim_openssl_client_tls_ctx), GET_UNTAINTED);
exim_client_ctx->corked = NULL;
store_pool = rc;
DEBUG(D_tls)
{
debug_printf("SSL_connect succeeded\n");
-#ifdef EXIM_HAVE_OPENSSL_KEYLOG
- {
- BIO * bp = BIO_new_fp(debug_file, BIO_NOCLOSE);
- SSL_SESSION_print_keylog(bp, SSL_get_session(exim_client_ctx->ssl));
- BIO_free(bp);
- }
-#endif
+ tls_dump_keylog(exim_client_ctx->ssl);
}
#ifndef DISABLE_TLS_RESUME
size_t len = SSL_get_finished(exim_client_ctx->ssl, &c, 0);
int old_pool = store_pool;
- SSL_get_finished(exim_client_ctx->ssl, s = store_get((int)len, TRUE), len);
+ SSL_get_finished(exim_client_ctx->ssl, s = store_get((int)len, GET_TAINTED), len);
store_pool = POOL_PERM;
- tlsp->channelbinding = b64encode_taint(CUS s, (int)len, TRUE);
+ tlsp->channelbinding = b64encode_taint(CUS s, (int)len, GET_TAINTED);
store_pool = old_pool;
DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage %p %p\n", tlsp->channelbinding, tlsp);
}
if ( (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */
&& do_shutdown > 1)
{
+#ifdef EXIM_TCP_CORK
+ (void) setsockopt(*fdp, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off));
+#endif
ALARM(2);
rc = SSL_shutdown(*sslp); /* wait for response */
ALARM_CLR(0);
uschar *
tls_validate_require_cipher(void)
{
-SSL_CTX *ctx;
-uschar *s, *expciphers, *err;
+SSL_CTX * ctx;
+uschar * expciphers, * err;
tls_openssl_init();
will change, so we can more usefully assist with version diagnosis by also
reporting the build date.
-Arguments: a FILE* to print the results to
-Returns: nothing
+Arguments: string to append to
+Returns: string
*/
-void
-tls_version_report(FILE *f)
+gstring *
+tls_version_report(gstring * g)
{
-fprintf(f, "Library version: OpenSSL: Compile: %s\n"
- " Runtime: %s\n"
- " : %s\n",
- OPENSSL_VERSION_TEXT,
- SSLeay_version(SSLEAY_VERSION),
- SSLeay_version(SSLEAY_BUILT_ON));
-/* third line is 38 characters for the %s and the line is 73 chars long;
-the OpenSSL output includes a "built on: " prefix already. */
+return string_fmt_append(g,
+ "Library version: OpenSSL: Compile: %s\n"
+ " Runtime: %s\n"
+ " : %s\n",
+ OPENSSL_VERSION_TEXT,
+ SSLeay_version(SSLEAY_VERSION),
+ SSLeay_version(SSLEAY_BUILT_ON));
+ /* third line is 38 characters for the %s and the line is 73 chars long;
+ the OpenSSL output includes a "built on: " prefix already. */
}