diff options
-rw-r--r-- | src/libcryptobox/base64/ref.c | 2 | ||||
-rw-r--r-- | src/libserver/symbols_cache.c | 88 | ||||
-rw-r--r-- | src/lua/lua_cryptobox.c | 187 | ||||
-rw-r--r-- | src/lua/lua_dns_resolver.c | 5 | ||||
-rw-r--r-- | src/lua/lua_redis.c | 4 | ||||
-rw-r--r-- | src/lua/lua_task.c | 6 | ||||
-rw-r--r-- | src/plugins/fuzzy_check.c | 18 | ||||
-rw-r--r-- | src/plugins/lua/antivirus.lua | 4 | ||||
-rw-r--r-- | src/plugins/surbl.c | 11 |
9 files changed, 283 insertions, 42 deletions
diff --git a/src/libcryptobox/base64/ref.c b/src/libcryptobox/base64/ref.c index 797a91ce7..6d3c295f1 100644 --- a/src/libcryptobox/base64/ref.c +++ b/src/libcryptobox/base64/ref.c @@ -214,7 +214,7 @@ repeat: } if (!ret && inlen > 0) { - /* Skip to the next valid character in input */ + /* Skip to the next valid character in lua_dns_resolver_resolve_commoninput */ while (inlen > 0 && base64_table_dec[*c] >= 254) { c ++; inlen --; diff --git a/src/libserver/symbols_cache.c b/src/libserver/symbols_cache.c index 9747a45d4..960171e1c 100644 --- a/src/libserver/symbols_cache.c +++ b/src/libserver/symbols_cache.c @@ -49,14 +49,14 @@ INIT_LOG_MODULE(symcache) #define CHECK_START_BIT(checkpoint, item) \ - isset((checkpoint)->processed_bits, (item)->id * 2) + isset((checkpoint)->started_bits, (item)->id) #define SET_START_BIT(checkpoint, item) \ - setbit((checkpoint)->processed_bits, (item)->id * 2) + setbit((checkpoint)->started_bits, (item)->id ) #define CHECK_FINISH_BIT(checkpoint, item) \ - isset((checkpoint)->processed_bits, (item)->id * 2 + 1) + isset((checkpoint)->finished_bits, (item)->id) #define SET_FINISH_BIT(checkpoint, item) \ - setbit((checkpoint)->processed_bits, (item)->id * 2 + 1) + setbit((checkpoint)->finished_bits, (item)->id) static const guchar rspamd_symbols_cache_magic[8] = {'r', 's', 'c', 2, 0, 0, 0, 0 }; @@ -173,13 +173,15 @@ enum rspamd_cache_savepoint_stage { }; struct cache_savepoint { - guchar *processed_bits; + guchar *started_bits; + guchar *finished_bits; enum rspamd_cache_savepoint_stage pass; guint version; struct rspamd_metric_result *rs; gdouble lim; struct rspamd_symcache_item *cur_item; guint items_inflight; + guint last_elt; struct symbols_cache_order *order; }; @@ -1510,9 +1512,10 @@ rspamd_symbols_cache_make_checkpoint (struct rspamd_task *task, } checkpoint = rspamd_mempool_alloc0 (task->task_pool, sizeof (*checkpoint)); - /* Bit 0: check started, Bit 1: check finished */ - checkpoint->processed_bits = rspamd_mempool_alloc0 (task->task_pool, - NBYTES (cache->used_items) * 2); + checkpoint->started_bits = rspamd_mempool_alloc0 (task->task_pool, + NBYTES (cache->used_items)); + checkpoint->finished_bits = rspamd_mempool_alloc0 (task->task_pool, + NBYTES (cache->used_items)); g_assert (cache->items_by_order != NULL); checkpoint->version = cache->items_by_order->d->len; checkpoint->order = cache->items_by_order; @@ -1663,7 +1666,7 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, saved_priority = G_MININT; all_done = TRUE; - for (i = 0; i < (gint)cache->prefilters->len; i ++) { + for (i = checkpoint->last_elt; i < (gint)cache->prefilters->len; i ++) { item = g_ptr_array_index (cache->prefilters, i); if (RSPAMD_TASK_IS_SKIPPED (task)) { @@ -1684,6 +1687,8 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, * priority filters to be processed */ checkpoint->pass = RSPAMD_CACHE_PASS_PREFILTERS; + checkpoint->last_elt = i; + return TRUE; } } @@ -1696,9 +1701,12 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, if (all_done || stage == RSPAMD_TASK_STAGE_FILTERS) { checkpoint->pass = RSPAMD_CACHE_PASS_FILTERS; + checkpoint->last_elt = 0; } if (stage == RSPAMD_TASK_STAGE_FILTERS) { + checkpoint->last_elt = 0; + return rspamd_symbols_cache_process_symbols (task, cache, stage); } @@ -1712,7 +1720,7 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, */ all_done = TRUE; - for (i = 0; i < (gint)checkpoint->version; i ++) { + for (i = checkpoint->last_elt; i < (gint)checkpoint->version; i ++) { if (RSPAMD_TASK_IS_SKIPPED (task)) { return TRUE; } @@ -1723,16 +1731,6 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, continue; } - if (!(item->type & SYMBOL_TYPE_FINE)) { - if (rspamd_symbols_cache_metric_limit (task, checkpoint)) { - msg_info_task ("<%s> has already scored more than %.2f, so do " - "not " - "plan more checks", task->message_id, - checkpoint->rs->score); - continue; - } - } - if (!CHECK_START_BIT (checkpoint, item)) { all_done = FALSE; @@ -1743,19 +1741,37 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, "resolved", item->id, item->symbol); + if (checkpoint->last_elt == 0) { + checkpoint->last_elt = i; + } + continue; } rspamd_symbols_cache_check_symbol (task, cache, item, checkpoint); } + + if (!(item->type & SYMBOL_TYPE_FINE)) { + if (rspamd_symbols_cache_metric_limit (task, checkpoint)) { + msg_info_task ("<%s> has already scored more than %.2f, so do " + "not " + "plan more checks", task->message_id, + checkpoint->rs->score); + all_done = TRUE; + break; + } + } } if (all_done || stage == RSPAMD_TASK_STAGE_POST_FILTERS) { checkpoint->pass = RSPAMD_CACHE_PASS_POSTFILTERS; + checkpoint->last_elt = 0; } if (stage == RSPAMD_TASK_STAGE_POST_FILTERS) { + checkpoint->last_elt = 0; + return rspamd_symbols_cache_process_symbols (task, cache, stage); } @@ -1766,7 +1782,7 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, saved_priority = G_MININT; all_done = TRUE; - for (i = 0; i < (gint)cache->postfilters->len; i ++) { + for (i = checkpoint->last_elt; i < (gint)cache->postfilters->len; i ++) { if (RSPAMD_TASK_IS_SKIPPED (task)) { return TRUE; } @@ -1789,6 +1805,8 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, * priority filters to be processed */ checkpoint->pass = RSPAMD_CACHE_PASS_POSTFILTERS; + checkpoint->last_elt = i; + return TRUE; } } @@ -1800,14 +1818,18 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, if (all_done) { checkpoint->pass = RSPAMD_CACHE_PASS_IDEMPOTENT; + checkpoint->last_elt = 0; } if (checkpoint->items_inflight == 0 || stage == RSPAMD_TASK_STAGE_IDEMPOTENT) { checkpoint->pass = RSPAMD_CACHE_PASS_IDEMPOTENT; + checkpoint->last_elt = 0; } if (stage == RSPAMD_TASK_STAGE_IDEMPOTENT) { + checkpoint->last_elt = 0; + return rspamd_symbols_cache_process_symbols (task, cache, stage); } @@ -1817,7 +1839,7 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, /* Check for postfilters */ saved_priority = G_MININT; - for (i = 0; i < (gint)cache->idempotent->len; i ++) { + for (i = checkpoint->last_elt; i < (gint)cache->idempotent->len; i ++) { item = g_ptr_array_index (cache->idempotent, i); if (!CHECK_START_BIT (checkpoint, item) && @@ -1834,6 +1856,8 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, * priority filters to be processed */ checkpoint->pass = RSPAMD_CACHE_PASS_IDEMPOTENT; + checkpoint->last_elt = i; + return TRUE; } } @@ -2266,8 +2290,10 @@ rspamd_symbols_cache_disable_all_symbols (struct rspamd_task *task, } /* Set all symbols as started + finished to disable their execution */ - memset (checkpoint->processed_bits, 0xff, - NBYTES (cache->used_items) * 2); + memset (checkpoint->started_bits, 0xff, + NBYTES (cache->used_items)); + memset (checkpoint->finished_bits, 0xff, + NBYTES (cache->used_items)); } static void @@ -2329,8 +2355,8 @@ rspamd_symbols_cache_enable_symbol_checkpoint (struct rspamd_task *task, /* Set executed and finished flags */ item = g_ptr_array_index (cache->items_by_id, id); - clrbit (checkpoint->processed_bits, item->id * 2); - clrbit (checkpoint->processed_bits, item->id * 2 + 1); + clrbit (checkpoint->started_bits, item->id); + clrbit (checkpoint->finished_bits, item->id); msg_debug_cache_task ("enable execution of %s (%d)", symbol, id); } @@ -2401,7 +2427,7 @@ rspamd_symbols_cache_is_checked (struct rspamd_task *task, checkpoint = task->checkpoint; if (checkpoint) { - return isset (checkpoint->processed_bits, id * 2); + return isset (checkpoint->started_bits, id); } return FALSE; @@ -2640,8 +2666,8 @@ guint rspamd_symcache_item_async_inc (struct rspamd_task *task, struct rspamd_symcache_item *item) { - msg_debug_cache_task ("increase async events counter for %s = %d + 1", - item->symbol, item->async_events); + msg_debug_cache_task ("increase async events counter for %s(%d) = %d + 1", + item->symbol, item->id, item->async_events); return ++item->async_events; } @@ -2649,8 +2675,8 @@ guint rspamd_symcache_item_async_dec (struct rspamd_task *task, struct rspamd_symcache_item *item) { - msg_debug_cache_task ("decrease async events counter for %s = %d - 1", - item->symbol, item->async_events); + msg_debug_cache_task ("decrease async events counter for %s(%d) = %d - 1", + item->symbol, item->id, item->async_events); g_assert (item->async_events > 0); return --item->async_events; diff --git a/src/lua/lua_cryptobox.c b/src/lua/lua_cryptobox.c index cda4912de..5f367ae04 100644 --- a/src/lua/lua_cryptobox.c +++ b/src/lua/lua_cryptobox.c @@ -26,11 +26,13 @@ * print(h:hex()) */ + #include "lua_common.h" #include "libcryptobox/cryptobox.h" #include "libcryptobox/keypair.h" #include "libcryptobox/keypair_private.h" #include "unix-std.h" +#include "contrib/libottery/ottery.h" struct rspamd_lua_cryptobox_hash { rspamd_cryptobox_hash_state_t *h; @@ -75,6 +77,8 @@ LUA_FUNCTION_DEF (cryptobox, encrypt_memory); LUA_FUNCTION_DEF (cryptobox, encrypt_file); LUA_FUNCTION_DEF (cryptobox, decrypt_memory); LUA_FUNCTION_DEF (cryptobox, decrypt_file); +LUA_FUNCTION_DEF (cryptobox, encrypt_cookie); +LUA_FUNCTION_DEF (cryptobox, decrypt_cookie); static const struct luaL_reg cryptoboxlib_f[] = { LUA_INTERFACE_DEF (cryptobox, verify_memory), @@ -85,6 +89,8 @@ static const struct luaL_reg cryptoboxlib_f[] = { LUA_INTERFACE_DEF (cryptobox, encrypt_file), LUA_INTERFACE_DEF (cryptobox, decrypt_memory), LUA_INTERFACE_DEF (cryptobox, decrypt_file), + LUA_INTERFACE_DEF (cryptobox, encrypt_cookie), + LUA_INTERFACE_DEF (cryptobox, decrypt_cookie), {NULL, NULL} }; @@ -1822,6 +1828,187 @@ lua_cryptobox_decrypt_file (lua_State *L) return 2; } +#define RSPAMD_CRYPTOBOX_AES_BLOCKSIZE 16 +#define RSPAMD_CRYPTOBOX_AES_KEYSIZE 16 + +/*** + * @function rspamd_cryptobox.encrypt_cookie(secret_key, secret_cookie) + * Specialised function that performs AES-CTR encryption of the provided cookie + * e := base64(nonce||aesencrypt(nonce, secret_cookie)) + * nonce := int64_le(unix_timestamp)||random_64bit + * aesencrypt := aes_ctr(nonce, secret_key) ^ pad(secret_cookie) + * pad := secret_cookie || 0^(32-len(secret_cookie)) + * @param {string} secret_key secret key as a hex string (must be 16 bytes in raw or 32 in hex) + * @param {string} secret_cookie secret cookie as a string for up to 31 character + * @return {string} e function value for this sk and cookie + */ +static gint +lua_cryptobox_encrypt_cookie (lua_State *L) +{ + guchar aes_block[RSPAMD_CRYPTOBOX_AES_BLOCKSIZE], *blk; + guchar padded_cookie[RSPAMD_CRYPTOBOX_AES_BLOCKSIZE]; + guchar nonce[RSPAMD_CRYPTOBOX_AES_BLOCKSIZE]; + guchar aes_key[RSPAMD_CRYPTOBOX_AES_KEYSIZE]; + guchar result[RSPAMD_CRYPTOBOX_AES_BLOCKSIZE * 2]; + guint64 ts; + + const gchar *sk, *cookie; + gsize sklen, cookie_len; + gint bklen; + + sk = lua_tolstring (L, 1, &sklen); + cookie = lua_tolstring (L, 2, &cookie_len); + + if (sk && cookie) { + if (sklen == 32) { + /* Hex */ + rspamd_decode_hex_buf (sk, sklen, aes_key, sizeof (aes_key)); + } + else if (sklen == RSPAMD_CRYPTOBOX_AES_KEYSIZE) { + /* Raw */ + memcpy (aes_key, sk, sizeof (aes_key)); + } + else { + return luaL_error (L, "invalid keysize %d", (gint)sklen); + } + + if (cookie_len > sizeof (padded_cookie) - 1) { + return luaL_error (L, "cookie is too long %d", (gint)padded_cookie); + } + + /* Fill nonce */ + ottery_rand_bytes (nonce, sizeof (nonce) / 2); + ts = (guint64)rspamd_get_calendar_ticks (); + memcpy (nonce + sizeof (nonce) / 2, &ts, sizeof (ts)); + + /* Prepare padded cookie */ + memset (padded_cookie, 0, sizeof (padded_cookie)); + memcpy (padded_cookie, cookie, cookie_len); + + /* Perform AES CTR via AES ECB on nonce */ + EVP_CIPHER_CTX *ctx; + ctx = EVP_CIPHER_CTX_new (); + EVP_EncryptInit_ex (ctx, EVP_aes_128_ecb (), NULL, aes_key, NULL); + EVP_CIPHER_CTX_set_padding (ctx, 0); + + bklen = sizeof (aes_block); + blk = aes_block; + g_assert (EVP_EncryptUpdate (ctx, blk, &bklen, nonce, sizeof (nonce))); + blk += bklen; + g_assert (EVP_EncryptFinal_ex(ctx, blk, &bklen)); + EVP_CIPHER_CTX_free (ctx); + + /* Encode result */ + memcpy (result, nonce, sizeof (nonce)); + for (guint i = 0; i < sizeof (aes_block); i ++) { + result[i + sizeof (nonce)] = padded_cookie[i] ^ aes_block[i]; + } + + gsize rlen; + gchar *res = rspamd_encode_base64 (result, sizeof (result), + 0, &rlen); + + lua_pushlstring (L, res, rlen); + g_free (res); + rspamd_explicit_memzero (aes_key, sizeof (aes_key)); + rspamd_explicit_memzero (aes_block, sizeof (aes_block)); + } + else { + return luaL_error (L, "invalid arguments"); + } + + return 1; +} + +/*** + * @function rspamd_cryptobox.decrypt_cookie(secret_key, encrypted_cookie) + * Specialised function that performs AES-CTR decryption of the provided cookie in form + * e := base64(nonce||aesencrypt(nonce, secret_cookie)) + * nonce := int64_le(unix_timestamp)||random_64bit + * aesencrypt := aes_ctr(nonce, secret_key) ^ pad(secret_cookie) + * pad := secret_cookie || 0^(32-len(secret_cookie)) + * @param {string} secret_key secret key as a hex string (must be 16 bytes in raw or 32 in hex) + * @param {string} encrypted_cookie encrypted cookie as a base64 encoded string + * @return {string} decrypted value of the cookie + */ +static gint +lua_cryptobox_decrypt_cookie (lua_State *L) +{ + guchar *blk; + guchar nonce[RSPAMD_CRYPTOBOX_AES_BLOCKSIZE]; + guchar aes_key[RSPAMD_CRYPTOBOX_AES_KEYSIZE]; + guchar *src; + guint64 ts; + + const gchar *sk, *cookie; + gsize sklen, cookie_len; + gint bklen; + + sk = lua_tolstring (L, 1, &sklen); + cookie = lua_tolstring (L, 2, &cookie_len); + + if (sk && cookie) { + if (sklen == 32) { + /* Hex */ + rspamd_decode_hex_buf (sk, sklen, aes_key, sizeof (aes_key)); + } + else if (sklen == RSPAMD_CRYPTOBOX_AES_KEYSIZE) { + /* Raw */ + memcpy (aes_key, sk, sizeof (aes_key)); + } + else { + return luaL_error (L, "invalid keysize %d", (gint)sklen); + } + + src = g_malloc (cookie_len); + + rspamd_cryptobox_base64_decode (cookie, cookie_len, src, &cookie_len); + + if (cookie_len != RSPAMD_CRYPTOBOX_AES_BLOCKSIZE * 2) { + g_free (src); + + return luaL_error (L, "invalid cookie len %d", (gint)cookie_len); + } + + /* Perform AES CTR via AES ECB on nonce */ + EVP_CIPHER_CTX *ctx; + ctx = EVP_CIPHER_CTX_new (); + /* As per CTR definition, we use encrypt for both encrypt and decrypt */ + EVP_EncryptInit_ex (ctx, EVP_aes_128_ecb (), NULL, aes_key, NULL); + EVP_CIPHER_CTX_set_padding (ctx, 0); + + bklen = sizeof (nonce); + blk = nonce; + g_assert (EVP_EncryptUpdate (ctx, blk, &bklen, src, + RSPAMD_CRYPTOBOX_AES_BLOCKSIZE)); + blk += bklen; + g_assert (EVP_EncryptFinal_ex (ctx, blk, &bklen)); + EVP_CIPHER_CTX_free (ctx); + + /* Decode result */ + for (guint i = 0; i < RSPAMD_CRYPTOBOX_AES_BLOCKSIZE; i ++) { + src[i + sizeof (nonce)] ^= nonce[i]; + } + + if (src[RSPAMD_CRYPTOBOX_AES_BLOCKSIZE * 2 - 1] != '\0') { + /* Bad cookie */ + lua_pushnil (L); + } + else { + lua_pushstring (L, src + sizeof (nonce)); + } + + rspamd_explicit_memzero (src, RSPAMD_CRYPTOBOX_AES_BLOCKSIZE * 2); + g_free (src); + rspamd_explicit_memzero (aes_key, sizeof (aes_key)); + } + else { + return luaL_error (L, "invalid arguments"); + } + + return 1; +} + static gint lua_load_pubkey (lua_State * L) { diff --git a/src/lua/lua_dns_resolver.c b/src/lua/lua_dns_resolver.c index 8a49fdfaf..d00aaa6a2 100644 --- a/src/lua/lua_dns_resolver.c +++ b/src/lua/lua_dns_resolver.c @@ -455,7 +455,10 @@ lua_dns_resolver_resolve_common (lua_State *L, if (ret) { cbdata->s = session; cbdata->item = rspamd_symbols_cache_get_cur_item (task); - rspamd_symcache_item_async_inc (task, cbdata->item); + + if (cbdata->item) { + rspamd_symcache_item_async_inc (task, cbdata->item); + } /* callback was set up */ lua_pushboolean (L, TRUE); } else { diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c index 8d884fab0..a1f62b72d 100644 --- a/src/lua/lua_redis.c +++ b/src/lua/lua_redis.c @@ -366,6 +366,10 @@ lua_redis_push_data (const redisReply *r, struct lua_redis_ctx *ctx, /* Data */ lua_redis_push_reply (cbs.L, r, ctx->flags & LUA_REDIS_TEXTDATA); + if (ud->item) { + rspamd_symbols_cache_set_cur_item (ud->task, ud->item); + } + if (lua_pcall (cbs.L, 2, 0, 0) != 0) { msg_info ("call to callback failed: %s", lua_tostring (cbs.L, -1)); lua_pop (cbs.L, 1); diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 80ece22a6..18754ee6b 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -1605,7 +1605,8 @@ lua_task_set_pre_result (lua_State * L) /* Keep compatibility here :( */ ucl_object_replace_key (task->messages, - ucl_object_fromstring (message), "smtp_message", 0, + ucl_object_fromstring_common (message, 0, UCL_STRING_RAW), + "smtp_message", 0, false); } else { @@ -1682,7 +1683,8 @@ lua_task_append_message (lua_State * L) } ucl_object_insert_key (task->messages, - ucl_object_fromstring (message), category, 0, + ucl_object_fromstring_common (message, 0, UCL_STRING_RAW), + category, 0, true); } else { diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index 751ee2aff..3da793adc 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -2107,7 +2107,9 @@ fuzzy_check_session_is_completed (struct fuzzy_client_session *session) if (nreplied == session->commands->len) { fuzzy_insert_metric_results (session->task, session->results); - rspamd_symcache_item_async_dec_check (session->task, session->item); + if (session->item) { + rspamd_symcache_item_async_dec_check (session->task, session->item); + } rspamd_session_remove_event (session->task->s, fuzzy_io_fin, session); return TRUE; @@ -2182,7 +2184,10 @@ fuzzy_check_io_callback (gint fd, short what, void *arg) errno, strerror (errno)); rspamd_upstream_fail (session->server, FALSE); - rspamd_symcache_item_async_dec_check (session->task, session->item); + + if (session->item) { + rspamd_symcache_item_async_dec_check (session->task, session->item); + } rspamd_session_remove_event (session->task->s, fuzzy_io_fin, session); } else { @@ -2223,7 +2228,9 @@ fuzzy_check_timer_callback (gint fd, short what, void *arg) rspamd_upstream_addr (session->server)), session->retransmits); rspamd_upstream_fail (session->server, FALSE); - rspamd_symcache_item_async_dec_check (session->task, session->item); + if (session->item) { + rspamd_symcache_item_async_dec_check (session->task, session->item); + } rspamd_session_remove_event (session->task->s, fuzzy_io_fin, session); } else { @@ -2879,7 +2886,10 @@ register_fuzzy_client_call (struct rspamd_task *task, rspamd_session_add_event (task->s, fuzzy_io_fin, session, g_quark_from_static_string ("fuzzy check")); session->item = rspamd_symbols_cache_get_cur_item (task); - rspamd_symcache_item_async_inc (task, session->item); + + if (session->item) { + rspamd_symcache_item_async_inc (task, session->item); + } } } } diff --git a/src/plugins/lua/antivirus.lua b/src/plugins/lua/antivirus.lua index 025e36043..a00d2cd73 100644 --- a/src/plugins/lua/antivirus.lua +++ b/src/plugins/lua/antivirus.lua @@ -313,7 +313,7 @@ local function check_av_cache(task, digest, rule, fn) -- Cached if data ~= 'OK' then lua_util.debugm(N, task, 'got cached result for %s: %s', key, data) - data = rspamd_str_split(data, '\x30') + data = rspamd_str_split(data, '\v') yield_result(task, rule, data) else lua_util.debugm(N, task, 'got cached result for %s: %s', key, data) @@ -359,7 +359,7 @@ local function save_av_cache(task, digest, rule, to_save) end if type(to_save) == 'table' then - to_save = table.concat(to_save, '\x30') + to_save = table.concat(to_save, '\v') end if redis_params then diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c index 52bfe42ca..8070bfb23 100644 --- a/src/plugins/surbl.c +++ b/src/plugins/surbl.c @@ -1574,6 +1574,10 @@ free_redirector_session (void *ud) { struct redirector_param *param = (struct redirector_param *)ud; + if (param->item) { + rspamd_symcache_item_async_dec_check (param->task, param->item); + } + rspamd_http_connection_unref (param->conn); close (param->sock); } @@ -1682,6 +1686,7 @@ register_redirector_call (struct rspamd_url *url, struct rspamd_task *task, msg_info_surbl ("<%s> cannot create tcp socket failed: %s", task->message_id, strerror (errno)); + return; } @@ -1710,6 +1715,10 @@ register_redirector_call (struct rspamd_url *url, struct rspamd_task *task, g_quark_from_static_string ("surbl")); param->item = rspamd_symbols_cache_get_cur_item (task); + if (param->item) { + rspamd_symcache_item_async_inc (param->task, param->item); + } + rspamd_http_connection_write_message (param->conn, msg, NULL, NULL, param, s, timeout, task->ev_base); @@ -1904,7 +1913,7 @@ surbl_test_url (struct rspamd_task *task, param->tree = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); param->ctx = surbl_module_ctx; param->item = item; - rspamd_symcache_item_async_inc (task, item); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_hash_table_unref, param->tree); |