X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/6b5cbf740022f7f57a425d212499f156b1641d49..e89d95f1909c0972b0e854ae05f50246f4d727d6:/src/src/tls.c diff --git a/src/src/tls.c b/src/src/tls.c index 63d98c806..e5aabc6b4 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ /* This module provides TLS (aka SSL) support for Exim. The code for OpenSSL is @@ -61,8 +62,6 @@ static int ssl_xfer_eof = FALSE; static BOOL ssl_xfer_error = FALSE; #endif -uschar *tls_channelbinding_b64 = NULL; - /************************************************* * Expand string; give error on failure * @@ -371,9 +370,14 @@ return FALSE; } -/* Environment cleanup: The GnuTLS library spots SSLKEYLOGFILE in the envonment -and writes a file by that name. We might make the OpenSSL support do the same, -in some future release. Restrict that filename to be under the spool directory. +/* Environment cleanup: The GnuTLS library uses SSLKEYLOGFILE in the environment +and writes a file by that name. Our OpenSSL code does the same, using keying +info from the library API. +The GnuTLS support only works if exim is run by root, not taking advantage of +the setuid bit. +You can use either the external environment (modulo the keep_environment config) +or the add_environment config option for SSLKEYLOGFILE; the latter takes +precedence. If the path is absolute, require it starts with the spooldir; otherwise delete the env variable. If relative, prefix the spooldir. @@ -394,10 +398,83 @@ if (path) else if (Ustrncmp(path, spool_directory, Ustrlen(spool_directory)) != 0) { DEBUG(D_tls) - debug_printf("removing env SSLKEYLOGFILE: not under spooldir\n"); + debug_printf("removing env SSLKEYLOGFILE=%s: not under spooldir\n", path); unsetenv("SSLKEYLOGFILE"); } } + +/************************************************* +* Drop privs for checking TLS config * +*************************************************/ + +/* We want to validate TLS options during readconf, but do not want to be +root when we call into the TLS library, in case of library linkage errors +which cause segfaults; before this check, those were always done as the Exim +runtime user and it makes sense to continue with that. + +Assumes: tls_require_ciphers has been set, if it will be + exim_user has been set, if it will be + exim_group has been set, if it will be + +Returns: bool for "okay"; false will cause caller to immediately exit. +*/ + +BOOL +tls_dropprivs_validate_require_cipher(BOOL nowarn) +{ +const uschar *errmsg; +pid_t pid; +int rc, status; +void (*oldsignal)(int); + +/* If TLS will never be used, no point checking ciphers */ + +if ( !tls_advertise_hosts + || !*tls_advertise_hosts + || Ustrcmp(tls_advertise_hosts, ":") == 0 + ) + return TRUE; +else if (!nowarn && !tls_certificate) + log_write(0, LOG_MAIN, + "Warning: No server certificate defined; will use a selfsigned one.\n" + " Suggested action: either install a certificate or change tls_advertise_hosts option"); + +oldsignal = signal(SIGCHLD, SIG_DFL); + +fflush(NULL); +if ((pid = exim_fork(US"cipher-validate")) < 0) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for TLS check"); + +if (pid == 0) + { + /* in some modes, will have dropped privilege already */ + if (!geteuid()) + exim_setugid(exim_uid, exim_gid, FALSE, + US"calling tls_validate_require_cipher"); + + if ((errmsg = tls_validate_require_cipher())) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG, + "tls_require_ciphers invalid: %s", errmsg); + fflush(NULL); + exim_underbar_exit(EXIT_SUCCESS); + } + +do { + rc = waitpid(pid, &status, 0); +} while (rc < 0 && errno == EINTR); + +DEBUG(D_tls) + debug_printf("tls_validate_require_cipher child %d ended: status=0x%x\n", + (int)pid, status); + +signal(SIGCHLD, oldsignal); + +return status == 0; +} + + + + #endif /*!DISABLE_TLS*/ #endif /*!MACRO_PREDEF*/