X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/817d9f576cdfbc27cf0536be348645baf27d7836..09792322d9224b0407783a19c2dd57fd1a8bbd52:/src/src/tls-gnu.c diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 8a133c5af..239985767 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -39,6 +39,10 @@ require current GnuTLS, then we'll drop support for the ancient libraries). #include /* man-page is incorrect, gnutls_rnd() is not in gnutls.h: */ #include +/* needed to disable PKCS11 autoload unless requested */ +#if GNUTLS_VERSION_NUMBER >= 0x020c00 +# include +#endif /* GnuTLS 2 vs 3 @@ -63,7 +67,7 @@ Some of these correspond to variables in globals.c; those variables will be set to point to content in one of these instances, as appropriate for the stage of the process lifetime. -Not handled here: global tls_channelbinding_b64. /*XXX JGH */ +Not handled here: global tls_channelbinding_b64. */ typedef struct exim_gnutls_state { @@ -94,7 +98,7 @@ typedef struct exim_gnutls_state { uschar *exp_tls_crl; uschar *exp_tls_require_ciphers; - tls_support *tlsp; + tls_support *tlsp; /* set in tls_init() */ uschar *xfer_buffer; int xfer_buffer_lwm; @@ -172,6 +176,7 @@ before, for now. */ #define HAVE_GNUTLS_SESSION_CHANNEL_BINDING #define HAVE_GNUTLS_SEC_PARAM_CONSTANTS #define HAVE_GNUTLS_RND +#define HAVE_GNUTLS_PKCS11 #endif @@ -649,7 +654,11 @@ if (!state->host) { if (!state->received_sni) { - if (state->tls_certificate && Ustrstr(state->tls_certificate, US"tls_sni")) + if (state->tls_certificate && + (Ustrstr(state->tls_certificate, US"tls_sni") || + Ustrstr(state->tls_certificate, US"tls_in_sni") || + Ustrstr(state->tls_certificate, US"tls_out_sni") + )) { DEBUG(D_tls) debug_printf("We will re-expand TLS session files if we receive SNI.\n"); state->trigger_sni_changes = TRUE; @@ -907,6 +916,19 @@ if (!exim_gnutls_base_init_done) { DEBUG(D_tls) debug_printf("GnuTLS global init required.\n"); +#ifdef HAVE_GNUTLS_PKCS11 + /* By default, gnutls_global_init will init PKCS11 support in auto mode, + which loads modules from a config file, which sounds good and may be wanted + by some sysadmin, but also means in common configurations that GNOME keyring + environment variables are used and so breaks for users calling mailq. + To prevent this, we init PKCS11 first, which is the documented approach. */ + if (!gnutls_enable_pkcs11) + { + rc = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL); + exim_gnutls_err_check(US"gnutls_pkcs11_init"); + } +#endif + rc = gnutls_global_init(); exim_gnutls_err_check(US"gnutls_global_init"); @@ -966,7 +988,7 @@ if (rc != OK) return rc; /* set SNI in client, only */ if (host) { - if (!expand_check_tlsvar(state->tlsp->sni)) + if (!expand_check(state->tlsp->sni, US"tls_out_sni", &state->exp_tls_sni)) return DEFER; if (state->exp_tls_sni && *state->exp_tls_sni) { @@ -1641,7 +1663,7 @@ tls_close(BOOL is_server, BOOL shutdown) { exim_gnutls_state_st *state = is_server ? &state_server : &state_client; -if (state->tlsp->active < 0) return; /* TLS was not active */ +if (!state->tlsp || state->tlsp->active < 0) return; /* TLS was not active */ if (shutdown) { @@ -1651,6 +1673,7 @@ if (shutdown) gnutls_deinit(state->session); +state->tlsp->active = -1; memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init)); if ((state_server.session == NULL) && (state_client.session == NULL)) @@ -1659,7 +1682,6 @@ if ((state_server.session == NULL) && (state_client.session == NULL)) exim_gnutls_base_init_done = FALSE; } -state->tlsp->active = -1; } @@ -1941,6 +1963,13 @@ if (exim_gnutls_base_init_done) log_write(0, LOG_MAIN|LOG_PANIC, "already initialised GnuTLS, Exim developer bug"); +#ifdef HAVE_GNUTLS_PKCS11 +if (!gnutls_enable_pkcs11) + { + rc = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL); + validate_check_rc(US"gnutls_pkcs11_init"); + } +#endif rc = gnutls_global_init(); validate_check_rc(US"gnutls_global_init()"); exim_gnutls_base_init_done = TRUE;