From 4b6905c2a2585eaf83cb0d9a7e34d73622add7d3 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 15 Feb 2016 14:37:34 +0000 Subject: [PATCH] Start reworking of maps --- src/controller.c | 1 + src/libserver/cfg_utils.c | 1 + src/libutil/map.c | 126 +++++++++++++++++++------------------- src/libutil/map.h | 29 +-------- src/libutil/map_private.h | 83 +++++++++++++++++++++++++ 5 files changed, 150 insertions(+), 90 deletions(-) create mode 100644 src/libutil/map_private.h diff --git a/src/controller.c b/src/controller.c index 59388ba1b..8e230eb0f 100644 --- a/src/controller.c +++ b/src/controller.c @@ -17,6 +17,7 @@ #include "libserver/dynamic_cfg.h" #include "libutil/rrd.h" #include "libutil/map.h" +#include "libutil/map_private.h" #include "libstat/stat_api.h" #include "rspamd.h" #include "libserver/worker_util.h" diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index eba9d66d9..5bd4c0668 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -21,6 +21,7 @@ #include "filter.h" #include "lua/lua_common.h" #include "map.h" +#include "map_private.h" #include "dynamic_cfg.h" #include "utlist.h" #include "stat_api.h" diff --git a/src/libutil/map.c b/src/libutil/map.c index 7d21e2f26..44048d743 100644 --- a/src/libutil/map.c +++ b/src/libutil/map.c @@ -18,6 +18,7 @@ */ #include "config.h" #include "map.h" +#include "map_private.h" #include "http.h" #include "rspamd.h" #include "cryptobox.h" @@ -25,40 +26,6 @@ static const gchar *hash_fill = "1"; -/** - * Data specific to file maps - */ -struct file_map_data { - const gchar *filename; - struct stat st; -}; - -/** - * Data specific to HTTP maps - */ -struct http_map_data { - struct addrinfo *addr; - guint16 port; - gchar *path; - gchar *host; - time_t last_checked; - gboolean request_sent; - struct rspamd_http_connection *conn; -}; - - -struct http_callback_data { - struct event_base *ev_base; - struct timeval tv; - struct rspamd_map *map; - struct http_map_data *data; - struct map_cb_data cbdata; - - GString *remain_buf; - - gint fd; -}; - /* Value in seconds after whitch we would try to do stat on list file */ /* HTTP timeouts */ @@ -441,33 +408,74 @@ rspamd_map_remove_all (struct rspamd_config *cfg) } } -gboolean -rspamd_map_check_proto (const gchar *map_line, gint *res, const gchar **pos) +static const gchar * +rspamd_map_check_proto (struct rspamd_config *cfg, + const gchar *map_line, struct rspamd_map *map) { - g_assert (res != NULL); + const gchar *pos = map_line, *end; + + g_assert (map != NULL); g_assert (pos != NULL); - if (g_ascii_strncasecmp (map_line, "http://", + end = pos + strlen (pos); + + if (g_ascii_strncasecmp (pos, "sign+", sizeof ("sign+") - 1) == 0) { + map->is_signed = TRUE; + pos += sizeof ("sign+") - 1; + } + + if (g_ascii_strncasecmp (pos, "key=", sizeof ("key=") - 1) == 0) { + pos += sizeof ("key=") - 1; + + if (end - pos > 64) { + map->trusted_pubkey = rspamd_pubkey_from_hex (pos, 64, + RSPAMD_KEYPAIR_SIGN, RSPAMD_CRYPTOBOX_MODE_25519); + + if (map->trusted_pubkey == NULL) { + msg_err_config ("cannot read pubkey from map: %s", + map_line); + return NULL; + } + } + else { + msg_err_config ("cannot read pubkey from map: %s", + map_line); + return NULL; + } + + pos += 64; + + if (*pos == '+' || *pos == ':') { + pos ++; + } + } + + if (g_ascii_strncasecmp (pos, "http://", sizeof ("http://") - 1) == 0) { - *res = MAP_PROTO_HTTP; - *pos = map_line + sizeof ("http://") - 1; + map->protocol = MAP_PROTO_HTTP; + /* Include http:// */ + map->uri = rspamd_mempool_strdup (cfg->cfg_pool, pos); + pos += sizeof ("http://") - 1; } - else if (g_ascii_strncasecmp (map_line, "file://", sizeof ("file://") - + else if (g_ascii_strncasecmp (pos, "file://", sizeof ("file://") - 1) == 0) { - *res = MAP_PROTO_FILE; - *pos = map_line + sizeof ("file://") - 1; + map->protocol = MAP_PROTO_FILE; + pos += sizeof ("file://") - 1; + /* Exclude file:// */ + map->uri = rspamd_mempool_strdup (cfg->cfg_pool, pos); } - else if (*map_line == '/') { + else if (*pos == '/') { /* Trivial file case */ - *res = MAP_PROTO_FILE; - *pos = map_line; + map->protocol = MAP_PROTO_FILE; + map->uri = rspamd_mempool_strdup (cfg->cfg_pool, pos); } else { - msg_debug ("invalid map fetching protocol: %s", map_line); - return FALSE; + msg_err_config ("invalid map fetching protocol: %s", map_line); + return NULL; } - return TRUE; + + return pos; } gboolean @@ -488,11 +496,6 @@ rspamd_map_add (struct rspamd_config *cfg, struct addrinfo hints, *res; rspamd_mempool_t *pool; - /* First of all detect protocol line */ - if (!rspamd_map_check_proto (map_line, (int *)&proto, &def)) { - return FALSE; - } - /* Constant pool */ if (cfg->map_pool == NULL) { cfg->map_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "map"); @@ -501,22 +504,21 @@ rspamd_map_add (struct rspamd_config *cfg, } new_map = rspamd_mempool_alloc0 (cfg->map_pool, sizeof (struct rspamd_map)); + + /* First of all detect protocol line */ + if (rspamd_map_check_proto (cfg, map_line, new_map) == NULL) { + return FALSE; + } + new_map->read_callback = read_callback; new_map->fin_callback = fin_callback; new_map->user_data = user_data; - new_map->protocol = proto; new_map->cfg = cfg; new_map->id = g_random_int (); new_map->locked = rspamd_mempool_alloc0_shared (cfg->cfg_pool, sizeof (gint)); + def = new_map->uri; - if (proto == MAP_PROTO_FILE) { - new_map->uri = rspamd_mempool_strdup (cfg->cfg_pool, def); - def = new_map->uri; - } - else { - new_map->uri = rspamd_mempool_strdup (cfg->cfg_pool, map_line); - } if (description != NULL) { new_map->description = rspamd_mempool_strdup (cfg->cfg_pool, description); diff --git a/src/libutil/map.h b/src/libutil/map.h index 95c7de27b..13590581e 100644 --- a/src/libutil/map.h +++ b/src/libutil/map.h @@ -12,11 +12,6 @@ * It monitor files and HTTP locations for modifications and reload them if they are * modified. */ - -enum fetch_proto { - MAP_PROTO_FILE, - MAP_PROTO_HTTP, -}; struct map_cb_data; /** @@ -30,24 +25,7 @@ typedef void (*map_fin_cb_t)(rspamd_mempool_t *pool, struct map_cb_data *data); * Common map object */ struct rspamd_config; -struct rspamd_map { - rspamd_mempool_t *pool; - struct rspamd_config *cfg; - enum fetch_proto protocol; - map_cb_t read_callback; - map_fin_cb_t fin_callback; - void **user_data; - struct event ev; - struct timeval tv; - struct event_base *ev_base; - void *map_data; - gchar *uri; - gchar *description; - guint32 id; - guint32 checksum; - /* Shared lock for temporary disabling of map reading (e.g. when this map is written by UI) */ - gint *locked; -}; +struct rspamd_map; /** * Callback data for async load @@ -59,11 +37,6 @@ struct map_cb_data { void *cur_data; }; - -/** - * Check map protocol - */ -gboolean rspamd_map_check_proto (const gchar *map_line, gint *res, const gchar **pos); /** * Add map from line */ diff --git a/src/libutil/map_private.h b/src/libutil/map_private.h new file mode 100644 index 000000000..39a546de6 --- /dev/null +++ b/src/libutil/map_private.h @@ -0,0 +1,83 @@ +/*- + * Copyright 2016 Vsevolod Stakhov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SRC_LIBUTIL_MAP_PRIVATE_H_ +#define SRC_LIBUTIL_MAP_PRIVATE_H_ + +#include "config.h" +#include "mem_pool.h" +#include "keypair.h" +#include "unix-std.h" + +enum fetch_proto { + MAP_PROTO_FILE, + MAP_PROTO_HTTP, +}; +struct rspamd_map { + rspamd_mempool_t *pool; + gboolean is_signed; + struct rspamd_cryptobox_pubkey *trusted_pubkey; + struct rspamd_config *cfg; + enum fetch_proto protocol; + map_cb_t read_callback; + map_fin_cb_t fin_callback; + void **user_data; + struct event ev; + struct timeval tv; + struct event_base *ev_base; + void *map_data; + gchar *uri; + gchar *description; + guint32 id; + guint32 checksum; + /* Shared lock for temporary disabling of map reading (e.g. when this map is written by UI) */ + gint *locked; +}; + +/** + * Data specific to file maps + */ +struct file_map_data { + const gchar *filename; + struct stat st; +}; + +/** + * Data specific to HTTP maps + */ +struct http_map_data { + struct addrinfo *addr; + guint16 port; + gchar *path; + gchar *host; + time_t last_checked; + gboolean request_sent; + struct rspamd_http_connection *conn; +}; + + +struct http_callback_data { + struct event_base *ev_base; + struct timeval tv; + struct rspamd_map *map; + struct http_map_data *data; + struct map_cb_data cbdata; + + GString *remain_buf; + + gint fd; +}; + +#endif /* SRC_LIBUTIL_MAP_PRIVATE_H_ */ -- 2.39.5