]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Refactor] Move OpenSSL providers from global to libs_ctx
authorVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 28 Oct 2025 11:30:28 +0000 (11:30 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 28 Oct 2025 11:30:28 +0000 (11:30 +0000)
Previously, OpenSSL 3.0+ providers (legacy and default) were stored in
static global variables. This is not a good architecture as these resources
should be managed alongside other library contexts.

This commit refactors the code to store SSL providers in the
rspamd_external_libs_ctx structure:
- Add ssl_legacy_provider and ssl_default_provider fields to libs_ctx
- Pass libs_ctx to rspamd_openssl_maybe_init() to store providers there
- Remove rspamd_openssl_cleanup() function - cleanup now happens in
  rspamd_deinit_libs() when the libs_ctx is freed
- Remove global variables and manual cleanup calls

This provides better resource management and clearer ownership of
OpenSSL provider lifecycle.

src/libserver/cfg_utils.cxx
src/libserver/ssl_util.c
src/libserver/ssl_util.h
src/rspamd.c
src/rspamd.h

index 55ed5a18ba8997df32fce21e5124c1c8e3ba9cc7..7bfe13f69e9cf24191628aa491d2cb6efb3be17f 100644 (file)
@@ -51,6 +51,9 @@
 #include <openssl/evp.h>
 #include <openssl/ssl.h>
 #include <openssl/conf.h>
+#if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/provider.h>
+#endif
 #endif
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
@@ -2736,7 +2739,7 @@ rspamd_init_libs(void)
        ottery_config_init(ottery_cfg);
        ctx->ottery_cfg = ottery_cfg;
 
-       rspamd_openssl_maybe_init();
+       rspamd_openssl_maybe_init(ctx);
 
        /* Check if we have rdrand */
        if ((ctx->crypto_ctx->cpu_config & CPUID_RDRAND) == 0) {
@@ -3016,6 +3019,14 @@ void rspamd_deinit_libs(struct rspamd_external_libs_ctx *ctx)
                ERR_free_strings();
                rspamd_ssl_ctx_free(ctx->ssl_ctx);
                rspamd_ssl_ctx_free(ctx->ssl_ctx_noverify);
+#if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
+               if (ctx->ssl_legacy_provider) {
+                       OSSL_PROVIDER_unload((OSSL_PROVIDER *) ctx->ssl_legacy_provider);
+               }
+               if (ctx->ssl_default_provider) {
+                       OSSL_PROVIDER_unload((OSSL_PROVIDER *) ctx->ssl_default_provider);
+               }
+#endif
 #endif
                rspamd_inet_library_destroy();
                rspamd_free_zstd_dictionary(ctx->in_dict);
index 6d6046ba04363b90243f5dd7d3e4f0c1042639d6..78d1c02a76f2c3b563c75b1972a9e90ba3ba9ee1 100644 (file)
@@ -19,6 +19,7 @@
 #include "libutil/hash.h"
 #include "libserver/logger.h"
 #include "libserver/cfg_file.h"
+#include "rspamd.h"
 #include "ssl_util.h"
 #include "unix-std.h"
 #include "cryptobox.h"
@@ -1002,8 +1003,6 @@ rspamd_init_ssl_ctx_common(void)
        int ssl_options;
        static const unsigned int client_cache_size = 1024;
 
-       rspamd_openssl_maybe_init();
-
        ret = g_malloc0(sizeof(*ret));
        ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
        ssl_ctx = SSL_CTX_new(SSLv23_method());
@@ -1056,11 +1055,9 @@ gpointer rspamd_init_ssl_ctx_noverify(void)
 }
 #if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
 #include <openssl/provider.h>
-static OSSL_PROVIDER *rspamd_legacy_provider = NULL;
-static OSSL_PROVIDER *rspamd_default_provider = NULL;
 #endif
 
-void rspamd_openssl_maybe_init(void)
+void rspamd_openssl_maybe_init(struct rspamd_external_libs_ctx *ctx)
 {
        static gboolean openssl_initialized = FALSE;
 
@@ -1081,15 +1078,17 @@ void rspamd_openssl_maybe_init(void)
                OPENSSL_init_ssl(0, NULL);
 #endif
 #if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
-               rspamd_legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
-               if (rspamd_legacy_provider == NULL) {
-                       msg_err("cannot load legacy OpenSSL provider: %s", ERR_lib_error_string(ERR_get_error()));
-                       ERR_clear_error();
-               }
-               rspamd_default_provider = OSSL_PROVIDER_load(NULL, "default");
-               if (rspamd_default_provider == NULL) {
-                       msg_err("cannot load default OpenSSL provider: %s", ERR_lib_error_string(ERR_get_error()));
-                       ERR_clear_error();
+               if (ctx) {
+                       ctx->ssl_legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
+                       if (ctx->ssl_legacy_provider == NULL) {
+                               msg_err("cannot load legacy OpenSSL provider: %s", ERR_lib_error_string(ERR_get_error()));
+                               ERR_clear_error();
+                       }
+                       ctx->ssl_default_provider = OSSL_PROVIDER_load(NULL, "default");
+                       if (ctx->ssl_default_provider == NULL) {
+                               msg_err("cannot load default OpenSSL provider: %s", ERR_lib_error_string(ERR_get_error()));
+                               ERR_clear_error();
+                       }
                }
 #endif
 
@@ -1109,20 +1108,6 @@ void rspamd_openssl_maybe_init(void)
        }
 }
 
-void rspamd_openssl_cleanup(void)
-{
-#if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
-       if (rspamd_legacy_provider) {
-               OSSL_PROVIDER_unload(rspamd_legacy_provider);
-               rspamd_legacy_provider = NULL;
-       }
-       if (rspamd_default_provider) {
-               OSSL_PROVIDER_unload(rspamd_default_provider);
-               rspamd_default_provider = NULL;
-       }
-#endif
-}
-
 void rspamd_ssl_ctx_config(struct rspamd_config *cfg, gpointer ssl_ctx)
 {
        struct rspamd_ssl_ctx *ctx = (struct rspamd_ssl_ctx *) ssl_ctx;
index 15962cc07249f6b50fac7fa65f9c5b7a983db650..628f2aed6bec87bbc3a7abfab553a3269c939bf1 100644 (file)
@@ -111,8 +111,7 @@ gpointer rspamd_init_ssl_ctx(void);
 gpointer rspamd_init_ssl_ctx_noverify(void);
 void rspamd_ssl_ctx_config(struct rspamd_config *cfg, gpointer ssl_ctx);
 void rspamd_ssl_ctx_free(gpointer ssl_ctx);
-void rspamd_openssl_maybe_init(void);
-void rspamd_openssl_cleanup(void);
+void rspamd_openssl_maybe_init(struct rspamd_external_libs_ctx *ctx);
 
 #ifdef __cplusplus
 }
index 777c6261f44b2a6530dc1bcd016cc2bdeb86d753..2329d421086ff6985bd056e953f88275183630ba 100644 (file)
@@ -334,14 +334,14 @@ reread_config(struct rspamd_main *rspamd_main)
                rspamd_main->cfg = old_cfg;
                rspamd_main->logger = old_logger;
                msg_err_main("cannot parse new config file, revert to old one");
-               REF_RELEASE(tmp_cfg);
+               CFG_REF_RELEASE(tmp_cfg);
 
                return FALSE;
        }
        else {
                rspamd_log_close(old_logger);
                msg_info_main("replacing config");
-               REF_RELEASE(old_cfg);
+               CFG_REF_RELEASE(old_cfg);
                rspamd_main->cfg->rspamd_user = rspamd_user;
                rspamd_main->cfg->rspamd_group = rspamd_group;
                /* Here, we can do post actions with the existing config */
@@ -1739,9 +1739,8 @@ int main(int argc, char **argv, char **env)
 #ifdef WITH_HYPERSCAN
        rspamd_hyperscan_cleanup_maybe();
 #endif
-       REF_RELEASE(rspamd_main->cfg);
+       CFG_REF_RELEASE(rspamd_main->cfg);
        rspamd_log_close(rspamd_main->logger);
-       rspamd_openssl_cleanup();
        g_hash_table_unref(rspamd_main->spairs);
        g_hash_table_unref(rspamd_main->workers);
        rspamd_mempool_delete(rspamd_main->server_pool);
index be66a192b761535d433c7794f245d0f326041c17..7aeccae98305183e4554467344655a302b6bfee5 100644 (file)
@@ -361,6 +361,10 @@ struct rspamd_external_libs_ctx {
        struct zstd_dictionary *out_dict;
        void *out_zstream;
        void *in_zstream;
+#if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
+       void *ssl_legacy_provider;
+       void *ssl_default_provider;
+#endif
        ref_entry_t ref;
 };