From 5fe437851dc63bf9c7488d34e434b0e00fd2656a Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 19 Feb 2019 17:56:42 +0000 Subject: [PATCH] [Project] Adopt librspamdserver for http context --- src/libserver/rspamd_control.c | 7 +- src/libutil/CMakeLists.txt | 1 + src/libutil/http_connection.c | 310 ++++----------------------------- src/libutil/http_connection.h | 9 +- src/libutil/http_private.h | 13 ++ src/libutil/http_router.c | 18 +- src/libutil/http_router.h | 5 +- src/libutil/http_util.c | 266 ++++++++++++++++++++++++++++ src/libutil/map.c | 13 +- src/libutil/util.c | 152 ++++++++++------ src/libutil/util.h | 3 + 11 files changed, 431 insertions(+), 366 deletions(-) diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c index 2fd1d983f..fb0fc22b6 100644 --- a/src/libserver/rspamd_control.c +++ b/src/libserver/rspamd_control.c @@ -511,13 +511,12 @@ rspamd_control_process_client_socket (struct rspamd_main *rspamd_main, session = g_malloc0 (sizeof (*session)); session->fd = fd; - session->conn = rspamd_http_connection_new (NULL, + session->conn = rspamd_http_connection_new (rspamd_main->http_ctx, + NULL, rspamd_control_error_handler, rspamd_control_finish_handler, 0, - RSPAMD_HTTP_SERVER, - NULL, - NULL); + RSPAMD_HTTP_SERVER); session->rspamd_main = rspamd_main; rspamd_http_connection_read_message (session->conn, session, session->fd, &io_timeout, rspamd_main->ev_base); diff --git a/src/libutil/CMakeLists.txt b/src/libutil/CMakeLists.txt index 4d4f8c7bd..f86d650f0 100644 --- a/src/libutil/CMakeLists.txt +++ b/src/libutil/CMakeLists.txt @@ -10,6 +10,7 @@ SET(LIBRSPAMDUTILSRC ${CMAKE_CURRENT_SOURCE_DIR}/http_message.c ${CMAKE_CURRENT_SOURCE_DIR}/http_connection.c ${CMAKE_CURRENT_SOURCE_DIR}/http_router.c + ${CMAKE_CURRENT_SOURCE_DIR}/http_context.c ${CMAKE_CURRENT_SOURCE_DIR}/logger.c ${CMAKE_CURRENT_SOURCE_DIR}/map.c ${CMAKE_CURRENT_SOURCE_DIR}/map_helpers.c diff --git a/src/libutil/http_connection.c b/src/libutil/http_connection.c index df283f752..8463ff762 100644 --- a/src/libutil/http_connection.c +++ b/src/libutil/http_connection.c @@ -55,9 +55,10 @@ enum rspamd_http_priv_flags { #define IS_CONN_RESETED(c) ((c)->flags & RSPAMD_HTTP_CONN_FLAG_RESETED) struct rspamd_http_connection_private { - gpointer ssl_ctx; + struct rspamd_http_context *ctx; struct rspamd_ssl_connection *ssl; struct _rspamd_http_privbuf *buf; + struct rspamd_keypair_cache *cache; struct rspamd_cryptobox_pubkey *peer_key; struct rspamd_cryptobox_keypair *local_key; struct rspamd_http_header *header; @@ -133,272 +134,6 @@ rspamd_http_code_to_str (gint code) return "Unknown error"; } -/* - * Obtained from nginx - * Copyright (C) Igor Sysoev - */ -static guint mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -time_t -rspamd_http_parse_date (const gchar *header, gsize len) -{ - const gchar *p, *end; - gint month; - guint day, year, hour, min, sec; - guint64 time; - enum { - no = 0, rfc822, /* Tue, 10 Nov 2002 23:50:13 */ - rfc850, /* Tuesday, 10-Dec-02 23:50:13 */ - isoc /* Tue Dec 10 23:50:13 2002 */ - } fmt; - - fmt = 0; - if (len > 0) { - end = header + len; - } - else { - end = header + strlen (header); - } - - day = 32; - year = 2038; - - for (p = header; p < end; p++) { - if (*p == ',') { - break; - } - - if (*p == ' ') { - fmt = isoc; - break; - } - } - - for (p++; p < end; p++) - if (*p != ' ') { - break; - } - - if (end - p < 18) { - return (time_t)-1; - } - - if (fmt != isoc) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return (time_t)-1; - } - - day = (*p - '0') * 10 + *(p + 1) - '0'; - p += 2; - - if (*p == ' ') { - if (end - p < 18) { - return (time_t)-1; - } - fmt = rfc822; - - } - else if (*p == '-') { - fmt = rfc850; - - } - else { - return (time_t)-1; - } - - p++; - } - - switch (*p) { - - case 'J': - month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6; - break; - - case 'F': - month = 1; - break; - - case 'M': - month = *(p + 2) == 'r' ? 2 : 4; - break; - - case 'A': - month = *(p + 1) == 'p' ? 3 : 7; - break; - - case 'S': - month = 8; - break; - - case 'O': - month = 9; - break; - - case 'N': - month = 10; - break; - - case 'D': - month = 11; - break; - - default: - return (time_t)-1; - } - - p += 3; - - if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) { - return (time_t)-1; - } - - p++; - - if (fmt == rfc822) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' - || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0' - || *(p + 3) > '9') { - return (time_t)-1; - } - - year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 - + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; - p += 4; - - } - else if (fmt == rfc850) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return (time_t)-1; - } - - year = (*p - '0') * 10 + *(p + 1) - '0'; - year += (year < 70) ? 2000 : 1900; - p += 2; - } - - if (fmt == isoc) { - if (*p == ' ') { - p++; - } - - if (*p < '0' || *p > '9') { - return (time_t)-1; - } - - day = *p++ - '0'; - - if (*p != ' ') { - if (*p < '0' || *p > '9') { - return (time_t)-1; - } - - day = day * 10 + *p++ - '0'; - } - - if (end - p < 14) { - return (time_t)-1; - } - } - - if (*p++ != ' ') { - return (time_t)-1; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return (time_t)-1; - } - - hour = (*p - '0') * 10 + *(p + 1) - '0'; - p += 2; - - if (*p++ != ':') { - return (time_t)-1; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return (time_t)-1; - } - - min = (*p - '0') * 10 + *(p + 1) - '0'; - p += 2; - - if (*p++ != ':') { - return (time_t)-1; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return (time_t)-1; - } - - sec = (*p - '0') * 10 + *(p + 1) - '0'; - - if (fmt == isoc) { - p += 2; - - if (*p++ != ' ') { - return (time_t)-1; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' - || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0' - || *(p + 3) > '9') { - return (time_t)-1; - } - - year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 - + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; - } - - if (hour > 23 || min > 59 || sec > 59) { - return (time_t)-1; - } - - if (day == 29 && month == 1) { - if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) { - return (time_t)-1; - } - - } - else if (day > mday[month]) { - return (time_t)-1; - } - - /* - * shift new year to March 1 and start months from 1 (not 0), - * it is needed for Gauss' formula - */ - - if (--month <= 0) { - month += 12; - year -= 1; - } - - /* Gauss' formula for Gregorian days since March 1, 1 BC */ - - time = (guint64) ( - /* days in years including leap years since March 1, 1 BC */ - - 365 * year + year / 4 - year / 100 + year / 400 - - /* days before the month */ - - + 367 * month / 12 - 30 - - /* days before the day */ - - + day - 1 - - /* - * 719527 days were between March 1, 1 BC and March 1, 1970, - * 31 and 28 days were in January and February 1970 - */ - - - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec; - - return (time_t) time; -} - static void rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn, struct rspamd_http_connection_private *priv) @@ -430,9 +165,10 @@ rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn, RSPAMD_KEYPAIR_SHORT_ID_LEN) == 0) { priv->msg->peer_key = pk; - if (conn->cache && priv->msg->peer_key) { - rspamd_keypair_cache_process (conn->cache, - priv->local_key, priv->msg->peer_key); + if (priv->cache && priv->msg->peer_key) { + rspamd_keypair_cache_process (priv->cache, + priv->local_key, + priv->msg->peer_key); } } else { @@ -1299,13 +1035,12 @@ rspamd_http_parser_reset (struct rspamd_http_connection *conn) struct rspamd_http_connection * rspamd_http_connection_new ( + struct rspamd_http_context *ctx, rspamd_http_body_handler_t body_handler, rspamd_http_error_handler_t error_handler, rspamd_http_finish_handler_t finish_handler, unsigned opts, - enum rspamd_http_connection_type type, - struct rspamd_keypair_cache *cache, - gpointer ssl_ctx) + enum rspamd_http_connection_type type) { struct rspamd_http_connection *conn; struct rspamd_http_connection_private *priv; @@ -1323,12 +1058,25 @@ rspamd_http_connection_new ( conn->fd = -1; conn->ref = 1; conn->finished = FALSE; - conn->cache = cache; /* Init priv */ + if (ctx == NULL) { + ctx = rspamd_http_context_default (); + } + priv = g_malloc0 (sizeof (struct rspamd_http_connection_private)); conn->priv = priv; - priv->ssl_ctx = ssl_ctx; + priv->ctx = ctx; + + if (conn->type == RSPAMD_HTTP_CLIENT) { + priv->cache = ctx->client_kp_cache; + if (ctx->client_kp) { + priv->local_key = rspamd_keypair_ref (ctx->client_kp); + } + } + else { + priv->cache = ctx->server_kp_cache; + } rspamd_http_parser_reset (conn); priv->parser.data = conn; @@ -2022,8 +1770,8 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn encrypted = TRUE; - if (conn->cache) { - rspamd_keypair_cache_process (conn->cache, + if (priv->cache) { + rspamd_keypair_cache_process (priv->cache, priv->local_key, priv->msg->peer_key); } } @@ -2287,10 +2035,14 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn } if (msg->flags & RSPAMD_HTTP_FLAG_SSL) { + gpointer ssl_ctx = (msg->flags & RSPAMD_HTTP_FLAG_SSL_NOVERIFY) ? + priv->ctx->ssl_ctx_noverify : priv->ctx->ssl_ctx; + if (base != NULL) { event_base_set (base, &priv->ev); } - if (!priv->ssl_ctx) { + + if (!ssl_ctx) { err = g_error_new (HTTP_ERROR, errno, "ssl message requested " "with no ssl ctx"); rspamd_http_connection_ref (conn); @@ -2305,7 +2057,7 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn rspamd_ssl_connection_free (priv->ssl); } - priv->ssl = rspamd_ssl_connection_new (priv->ssl_ctx, base, + priv->ssl = rspamd_ssl_connection_new (ssl_ctx, base, !(msg->flags & RSPAMD_HTTP_FLAG_SSL_NOVERIFY)); g_assert (priv->ssl != NULL); diff --git a/src/libutil/http_connection.h b/src/libutil/http_connection.h index 1fa1170b2..4e9f9f800 100644 --- a/src/libutil/http_connection.h +++ b/src/libutil/http_connection.h @@ -24,8 +24,7 @@ */ #include "config.h" -#include "keypair.h" -#include "keypairs_cache.h" +#include "http_context.h" #include "fstring.h" #include "ref.h" #include "http_message.h" @@ -104,7 +103,6 @@ struct rspamd_http_connection { rspamd_http_body_handler_t body_handler; rspamd_http_error_handler_t error_handler; rspamd_http_finish_handler_t finish_handler; - struct rspamd_keypair_cache *cache; gpointer ud; gsize max_size; unsigned opts; @@ -121,13 +119,12 @@ struct rspamd_http_connection { * @return new connection structure */ struct rspamd_http_connection *rspamd_http_connection_new ( + struct rspamd_http_context *ctx, rspamd_http_body_handler_t body_handler, rspamd_http_error_handler_t error_handler, rspamd_http_finish_handler_t finish_handler, unsigned opts, - enum rspamd_http_connection_type type, - struct rspamd_keypair_cache *cache, - gpointer ssl_ctx); + enum rspamd_http_connection_type type); /** diff --git a/src/libutil/http_private.h b/src/libutil/http_private.h index df1233d8b..0f8c847a2 100644 --- a/src/libutil/http_private.h +++ b/src/libutil/http_private.h @@ -19,6 +19,8 @@ #include "http_connection.h" #include "http_parser.h" #include "str_util.h" +#include "keypair.h" +#include "keypairs_cache.h" #include "ref.h" #define HASH_CASELESS #include "uthash_strcase.h" @@ -74,6 +76,17 @@ struct rspamd_http_message { ref_entry_t ref; }; +struct rspamd_http_context { + struct rspamd_http_context_cfg config; + struct rspamd_keypair_cache *client_kp_cache; + struct rspamd_cryptobox_keypair *client_kp; + struct rspamd_keypair_cache *server_kp_cache; + gpointer ssl_ctx; + gpointer ssl_ctx_noverify; + struct event_base *ev_base; + struct event client_rotate_ev; +}; + #define HTTP_ERROR http_error_quark () GQuark http_error_quark (void); diff --git a/src/libutil/http_router.c b/src/libutil/http_router.c index 0dc597788..be45c4351 100644 --- a/src/libutil/http_router.c +++ b/src/libutil/http_router.c @@ -373,9 +373,9 @@ rspamd_http_router_finish_handler (struct rspamd_http_connection *conn, struct rspamd_http_connection_router * rspamd_http_router_new (rspamd_http_router_error_handler_t eh, rspamd_http_router_finish_handler_t fh, - struct timeval *timeout, struct event_base *base, + struct timeval *timeout, const char *default_fs_path, - struct rspamd_keypair_cache *cache) + struct rspamd_http_context *ctx) { struct rspamd_http_connection_router * new; struct stat st; @@ -387,7 +387,6 @@ rspamd_http_router_new (rspamd_http_router_error_handler_t eh, new->conns = NULL; new->error_handler = eh; new->finish_handler = fh; - new->ev_base = base; new->response_headers = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, g_free, g_free); @@ -415,7 +414,7 @@ rspamd_http_router_new (rspamd_http_router_error_handler_t eh, } } - new->cache = cache; + new->ctx = ctx; return new; } @@ -510,13 +509,12 @@ rspamd_http_router_handle_socket (struct rspamd_http_connection_router *router, conn->ud = ud; conn->is_reply = FALSE; - conn->conn = rspamd_http_connection_new (NULL, + conn->conn = rspamd_http_connection_new (router->ctx, + NULL, rspamd_http_router_error_handler, rspamd_http_router_finish_handler, 0, - RSPAMD_HTTP_SERVER, - router->cache, - NULL); + RSPAMD_HTTP_SERVER); if (router->key) { rspamd_http_connection_set_key (conn->conn, router->key); @@ -543,10 +541,6 @@ rspamd_http_router_free (struct rspamd_http_connection_router *router) rspamd_keypair_unref (router->key); } - if (router->cache) { - rspamd_keypair_cache_destroy (router->cache); - } - if (router->default_fs_path != NULL) { g_free (router->default_fs_path); } diff --git a/src/libutil/http_router.h b/src/libutil/http_router.h index 7440c519e..8e8056240 100644 --- a/src/libutil/http_router.h +++ b/src/libutil/http_router.h @@ -47,7 +47,7 @@ struct rspamd_http_connection_router { struct timeval tv; struct timeval *ptv; struct event_base *ev_base; - struct rspamd_keypair_cache *cache; + struct rspamd_http_context *ctx; gchar *default_fs_path; rspamd_http_router_handler_t unknown_method_handler; struct rspamd_cryptobox_keypair *key; @@ -67,9 +67,8 @@ struct rspamd_http_connection_router * rspamd_http_router_new ( rspamd_http_router_error_handler_t eh, rspamd_http_router_finish_handler_t fh, struct timeval *timeout, - struct event_base *base, const char *default_fs_path, - struct rspamd_keypair_cache *cache); + struct rspamd_http_context *ctx); /** * Set encryption key for the HTTP router diff --git a/src/libutil/http_util.c b/src/libutil/http_util.c index 8e220adfa..8fb658e08 100644 --- a/src/libutil/http_util.c +++ b/src/libutil/http_util.c @@ -22,6 +22,272 @@ static const gchar *http_week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "S static const gchar *http_month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +/* + * Obtained from nginx + * Copyright (C) Igor Sysoev + */ +static guint mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +time_t +rspamd_http_parse_date (const gchar *header, gsize len) +{ + const gchar *p, *end; + gint month; + guint day, year, hour, min, sec; + guint64 time; + enum { + no = 0, rfc822, /* Tue, 10 Nov 2002 23:50:13 */ + rfc850, /* Tuesday, 10-Dec-02 23:50:13 */ + isoc /* Tue Dec 10 23:50:13 2002 */ + } fmt; + + fmt = 0; + if (len > 0) { + end = header + len; + } + else { + end = header + strlen (header); + } + + day = 32; + year = 2038; + + for (p = header; p < end; p++) { + if (*p == ',') { + break; + } + + if (*p == ' ') { + fmt = isoc; + break; + } + } + + for (p++; p < end; p++) + if (*p != ' ') { + break; + } + + if (end - p < 18) { + return (time_t)-1; + } + + if (fmt != isoc) { + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return (time_t)-1; + } + + day = (*p - '0') * 10 + *(p + 1) - '0'; + p += 2; + + if (*p == ' ') { + if (end - p < 18) { + return (time_t)-1; + } + fmt = rfc822; + + } + else if (*p == '-') { + fmt = rfc850; + + } + else { + return (time_t)-1; + } + + p++; + } + + switch (*p) { + + case 'J': + month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6; + break; + + case 'F': + month = 1; + break; + + case 'M': + month = *(p + 2) == 'r' ? 2 : 4; + break; + + case 'A': + month = *(p + 1) == 'p' ? 3 : 7; + break; + + case 'S': + month = 8; + break; + + case 'O': + month = 9; + break; + + case 'N': + month = 10; + break; + + case 'D': + month = 11; + break; + + default: + return (time_t)-1; + } + + p += 3; + + if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) { + return (time_t)-1; + } + + p++; + + if (fmt == rfc822) { + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' + || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0' + || *(p + 3) > '9') { + return (time_t)-1; + } + + year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 + + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; + p += 4; + + } + else if (fmt == rfc850) { + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return (time_t)-1; + } + + year = (*p - '0') * 10 + *(p + 1) - '0'; + year += (year < 70) ? 2000 : 1900; + p += 2; + } + + if (fmt == isoc) { + if (*p == ' ') { + p++; + } + + if (*p < '0' || *p > '9') { + return (time_t)-1; + } + + day = *p++ - '0'; + + if (*p != ' ') { + if (*p < '0' || *p > '9') { + return (time_t)-1; + } + + day = day * 10 + *p++ - '0'; + } + + if (end - p < 14) { + return (time_t)-1; + } + } + + if (*p++ != ' ') { + return (time_t)-1; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return (time_t)-1; + } + + hour = (*p - '0') * 10 + *(p + 1) - '0'; + p += 2; + + if (*p++ != ':') { + return (time_t)-1; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return (time_t)-1; + } + + min = (*p - '0') * 10 + *(p + 1) - '0'; + p += 2; + + if (*p++ != ':') { + return (time_t)-1; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return (time_t)-1; + } + + sec = (*p - '0') * 10 + *(p + 1) - '0'; + + if (fmt == isoc) { + p += 2; + + if (*p++ != ' ') { + return (time_t)-1; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' + || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0' + || *(p + 3) > '9') { + return (time_t)-1; + } + + year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 + + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; + } + + if (hour > 23 || min > 59 || sec > 59) { + return (time_t)-1; + } + + if (day == 29 && month == 1) { + if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) { + return (time_t)-1; + } + + } + else if (day > mday[month]) { + return (time_t)-1; + } + + /* + * shift new year to March 1 and start months from 1 (not 0), + * it is needed for Gauss' formula + */ + + if (--month <= 0) { + month += 12; + year -= 1; + } + + /* Gauss' formula for Gregorian days since March 1, 1 BC */ + + time = (guint64) ( + /* days in years including leap years since March 1, 1 BC */ + + 365 * year + year / 4 - year / 100 + year / 400 + + /* days before the month */ + + + 367 * month / 12 - 30 + + /* days before the day */ + + + day - 1 + + /* + * 719527 days were between March 1, 1 BC and March 1, 1970, + * 31 and 28 days were in January and February 1970 + */ + + - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec; + + return (time_t) time; +} + glong rspamd_http_date_format (gchar *buf, gsize len, time_t time) { diff --git a/src/libutil/map.c b/src/libutil/map.c index 9161ae68d..1413b2953 100644 --- a/src/libutil/map.c +++ b/src/libutil/map.c @@ -1277,12 +1277,11 @@ rspamd_map_dns_callback (struct rdns_reply *reply, void *arg) if (cbd->fd != -1) { cbd->stage = map_load_file; cbd->conn = rspamd_http_connection_new (NULL, + NULL, http_map_error, http_map_finish, flags, - RSPAMD_HTTP_CLIENT, - NULL, - cbd->map->cfg->libs_ctx->ssl_ctx); + RSPAMD_HTTP_CLIENT); write_http_request (cbd); } @@ -1649,13 +1648,13 @@ check: if (cbd->fd != -1) { cbd->stage = map_load_file; - cbd->conn = rspamd_http_connection_new (NULL, + cbd->conn = rspamd_http_connection_new ( + NULL, + NULL, http_map_error, http_map_finish, flags, - RSPAMD_HTTP_CLIENT, - NULL, - cbd->map->cfg->libs_ctx->ssl_ctx); + RSPAMD_HTTP_CLIENT); write_http_request (cbd); MAP_RELEASE (cbd, "http_callback_data"); diff --git a/src/libutil/util.c b/src/libutil/util.c index 68fbd5443..1f0c5fa70 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -2035,13 +2035,102 @@ void rspamd_gerror_free_maybe (gpointer p) } } + + +static void +rspamd_openssl_maybe_init (void) +{ + static gboolean openssl_initialized = FALSE; + + if (!openssl_initialized) { + ERR_load_crypto_strings (); + SSL_load_error_strings (); + + OpenSSL_add_all_algorithms (); + OpenSSL_add_all_digests (); + OpenSSL_add_all_ciphers (); + +#if OPENSSL_VERSION_NUMBER >= 0x1000104fL && !defined(LIBRESSL_VERSION_NUMBER) + ENGINE_load_builtin_engines (); +#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + SSL_library_init (); +#else + OPENSSL_init_ssl (0, NULL); +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + OPENSSL_config (NULL); +#endif + if (RAND_status () == 0) { + guchar seed[128]; + + /* Try to use ottery to seed rand */ + ottery_rand_bytes (seed, sizeof (seed)); + RAND_seed (seed, sizeof (seed)); + rspamd_explicit_memzero (seed, sizeof (seed)); + } + + openssl_initialized = TRUE; + } +} + +gpointer +rspamd_init_ssl_ctx (void) +{ + SSL_CTX *ssl_ctx; + gint ssl_options; + + rspamd_openssl_maybe_init (); + + ssl_ctx = SSL_CTX_new (SSLv23_method ()); + SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, NULL); + SSL_CTX_set_verify_depth (ssl_ctx, 4); + ssl_options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; + +#ifdef SSL_OP_NO_COMPRESSION + ssl_options |= SSL_OP_NO_COMPRESSION; +#elif OPENSSL_VERSION_NUMBER >= 0x00908000L + sk_SSL_COMP_zero (SSL_COMP_get_compression_methods ()); +#endif + + SSL_CTX_set_options (ssl_ctx, ssl_options); + + return ssl_ctx; +} + +gpointer rspamd_init_ssl_ctx_noverify (void) +{ + SSL_CTX *ssl_ctx_noverify; + gint ssl_options; + + rspamd_openssl_maybe_init (); + + ssl_options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; + +#ifdef SSL_OP_NO_COMPRESSION + ssl_options |= SSL_OP_NO_COMPRESSION; +#elif OPENSSL_VERSION_NUMBER >= 0x00908000L + sk_SSL_COMP_zero (SSL_COMP_get_compression_methods ()); +#endif + + ssl_ctx_noverify = SSL_CTX_new (SSLv23_method ()); + SSL_CTX_set_verify (ssl_ctx_noverify, SSL_VERIFY_NONE, NULL); + SSL_CTX_set_options (ssl_ctx_noverify, ssl_options); +#ifdef SSL_SESS_CACHE_BOTH + SSL_CTX_set_session_cache_mode (ssl_ctx_noverify, SSL_SESS_CACHE_BOTH); +#endif + + return ssl_ctx_noverify; +} + + struct rspamd_external_libs_ctx * rspamd_init_libs (void) { struct rlimit rlim; struct rspamd_external_libs_ctx *ctx; struct ottery_config *ottery_cfg; - gint ssl_options; ctx = g_malloc0 (sizeof (*ctx)); ctx->crypto_ctx = rspamd_cryptobox_init (); @@ -2049,10 +2138,15 @@ rspamd_init_libs (void) ottery_config_init (ottery_cfg); ctx->ottery_cfg = ottery_cfg; + rspamd_openssl_maybe_init (); + /* Check if we have rdrand */ if ((ctx->crypto_ctx->cpu_config & CPUID_RDRAND) == 0) { ottery_config_disable_entropy_sources (ottery_cfg, OTTERY_ENTROPY_SRC_RDRAND); +#if OPENSSL_VERSION_NUMBER >= 0x1000104fL && !defined(LIBRESSL_VERSION_NUMBER) + RAND_set_rand_engine (NULL); +#endif } g_assert (ottery_init (ottery_cfg) == 0); @@ -2072,60 +2166,8 @@ rspamd_init_libs (void) } #endif -#ifdef HAVE_OPENSSL - ERR_load_crypto_strings (); - SSL_load_error_strings (); - - OpenSSL_add_all_algorithms (); - OpenSSL_add_all_digests (); - OpenSSL_add_all_ciphers (); - -#if OPENSSL_VERSION_NUMBER >= 0x1000104fL && !defined(LIBRESSL_VERSION_NUMBER) - ENGINE_load_builtin_engines (); - - if ((ctx->crypto_ctx->cpu_config & CPUID_RDRAND) == 0) { - RAND_set_rand_engine (NULL); - } -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - SSL_library_init (); -#else - OPENSSL_init_ssl (0, NULL); -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - OPENSSL_config (NULL); -#endif - - if (RAND_poll () == 0) { - guchar seed[128]; - - /* Try to use ottery to seed rand */ - ottery_rand_bytes (seed, sizeof (seed)); - RAND_seed (seed, sizeof (seed)); - rspamd_explicit_memzero (seed, sizeof (seed)); - } - - ctx->ssl_ctx = SSL_CTX_new (SSLv23_method ()); - SSL_CTX_set_verify (ctx->ssl_ctx, SSL_VERIFY_PEER, NULL); - SSL_CTX_set_verify_depth (ctx->ssl_ctx, 4); - ssl_options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; - -#ifdef SSL_OP_NO_COMPRESSION - ssl_options |= SSL_OP_NO_COMPRESSION; -#elif OPENSSL_VERSION_NUMBER >= 0x00908000L - sk_SSL_COMP_zero (SSL_COMP_get_compression_methods ()); -#endif - - SSL_CTX_set_options (ctx->ssl_ctx, ssl_options); - ctx->ssl_ctx_noverify = SSL_CTX_new (SSLv23_method ()); - SSL_CTX_set_verify (ctx->ssl_ctx_noverify, SSL_VERIFY_NONE, NULL); - SSL_CTX_set_options (ctx->ssl_ctx_noverify, ssl_options); -#endif -#ifdef SSL_SESS_CACHE_BOTH - SSL_CTX_set_session_cache_mode (ctx->ssl_ctx, SSL_SESS_CACHE_BOTH); -#endif + ctx->ssl_ctx = rspamd_init_ssl_ctx (); + ctx->ssl_ctx_noverify = rspamd_init_ssl_ctx_noverify (); rspamd_random_seed_fast (); /* Set stack size for pcre */ diff --git a/src/libutil/util.h b/src/libutil/util.h index e97593d21..e9c1fa1db 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -349,6 +349,9 @@ struct rspamd_external_libs_ctx; */ struct rspamd_external_libs_ctx* rspamd_init_libs (void); +gpointer rspamd_init_ssl_ctx (void); +gpointer rspamd_init_ssl_ctx_noverify (void); + /** * Configure libraries */ -- 2.39.5