summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-07-16 18:21:51 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-07-16 18:21:51 +0100
commit80bbb6bf904499490d1d7879bbedbf46b0b7632d (patch)
tree1a62702dd1afcbc35cc23f1697c4bae89ca5e7b6 /src
parentc558398b7bfb8d5ceb1d4148130f8b39d438833d (diff)
downloadrspamd-80bbb6bf904499490d1d7879bbedbf46b0b7632d.tar.gz
rspamd-80bbb6bf904499490d1d7879bbedbf46b0b7632d.zip
[Rework] Stop support of signed HTTP maps to simplify code
Diffstat (limited to 'src')
-rw-r--r--src/libutil/map.c615
-rw-r--r--src/libutil/map_private.h16
-rw-r--r--src/lua/lua_map.c2
-rw-r--r--src/lua/lua_util.c2
4 files changed, 234 insertions, 401 deletions
diff --git a/src/libutil/map.c b/src/libutil/map.c
index 458d298dd..24dc2755a 100644
--- a/src/libutil/map.c
+++ b/src/libutil/map.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016 Vsevolod Stakhov
+ * Copyright 2019 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
/*
* Implementation of map files handling
*/
+
#include "config.h"
#include "map.h"
#include "map_private.h"
@@ -24,6 +25,7 @@
#include "rspamd.h"
#include "contrib/zstd/zstd.h"
#include "contrib/libev/ev.h"
+#include "contrib/uthash/utlist.h"
#undef MAP_DEBUG_REFS
#ifdef MAP_DEBUG_REFS
@@ -86,35 +88,20 @@ write_http_request (struct http_callback_data *cbd)
msg->method = HTTP_HEAD;
}
- if (cbd->stage == map_load_file) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
+ msg->url = rspamd_fstring_append (msg->url,
+ cbd->data->path, strlen (cbd->data->path));
- if (cbd->check && cbd->stage == map_load_file) {
- if (cbd->data->last_modified != 0) {
- rspamd_http_date_format (datebuf, sizeof (datebuf),
- cbd->data->last_modified);
- rspamd_http_message_add_header (msg, "If-Modified-Since",
- datebuf);
- }
- if (cbd->data->etag) {
- rspamd_http_message_add_header_len (msg, "If-None-Match",
- cbd->data->etag->str, cbd->data->etag->len);
- }
+ if (cbd->check) {
+ if (cbd->data->last_modified != 0) {
+ rspamd_http_date_format (datebuf, sizeof (datebuf),
+ cbd->data->last_modified);
+ rspamd_http_message_add_header (msg, "If-Modified-Since",
+ datebuf);
+ }
+ if (cbd->data->etag) {
+ rspamd_http_message_add_header_len (msg, "If-None-Match",
+ cbd->data->etag->str, cbd->data->etag->len);
}
- }
- else if (cbd->stage == map_load_pubkey) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
- msg->url = rspamd_fstring_append (msg->url, ".pub", 4);
- }
- else if (cbd->stage == map_load_signature) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
- msg->url = rspamd_fstring_append (msg->url, ".sig", 4);
- }
- else {
- g_assert_not_reached ();
}
msg->url = rspamd_fstring_append (msg->url, cbd->data->rest,
@@ -134,112 +121,6 @@ write_http_request (struct http_callback_data *cbd)
cbd->timeout);
}
-static gboolean
-rspamd_map_check_sig_pk_mem (const guchar *sig,
- gsize siglen,
- struct rspamd_map *map,
- const guchar *input,
- gsize inlen,
- struct rspamd_cryptobox_pubkey *pk)
-{
- GString *b32_key;
- gboolean ret = TRUE;
-
- if (siglen != rspamd_cryptobox_signature_bytes (RSPAMD_CRYPTOBOX_MODE_25519)) {
- msg_err_map ("can't open signature for %s: invalid size: %z", map->name, siglen);
-
- ret = FALSE;
- }
-
- if (ret && !rspamd_cryptobox_verify (sig, siglen, input, inlen,
- rspamd_pubkey_get_pk (pk, NULL), RSPAMD_CRYPTOBOX_MODE_25519)) {
- msg_err_map ("can't verify signature for %s: incorrect signature", map->name);
-
- ret = FALSE;
- }
-
- if (ret) {
- b32_key = rspamd_pubkey_print (pk,
- RSPAMD_KEYPAIR_BASE32|RSPAMD_KEYPAIR_PUBKEY);
- msg_info_map ("verified signature for %s using trusted key %v",
- map->name, b32_key);
- g_string_free (b32_key, TRUE);
- }
-
- return ret;
-}
-
-static gboolean
-rspamd_map_check_file_sig (const char *fname,
- struct rspamd_map *map,
- struct rspamd_map_backend *bk,
- const guchar *input,
- gsize inlen)
-{
- guchar *data;
- struct rspamd_cryptobox_pubkey *pk = NULL;
- GString *b32_key;
- gboolean ret = TRUE;
- gsize len = 0;
- gchar fpath[PATH_MAX];
-
- if (bk->trusted_pubkey == NULL) {
- /* Try to load and check pubkey */
- rspamd_snprintf (fpath, sizeof (fpath), "%s.pub", fname);
- data = rspamd_file_xmap (fpath, PROT_READ, &len, TRUE);
-
- if (data == NULL) {
- msg_err_map ("can't open pubkey %s: %s", fpath, strerror (errno));
- return FALSE;
- }
-
- pk = rspamd_pubkey_from_base32 (data, len, RSPAMD_KEYPAIR_SIGN,
- RSPAMD_CRYPTOBOX_MODE_25519);
- munmap (data, len);
-
- if (pk == NULL) {
- msg_err_map ("can't load pubkey %s", fpath);
- return FALSE;
- }
-
- /* We just check pk against the trusted db of keys */
- b32_key = rspamd_pubkey_print (pk,
- RSPAMD_KEYPAIR_BASE32|RSPAMD_KEYPAIR_PUBKEY);
- g_assert (b32_key != NULL);
-
- if (g_hash_table_lookup (map->cfg->trusted_keys, b32_key->str) == NULL) {
- msg_err_map ("pubkey loaded from %s is untrusted: %v", fpath,
- b32_key);
- g_string_free (b32_key, TRUE);
- rspamd_pubkey_unref (pk);
-
- return FALSE;
- }
-
- g_string_free (b32_key, TRUE);
- }
- else {
- pk = rspamd_pubkey_ref (bk->trusted_pubkey);
- }
-
- rspamd_snprintf (fpath, sizeof (fpath), "%s.sig", fname);
- data = rspamd_shmem_xmap (fpath, PROT_READ, &len);
-
- if (data == NULL) {
- msg_err_map ("can't open signature %s: %s", fpath, strerror (errno));
- ret = FALSE;
- }
-
- if (ret) {
- ret = rspamd_map_check_sig_pk_mem (data, len, map, input, inlen, pk);
- munmap (data, len);
- }
-
- rspamd_pubkey_unref (pk);
-
- return ret;
-}
-
/**
* Callback for destroying HTTP callback data
*/
@@ -248,14 +129,6 @@ free_http_cbdata_common (struct http_callback_data *cbd, gboolean plan_new)
{
struct map_periodic_cbdata *periodic = cbd->periodic;
- if (cbd->shmem_sig) {
- rspamd_http_message_shmem_unref (cbd->shmem_sig);
- }
-
- if (cbd->shmem_pubkey) {
- rspamd_http_message_shmem_unref (cbd->shmem_pubkey);
- }
-
if (cbd->shmem_data) {
rspamd_http_message_shmem_unref (cbd->shmem_data);
}
@@ -269,8 +142,15 @@ free_http_cbdata_common (struct http_callback_data *cbd, gboolean plan_new)
cbd->conn = NULL;
}
- if (cbd->addr) {
- rspamd_inet_address_free (cbd->addr);
+ if (cbd->addrs) {
+ rspamd_inet_addr_t *addr;
+ guint i;
+
+ PTR_ARRAY_FOREACH (cbd->addrs, i, addr) {
+ rspamd_inet_address_free (addr);
+ }
+
+ g_ptr_array_free (cbd->addrs, TRUE);
}
@@ -300,18 +180,17 @@ free_http_cbdata_dtor (gpointer p)
struct rspamd_map *map;
map = cbd->map;
- if (cbd->stage >= map_load_file) {
+ if (cbd->stage == http_map_http_conn) {
REF_RELEASE (cbd);
}
else {
/* We cannot terminate DNS requests sent */
- cbd->stage = map_finished;
+ cbd->stage = http_map_terminated;
}
msg_warn_map ("%s: "
- "connection with http server is terminated: worker is stopping",
+ "connection with http server is terminated: worker is stopping",
map->name);
-
}
/*
@@ -325,17 +204,22 @@ http_map_error (struct rspamd_http_connection *conn,
struct rspamd_map *map;
map = cbd->map;
- cbd->periodic->errored = TRUE;
- msg_err_map ("error reading %s(%s): "
- "connection with http server terminated incorrectly: %e",
- cbd->bk->uri,
- cbd->addr ? rspamd_inet_address_to_string_pretty (cbd->addr) : "",
- err);
- MAP_RETAIN (cbd->periodic, "periodic");
- rspamd_map_process_periodic (cbd->periodic);
- MAP_RELEASE (cbd->periodic, "periodic");
- /* Detach periodic as rspamd_map_process_periodic will destroy it */
- cbd->periodic = NULL;
+
+ if (cbd->periodic) {
+ cbd->periodic->errored = TRUE;
+ msg_err_map ("error reading %s(%s): "
+ "connection with http server terminated incorrectly: %e",
+ cbd->bk->uri,
+ cbd->addr ? rspamd_inet_address_to_string_pretty (cbd->addr) : "",
+ err);
+
+ MAP_RETAIN (cbd->periodic, "periodic");
+ rspamd_map_process_periodic (cbd->periodic);
+ MAP_RELEASE (cbd->periodic, "periodic");
+ /* Detach periodic as rspamd_map_process_periodic will destroy it */
+ cbd->periodic = NULL;
+ }
+
MAP_RELEASE (cbd, "http_callback_data");
}
@@ -390,61 +274,6 @@ rspamd_map_cache_cb (struct ev_loop *loop, ev_timer *w, int revents)
}
}
-static gboolean
-rspamd_http_check_pubkey (struct http_callback_data *cbd,
- struct rspamd_http_message *msg)
-{
- const rspamd_ftok_t *pubkey_hdr;
-
- pubkey_hdr = rspamd_http_message_find_header (msg, "Pubkey");
-
- if (pubkey_hdr) {
- cbd->pk = rspamd_pubkey_from_base32 (pubkey_hdr->begin,
- pubkey_hdr->len,
- RSPAMD_KEYPAIR_SIGN, RSPAMD_CRYPTOBOX_MODE_25519);
-
- return cbd->pk != NULL;
- }
-
- return FALSE;
-}
-
-static gboolean
-rspamd_http_check_signature (struct rspamd_map *map,
- struct http_callback_data *cbd,
- struct rspamd_http_message *msg)
-{
- const rspamd_ftok_t *sig_hdr;
- guchar *in;
- size_t dlen;
-
- sig_hdr = rspamd_http_message_find_header (msg, "Signature");
-
- if (sig_hdr && cbd->pk) {
- in = rspamd_shmem_xmap (cbd->shmem_data->shm_name, PROT_READ, &dlen);
-
- if (in == NULL) {
- msg_err_map ("cannot read tempfile %s: %s",
- cbd->shmem_data->shm_name,
- strerror (errno));
- return FALSE;
- }
-
- if (!rspamd_map_check_sig_pk_mem (sig_hdr->begin, sig_hdr->len,
- map, in,
- cbd->data_len, cbd->pk)) {
- munmap (in, dlen);
- return FALSE;
- }
-
- munmap (in, dlen);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
static int
http_map_finish (struct rspamd_http_connection *conn,
struct rspamd_http_message *msg)
@@ -456,8 +285,8 @@ http_map_finish (struct rspamd_http_connection *conn,
struct rspamd_http_map_cached_cbdata *cache_cbd;
const rspamd_ftok_t *expires_hdr, *etag_hdr;
char next_check_date[128];
- guchar *aux_data, *in = NULL;
- gsize inlen = 0, dlen = 0;
+ guchar *in = NULL;
+ gsize dlen = 0;
map = cbd->map;
bk = cbd->bk;
@@ -479,149 +308,20 @@ http_map_finish (struct rspamd_http_connection *conn,
return 0;
}
- if (cbd->stage == map_load_file) {
- cbd->data->last_checked = msg->date;
-
- if (msg->last_modified) {
- cbd->data->last_modified = msg->last_modified;
- }
- else {
- cbd->data->last_modified = msg->date;
- }
-
- /* Maybe we need to check signature ? */
- if (bk->is_signed) {
-
- cbd->shmem_data = rspamd_http_message_shmem_ref (msg);
- cbd->data_len = msg->body_buf.len;
-
- if (bk->trusted_pubkey) {
- /* No need to load key */
- cbd->pk = rspamd_pubkey_ref (bk->trusted_pubkey);
- cbd->stage = map_load_signature;
- }
- else {
- if (!rspamd_http_check_pubkey (cbd, msg)) {
- cbd->stage = map_load_pubkey;
- }
- else {
- cbd->stage = map_load_signature;
- }
- }
-
- if (cbd->stage == map_load_signature) {
- /* Try HTTP header */
- if (rspamd_http_check_signature (map, cbd, msg)) {
- goto read_data;
- }
- }
-
- rspamd_http_connection_unref (cbd->conn);
- cbd->conn = rspamd_http_connection_new_client (NULL,
- NULL,
- http_map_error,
- http_map_finish,
- RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_SHARED,
- cbd->addr);
- write_http_request (cbd);
- MAP_RELEASE (cbd, "http_callback_data");
-
- return 0;
- }
- else {
- /* Unsigned version - just open file */
- cbd->shmem_data = rspamd_http_message_shmem_ref (msg);
- cbd->data_len = msg->body_buf.len;
+ cbd->data->last_checked = msg->date;
- goto read_data;
- }
+ if (msg->last_modified) {
+ cbd->data->last_modified = msg->last_modified;
}
- else if (cbd->stage == map_load_pubkey) {
- /* We now can load pubkey */
- cbd->shmem_pubkey = rspamd_http_message_shmem_ref (msg);
- cbd->pubkey_len = msg->body_buf.len;
-
- aux_data = rspamd_shmem_xmap (cbd->shmem_pubkey->shm_name,
- PROT_READ, &inlen);
-
- if (aux_data == NULL) {
- msg_err_map ("cannot map pubkey file %s: %s",
- cbd->shmem_pubkey->shm_name, strerror (errno));
- goto err;
- }
-
- if (inlen < cbd->pubkey_len) {
- msg_err_map ("cannot map pubkey file %s: %s",
- cbd->shmem_pubkey->shm_name, strerror (errno));
- munmap (aux_data, inlen);
- goto err;
- }
-
- cbd->pk = rspamd_pubkey_from_base32 (aux_data, cbd->pubkey_len,
- RSPAMD_KEYPAIR_SIGN, RSPAMD_CRYPTOBOX_MODE_25519);
- munmap (aux_data, inlen);
-
- if (cbd->pk == NULL) {
- msg_err_map ("cannot load pubkey file %s: bad pubkey",
- cbd->shmem_pubkey->shm_name);
- goto err;
- }
-
- cbd->stage = map_load_signature;
- rspamd_http_connection_unref (cbd->conn);
- cbd->conn = rspamd_http_connection_new_client (NULL,
- NULL,
- http_map_error,
- http_map_finish,
- RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_SHARED,
- cbd->addr);
- write_http_request (cbd);
- MAP_RELEASE (cbd, "http_callback_data");
-
- return 0;
+ else {
+ cbd->data->last_modified = msg->date;
}
- else if (cbd->stage == map_load_signature) {
- /* We can now check signature */
- cbd->shmem_sig = rspamd_http_message_shmem_ref (msg);
- cbd->sig_len = msg->body_buf.len;
- aux_data = rspamd_shmem_xmap (cbd->shmem_sig->shm_name,
- PROT_READ, &inlen);
- if (aux_data == NULL) {
- msg_err_map ("cannot map signature file %s: %s",
- cbd->shmem_sig->shm_name, strerror (errno));
- goto err;
- }
-
- if (inlen < cbd->sig_len) {
- msg_err_map ("cannot map pubkey file %s: %s",
- cbd->shmem_pubkey->shm_name, strerror (errno));
- munmap (aux_data, inlen);
- goto err;
- }
-
- in = rspamd_shmem_xmap (cbd->shmem_data->shm_name, PROT_READ, &dlen);
-
- if (in == NULL) {
- msg_err_map ("cannot read tempfile %s: %s",
- cbd->shmem_data->shm_name,
- strerror (errno));
- munmap (aux_data, inlen);
- goto err;
- }
-
- if (!rspamd_map_check_sig_pk_mem (aux_data, cbd->sig_len, map, in,
- cbd->data_len, cbd->pk)) {
- munmap (aux_data, inlen);
- munmap (in, dlen);
- goto err;
- }
-
- munmap (in, dlen);
- }
+ /* Unsigned version - just open file */
+ cbd->shmem_data = rspamd_http_message_shmem_ref (msg);
+ cbd->data_len = msg->body_buf.len;
-read_data:
if (cbd->data_len == 0) {
msg_err_map ("cannot read empty map");
goto err;
@@ -788,7 +488,7 @@ read_data:
munmap (in, dlen);
rspamd_map_process_periodic (cbd->periodic);
}
- else if (msg->code == 304 && (cbd->check && cbd->stage == map_load_file)) {
+ else if (msg->code == 304 && cbd->check) {
cbd->data->last_checked = msg->date;
if (msg->last_modified) {
@@ -931,6 +631,111 @@ read_map_file_chunks (struct rspamd_map *map, struct map_cb_data *cbdata,
return TRUE;
}
+static gboolean
+rspamd_map_check_sig_pk_mem (const guchar *sig,
+ gsize siglen,
+ struct rspamd_map *map,
+ const guchar *input,
+ gsize inlen,
+ struct rspamd_cryptobox_pubkey *pk)
+{
+ GString *b32_key;
+ gboolean ret = TRUE;
+
+ if (siglen != rspamd_cryptobox_signature_bytes (RSPAMD_CRYPTOBOX_MODE_25519)) {
+ msg_err_map ("can't open signature for %s: invalid size: %z", map->name, siglen);
+
+ ret = FALSE;
+ }
+
+ if (ret && !rspamd_cryptobox_verify (sig, siglen, input, inlen,
+ rspamd_pubkey_get_pk (pk, NULL), RSPAMD_CRYPTOBOX_MODE_25519)) {
+ msg_err_map ("can't verify signature for %s: incorrect signature", map->name);
+
+ ret = FALSE;
+ }
+
+ if (ret) {
+ b32_key = rspamd_pubkey_print (pk,
+ RSPAMD_KEYPAIR_BASE32 | RSPAMD_KEYPAIR_PUBKEY);
+ msg_info_map ("verified signature for %s using trusted key %v",
+ map->name, b32_key);
+ g_string_free (b32_key, TRUE);
+ }
+
+ return ret;
+}
+
+static gboolean
+rspamd_map_check_file_sig (const char *fname,
+ struct rspamd_map *map,
+ struct rspamd_map_backend *bk,
+ const guchar *input,
+ gsize inlen) {
+ guchar *data;
+ struct rspamd_cryptobox_pubkey *pk = NULL;
+ GString *b32_key;
+ gboolean ret = TRUE;
+ gsize len = 0;
+ gchar fpath[PATH_MAX];
+
+ if (bk->trusted_pubkey == NULL) {
+ /* Try to load and check pubkey */
+ rspamd_snprintf (fpath, sizeof (fpath), "%s.pub", fname);
+ data = rspamd_file_xmap (fpath, PROT_READ, &len, TRUE);
+
+ if (data == NULL) {
+ msg_err_map ("can't open pubkey %s: %s", fpath, strerror (errno));
+ return FALSE;
+ }
+
+ pk = rspamd_pubkey_from_base32 (data, len, RSPAMD_KEYPAIR_SIGN,
+ RSPAMD_CRYPTOBOX_MODE_25519);
+ munmap (data, len);
+
+ if (pk == NULL) {
+ msg_err_map ("can't load pubkey %s", fpath);
+ return FALSE;
+ }
+
+ /* We just check pk against the trusted db of keys */
+ b32_key = rspamd_pubkey_print (pk,
+ RSPAMD_KEYPAIR_BASE32 | RSPAMD_KEYPAIR_PUBKEY);
+ g_assert (b32_key != NULL);
+
+ if (g_hash_table_lookup (map->cfg->trusted_keys, b32_key->str) == NULL) {
+ msg_err_map ("pubkey loaded from %s is untrusted: %v", fpath,
+ b32_key);
+ g_string_free (b32_key, TRUE);
+ rspamd_pubkey_unref (pk);
+
+ return FALSE;
+ }
+
+ g_string_free (b32_key, TRUE);
+ }
+ else {
+ pk = rspamd_pubkey_ref (bk->trusted_pubkey);
+ }
+
+ rspamd_snprintf (fpath, sizeof (fpath), "%s.sig", fname);
+ data = rspamd_shmem_xmap (fpath, PROT_READ, &len);
+
+ if (data == NULL) {
+ msg_err_map ("can't open signature %s: %s", fpath, strerror (errno));
+ ret = FALSE;
+ }
+
+ if (ret) {
+ ret = rspamd_map_check_sig_pk_mem (data, len, map, input, inlen, pk);
+ munmap (data, len);
+ }
+
+ rspamd_pubkey_unref (pk);
+
+ return ret;
+}
+
/**
* Callback for reading data from file
*/
@@ -1258,12 +1063,13 @@ static void
rspamd_map_dns_callback (struct rdns_reply *reply, void *arg)
{
struct http_callback_data *cbd = arg;
+ struct rdns_reply_entry *cur_rep;
struct rspamd_map *map;
guint flags = RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_SHARED;
map = cbd->map;
- if (cbd->stage == map_finished) {
+ if (cbd->stage == http_map_terminated) {
MAP_RELEASE (cbd, "http_callback_data");
return;
}
@@ -1273,35 +1079,31 @@ rspamd_map_dns_callback (struct rdns_reply *reply, void *arg)
* We just get the first address hoping that a resolver performs
* round-robin rotation well
*/
- if (cbd->addr == NULL) {
- cbd->addr = rspamd_inet_address_from_rnds (reply->entries);
-
- if (cbd->addr != NULL) {
- rspamd_inet_address_set_port (cbd->addr, cbd->data->port);
- cbd->conn = rspamd_http_connection_new_client (NULL,
- NULL,
- http_map_error,
- http_map_finish,
- flags,
- cbd->addr);
-
- if (cbd->conn != NULL) {
- cbd->stage = map_load_file;
- write_http_request (cbd);
- }
- else {
- rspamd_inet_address_free (cbd->addr);
- cbd->addr = NULL;
- }
+
+ DL_FOREACH (reply->entries, cur_rep) {
+ rspamd_inet_addr_t *addr;
+ addr = rspamd_inet_address_from_rnds (reply->entries);
+
+ if (addr != NULL) {
+ rspamd_inet_address_set_port (addr, cbd->data->port);
+ g_ptr_array_add (cbd->addrs, (void *)addr);
}
}
+
+ if (cbd->stage == http_map_resolve_host2) {
+ /* We have still one request pending */
+ cbd->stage = http_map_resolve_host1;
+ }
+ else if (cbd->stage == http_map_resolve_host1) {
+ cbd->stage = http_map_http_conn;
+ }
}
- else if (cbd->stage < map_load_file) {
- if (cbd->stage == map_resolve_host2) {
+ else if (cbd->stage < http_map_http_conn) {
+ if (cbd->stage == http_map_resolve_host2) {
/* We have still one request pending */
- cbd->stage = map_resolve_host1;
+ cbd->stage = http_map_resolve_host1;
}
- else {
+ else if (cbd->addrs->len == 0) {
/* We could not resolve host, so cowardly fail here */
msg_err_map ("cannot resolve %s: %s", cbd->data->host,
rdns_strerror (reply->code));
@@ -1310,6 +1112,25 @@ rspamd_map_dns_callback (struct rdns_reply *reply, void *arg)
}
}
+ if (cbd->stage == http_map_http_conn && cbd->addrs->len > 0) {
+ guint selected_addr_idx;
+
+ selected_addr_idx = rspamd_random_uint64_fast () % cbd->addrs->len;
+ cbd->addr = (rspamd_inet_addr_t *)g_ptr_array_index (cbd->addrs,
+ selected_addr_idx);
+
+ cbd->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ flags,
+ cbd->addr);
+
+ if (cbd->conn != NULL) {
+ write_http_request (cbd);
+ }
+ }
+
MAP_RELEASE (cbd, "http_callback_data");
}
@@ -1630,6 +1451,7 @@ check:
cbd = g_malloc0 (sizeof (struct http_callback_data));
cbd->event_loop = map->event_loop;
+ cbd->addrs = g_ptr_array_sized_new (4);
cbd->map = map;
cbd->data = data;
cbd->check = check;
@@ -1637,47 +1459,62 @@ check:
MAP_RETAIN (periodic, "periodic");
cbd->bk = bk;
MAP_RETAIN (bk, "rspamd_map_backend");
- cbd->stage = map_resolve_host2;
+ cbd->stage = http_map_terminated;
REF_INIT_RETAIN (cbd, free_http_cbdata);
msg_debug_map ("%s map data from %s", check ? "checking" : "reading",
data->host);
- /* Send both A and AAAA requests */
- if (rspamd_parse_inet_address (&cbd->addr, data->host, strlen (data->host))) {
- rspamd_inet_address_set_port (cbd->addr, cbd->data->port);
+
+ /* Try address */
+ rspamd_inet_addr_t *addr = NULL;
+
+ if (rspamd_parse_inet_address (&addr, data->host, strlen (data->host))) {
+ rspamd_inet_address_set_port (addr, cbd->data->port);
+ g_ptr_array_add (cbd->addrs, (void *)addr);
cbd->conn = rspamd_http_connection_new_client (
NULL,
NULL,
http_map_error,
http_map_finish,
flags,
- cbd->addr);
+ addr);
if (cbd->conn != NULL) {
- cbd->stage = map_load_file;
+ cbd->stage = http_map_http_conn;
write_http_request (cbd);
+ cbd->addr = addr;
MAP_RELEASE (cbd, "http_callback_data");
}
else {
msg_warn_map ("cannot load map: cannot connect to %s: %s",
data->host, strerror (errno));
- rspamd_inet_address_free (cbd->addr);
- cbd->addr = NULL;
MAP_RELEASE (cbd, "http_callback_data");
}
return;
}
else if (map->r->r) {
+ /* Send both A and AAAA requests */
+ guint nreq = 0;
+
if (rdns_make_request_full (map->r->r, rspamd_map_dns_callback, cbd,
map->cfg->dns_timeout, map->cfg->dns_retransmits, 1,
data->host, RDNS_REQUEST_A)) {
MAP_RETAIN (cbd, "http_callback_data");
+ nreq ++;
}
if (rdns_make_request_full (map->r->r, rspamd_map_dns_callback, cbd,
map->cfg->dns_timeout, map->cfg->dns_retransmits, 1,
data->host, RDNS_REQUEST_AAAA)) {
MAP_RETAIN (cbd, "http_callback_data");
+ nreq ++;
+ }
+
+ if (nreq == 2) {
+ cbd->stage = http_map_resolve_host2;
+ }
+ else if (nreq == 1) {
+ cbd->stage = http_map_resolve_host1;
}
map->tmp_dtor = free_http_cbdata_dtor;
@@ -2233,6 +2070,10 @@ rspamd_map_check_proto (struct rspamd_config *cfg,
return NULL;
}
+ if (bk->protocol != MAP_PROTO_FILE && bk->is_signed) {
+ msg_err_config ("signed maps are no longer supported for HTTP(s): %s", map_line);
+ }
+
return pos;
}
diff --git a/src/libutil/map_private.h b/src/libutil/map_private.h
index de84322ec..e285c8498 100644
--- a/src/libutil/map_private.h
+++ b/src/libutil/map_private.h
@@ -95,7 +95,6 @@ struct http_map_data {
gchar *path;
gchar *host;
gchar *rest;
- gchar *last_signature;
rspamd_fstring_t *etag;
time_t last_modified;
time_t last_checked;
@@ -163,12 +162,10 @@ struct rspamd_map {
};
enum rspamd_map_http_stage {
- map_resolve_host2 = 0, /* 2 requests sent */
- map_resolve_host1, /* 1 requests sent */
- map_load_file,
- map_load_pubkey,
- map_load_signature,
- map_finished
+ http_map_resolve_host2 = 0, /* 2 requests sent */
+ http_map_resolve_host1, /* 1 requests sent */
+ http_map_http_conn, /* http connection */
+ http_map_terminated /* terminated when doing resolving */
};
struct map_periodic_cbdata {
@@ -195,6 +192,7 @@ struct rspamd_http_file_data {
struct http_callback_data {
struct ev_loop *event_loop;
struct rspamd_http_connection *conn;
+ GPtrArray *addrs;
rspamd_inet_addr_t *addr;
struct rspamd_map *map;
struct rspamd_map_backend *bk;
@@ -202,11 +200,7 @@ struct http_callback_data {
struct map_periodic_cbdata *periodic;
struct rspamd_cryptobox_pubkey *pk;
struct rspamd_storage_shmem *shmem_data;
- struct rspamd_storage_shmem *shmem_sig;
- struct rspamd_storage_shmem *shmem_pubkey;
gsize data_len;
- gsize sig_len;
- gsize pubkey_len;
gboolean check;
enum rspamd_map_http_stage stage;
ev_tstamp timeout;
diff --git a/src/lua/lua_map.c b/src/lua/lua_map.c
index b28543c07..bead7ae4a 100644
--- a/src/lua/lua_map.c
+++ b/src/lua/lua_map.c
@@ -997,7 +997,7 @@ lua_map_is_signed (lua_State *L)
if (map->map) {
for (i = 0; i < map->map->backends->len; i ++) {
bk = g_ptr_array_index (map->map->backends, i);
- if (bk->is_signed) {
+ if (bk->is_signed && bk->protocol == MAP_PROTO_FILE) {
ret = TRUE;
break;
}
diff --git a/src/lua/lua_util.c b/src/lua/lua_util.c
index 7ff9d75f8..927ada2d4 100644
--- a/src/lua/lua_util.c
+++ b/src/lua/lua_util.c
@@ -1038,8 +1038,6 @@ lua_util_decode_base64 (lua_State *L)
struct rspamd_lua_text *t;
const gchar *s = NULL;
gsize inlen = 0, outlen;
- gint state = 0;
- guint save = 0;
if (lua_type (L, 1) == LUA_TSTRING) {
s = luaL_checklstring (L, 1, &inlen);