]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Adopt librspamdserver for http context
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 19 Feb 2019 17:56:42 +0000 (17:56 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 19 Feb 2019 17:56:42 +0000 (17:56 +0000)
src/libserver/rspamd_control.c
src/libutil/CMakeLists.txt
src/libutil/http_connection.c
src/libutil/http_connection.h
src/libutil/http_private.h
src/libutil/http_router.c
src/libutil/http_router.h
src/libutil/http_util.c
src/libutil/map.c
src/libutil/util.c
src/libutil/util.h

index 2fd1d983f2897677576bf3a093687a420feb07cb..fb0fc22b67b400e169c0d30810263423a0924b30 100644 (file)
@@ -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);
index 4d4f8c7bdd08db010b029b872f49a68d07e3d8df..f86d650f020d181351e1d71e70f1086f56f4bba2 100644 (file)
@@ -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
index df283f752a538fbc9fa46a1914d251fcaf34448a..8463ff76249831f32733b05382dc9283a28e0c12 100644 (file)
@@ -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);
 
index 1fa1170b2db68d9af1c414f17702b79abb7591d6..4e9f9f800d39c8eca001d8360081fe7ee858a77f 100644 (file)
@@ -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);
 
 
 /**
index df1233d8b95740b0150377b4d34ff224404dd185..0f8c847a2d34f27402b36149c2f2e8ec5807c230 100644 (file)
@@ -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);
 
index 0dc597788107ee3e38986ff84ffdfe2b6cf5b9bd..be45c4351548568dafd27bfb34d66550c4241eaf 100644 (file)
@@ -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);
                }
index 7440c519ea29174ef56bd6bc417e5ffc60f75b1a..8e805624018648cbfff7ec3dda41b314cc698618 100644 (file)
@@ -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
index 8e220adfa5cb645e0936becdb76df1c5a4f31447..8fb658e08d85665a092f20b391f151405db19696 100644 (file)
@@ -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)
 {
index 9161ae68d77c4883362c9ce39540d86479d2ac66..1413b2953be4ffa48dc925fb1f9d004e260c8795 100644 (file)
@@ -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");
index 68fbd544350629f88e8de946dd85b5a835cf3c44..1f0c5fa705ff48a958808cb740e0e597a352b24a 100644 (file)
@@ -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 */
index e97593d2151e960123940eebca11ce1df511db3b..e9c1fa1dbc7a1aa24e9bffaee6d999274dfcab76 100644 (file)
@@ -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
  */