From 7bfa22b17c1c6fa0010e4b1f11013b402dac84b0 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 4 Oct 2020 14:15:09 +0100 Subject: [PATCH] Fix build on earlier library version Broken-by: 6a9cf7f890 --- src/src/tls-gnu.c | 118 ++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 4a3e1651e..b6354b4b2 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -345,6 +345,53 @@ tls_server_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when, #endif +/************************************************* +* Handle TLS error * +*************************************************/ + +/* Called from lots of places when errors occur before actually starting to do +the TLS handshake, that is, while the session is still in clear. Always returns +DEFER for a server and FAIL for a client so that most calls can use "return +tls_error(...)" to do this processing and then give an appropriate return. A +single function is used for both server and client, because it is called from +some shared functions. + +Argument: + prefix text to include in the logged error + msg additional error string (may be NULL) + usually obtained from gnutls_strerror() + host NULL if setting up a server; + the connected host if setting up a client + errstr pointer to returned error string + +Returns: OK/DEFER/FAIL +*/ + +static int +tls_error(const uschar *prefix, const uschar *msg, const host_item *host, + uschar ** errstr) +{ +if (errstr) + *errstr = string_sprintf("(%s)%s%s", prefix, msg ? ": " : "", msg ? msg : US""); +return host ? FAIL : DEFER; +} + + +static int +tls_error_gnu(const uschar *prefix, int err, const host_item *host, + uschar ** errstr) +{ +return tls_error(prefix, US gnutls_strerror(err), host, errstr); +} + +static int +tls_error_sys(const uschar *prefix, int err, const host_item *host, + uschar ** errstr) +{ +return tls_error(prefix, US strerror(err), host, errstr); +} + + /* ------------------------------------------------------------------------ */ /* Initialisation */ @@ -379,9 +426,10 @@ return FALSE; #endif -static void -tls_g_init(void) +static int +tls_g_init(uschar ** errstr) { +int rc; DEBUG(D_tls) debug_printf("GnuTLS global init required\n"); #if defined(HAVE_GNUTLS_PKCS11) && !defined(GNUTLS_AUTO_PKCS11_MANUAL) @@ -393,12 +441,12 @@ To prevent this, we init PKCS11 first, which is the documented approach. */ if (!gnutls_allow_auto_pkcs11) if ((rc = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL))) - return tls_error_gnu(US"gnutls_pkcs11_init", rc, host, errstr); + return tls_error_gnu(US"gnutls_pkcs11_init", rc, NULL, errstr); #endif #ifndef GNUTLS_AUTO_GLOBAL_INIT if ((rc = gnutls_global_init())) - return tls_error_gnu(US"gnutls_global_init", rc, host, errstr); + return tls_error_gnu(US"gnutls_global_init", rc, NULL, errstr); #endif #if EXIM_GNUTLS_LIBRARY_LOG_LEVEL >= 0 @@ -416,6 +464,7 @@ if (tls_ocsp_file && (gnutls_buggy_ocsp = tls_is_buggy_ocsp())) #endif exim_gnutls_base_init_done = TRUE; +return OK; } @@ -432,10 +481,11 @@ tls_per_lib_daemon_tick(void) static void tls_per_lib_daemon_init(void) { +uschar * dummy_errstr; static BOOL once = FALSE; if (!exim_gnutls_base_init_done) - tls_g_init(); + tls_g_init(&dummy_errstr); if (!once) { @@ -456,54 +506,6 @@ if (!once) } /* ------------------------------------------------------------------------ */ -/* Static functions */ - -/************************************************* -* Handle TLS error * -*************************************************/ - -/* Called from lots of places when errors occur before actually starting to do -the TLS handshake, that is, while the session is still in clear. Always returns -DEFER for a server and FAIL for a client so that most calls can use "return -tls_error(...)" to do this processing and then give an appropriate return. A -single function is used for both server and client, because it is called from -some shared functions. - -Argument: - prefix text to include in the logged error - msg additional error string (may be NULL) - usually obtained from gnutls_strerror() - host NULL if setting up a server; - the connected host if setting up a client - errstr pointer to returned error string - -Returns: OK/DEFER/FAIL -*/ - -static int -tls_error(const uschar *prefix, const uschar *msg, const host_item *host, - uschar ** errstr) -{ -if (errstr) - *errstr = string_sprintf("(%s)%s%s", prefix, msg ? ": " : "", msg ? msg : US""); -return host ? FAIL : DEFER; -} - - -static int -tls_error_gnu(const uschar *prefix, int err, const host_item *host, - uschar ** errstr) -{ -return tls_error(prefix, US gnutls_strerror(err), host, errstr); -} - -static int -tls_error_sys(const uschar *prefix, int err, const host_item *host, - uschar ** errstr) -{ -return tls_error(prefix, US strerror(err), host, errstr); -} - /************************************************* * Deal with logging errors during I/O * @@ -1532,8 +1534,9 @@ exim_gnutls_state_st tpt_dummy_state; host_item * dummy_host = (host_item *)1; uschar * dummy_errstr; -if (!exim_gnutls_base_init_done) - tls_g_init(); +if ( !exim_gnutls_base_init_done + && tls_g_init(&dummy_errstr) != OK) + return; ob->tls_preload = null_tls_preload; if (gnutls_certificate_allocate_credentials( @@ -1937,8 +1940,9 @@ exim_gnutls_state_st * state; int rc; size_t sz; -if (!exim_gnutls_base_init_done) - tls_g_init(); +if ( !exim_gnutls_base_init_done + && (rc = tls_g_init(errstr)) != OK) + return rc; if (host) { -- 2.30.2