Browse Source

Support IP DNS black lists for URIBL

Rspamd now can resolve URL's IP address and check it via the standard DNS IP blacklist (such as spamhaus SBL, for example)
tags/1.1.0
Vsevolod Stakhov 8 years ago
parent
commit
79828e25c8
3 changed files with 117 additions and 14 deletions
  1. 1
    1
      src/lua/lua_dns.c
  2. 114
    12
      src/plugins/surbl.c
  3. 2
    1
      src/plugins/surbl.h

+ 1
- 1
src/lua/lua_dns.c View File

@@ -207,7 +207,7 @@ lua_dns_callback (struct rdns_reply *reply, gpointer arg)
}

if (lua_pcall (cd->L, 5, 0, 0) != 0) {
msg_info ("call to dns_callback failed: %s", lua_tostring (cd->L, -1));
msg_info ("call to dns callback failed: %s", lua_tostring (cd->L, -1));
}

/* Unref function */

+ 114
- 12
src/plugins/surbl.c View File

@@ -41,6 +41,7 @@
* - bit (string): describes a prefix for a single bit
*/

#include <rdns.h>
#include "config.h"
#include "libmime/message.h"
#include "libutil/map.h"
@@ -52,7 +53,8 @@
static struct surbl_ctx *surbl_module_ctx = NULL;

static void surbl_test_url (struct rspamd_task *task, void *user_data);
static void dns_callback (struct rdns_reply *reply, gpointer arg);
static void surbl_dns_callback (struct rdns_reply *reply, gpointer arg);
static void surbl_dns_ip_callback (struct rdns_reply *reply, gpointer arg);
static void process_dns_results (struct rspamd_task *task,
struct suffix_item *suffix, gchar *url, guint32 addr);

@@ -484,6 +486,19 @@ surbl_module_config (struct rspamd_config *cfg)
new_suffix->options |= SURBL_OPTION_NOIP;
}
}
cur = ucl_obj_get_key (cur_rule, "resolve_ip");
if (cur != NULL && cur->type == UCL_BOOLEAN) {
if (ucl_object_toboolean (cur)) {
new_suffix->options |= SURBL_OPTION_RESOLVEIP;
}
}

if ((new_suffix->options & (SURBL_OPTION_RESOLVEIP|SURBL_OPTION_NOIP)) ==
(SURBL_OPTION_NOIP|SURBL_OPTION_RESOLVEIP)) {
/* Mutually exclusive options */
msg_err_config ("options noip and resolve_ip are "
"mutually exclusive for suffix %s", new_suffix->suffix);
}

cb_id = rspamd_symbols_cache_add_symbol (cfg->cache,
"SURBL_CALLBACK",
@@ -859,7 +874,46 @@ make_surbl_requests (struct rspamd_url *url, struct rspamd_task *task,
f.begin = url->host;
f.len = url->hostlen;

if ((surbl_req = format_surbl_request (task->task_pool, &f, suffix, TRUE,
if (suffix->options & SURBL_OPTION_RESOLVEIP) {
/*
* We need to get url real TLD, resolve it with no suffix and then
* check against surbl using reverse octets printing
*/
surbl_req = format_surbl_request (task->task_pool, &f, suffix, FALSE,
&err, forced, tree, url);

if (surbl_req == NULL) {
if (err != NULL) {
if (err->code != WHITELIST_ERROR && err->code != DUPLICATE_ERROR) {
msg_info_task ("cannot format url string for surbl %s, %e",
struri (url),
err);
}
g_error_free (err);
return;
}
}
else {
/* XXX: We make merely A request here */
param =
rspamd_mempool_alloc (task->task_pool,
sizeof (struct dns_param));
param->url = url;
param->task = task;
param->suffix = suffix;
param->host_resolve =
rspamd_mempool_strdup (task->task_pool, surbl_req);
debug_task ("send surbl dns ip request %s", surbl_req);

if (make_dns_request_task (task,
surbl_dns_ip_callback,
(void *) param, RDNS_REQUEST_A, surbl_req)) {
param->w = rspamd_session_get_watcher (task->s);
rspamd_session_watcher_push (task->s);
}
}
}
else if ((surbl_req = format_surbl_request (task->task_pool, &f, suffix, TRUE,
&err, forced, tree, url)) != NULL) {
param =
rspamd_mempool_alloc (task->task_pool, sizeof (struct dns_param));
@@ -871,21 +925,19 @@ make_surbl_requests (struct rspamd_url *url, struct rspamd_task *task,
debug_task ("send surbl dns request %s", surbl_req);

if (make_dns_request_task (task,
dns_callback,
(void *)param, RDNS_REQUEST_A, surbl_req)) {
surbl_dns_callback,
(void *) param, RDNS_REQUEST_A, surbl_req)) {
param->w = rspamd_session_get_watcher (task->s);
rspamd_session_watcher_push (task->s);
}
}
else if (err != NULL && err->code != WHITELIST_ERROR && err->code !=
DUPLICATE_ERROR) {
msg_info_task ("cannot format url string for surbl %s, %e", struri (
url), err);
g_error_free (err);
return;
}
else if (err != NULL) {
if (err->code != WHITELIST_ERROR && err->code != DUPLICATE_ERROR) {
msg_info_task ("cannot format url string for surbl %s, %e", struri (
url), err);
}
g_error_free (err);
return;
}
}

@@ -930,7 +982,7 @@ process_dns_results (struct rspamd_task *task,
}

static void
dns_callback (struct rdns_reply *reply, gpointer arg)
surbl_dns_callback (struct rdns_reply *reply, gpointer arg)
{
struct dns_param *param = (struct dns_param *)arg;
struct rspamd_task *task;
@@ -957,6 +1009,56 @@ dns_callback (struct rdns_reply *reply, gpointer arg)
rspamd_session_watcher_pop (param->task->s, param->w);
}

static void
surbl_dns_ip_callback (struct rdns_reply *reply, gpointer arg)
{
struct dns_param *param = (struct dns_param *) arg;
struct rspamd_task *task;
struct rdns_reply_entry *elt;
GString *to_resolve;
guint32 ip_addr;

task = param->task;
/* If we have result from DNS server, this url exists in SURBL, so increase score */
if (reply->code == RDNS_RC_NOERROR && reply->entries) {

LL_FOREACH (reply->entries, elt) {
elt = reply->entries;

if (elt->type == RDNS_REQUEST_A) {
to_resolve = g_string_sized_new (
strlen (param->suffix->suffix) +
sizeof ("255.255.255.255."));
ip_addr = elt->content.a.addr.s_addr;

/* Big endian <4>.<3>.<2>.<1> */
rspamd_printf_gstring (to_resolve, "%d.%d.%d.%d.%s",
ip_addr >> 24 & 0xff,
ip_addr >> 16 & 0xff,
ip_addr >> 8 & 0xff,
ip_addr & 0xff, param->suffix->suffix);

if (make_dns_request_task (task,
surbl_dns_callback,
param, RDNS_REQUEST_A, to_resolve->str)) {
param->w = rspamd_session_get_watcher (task->s);
rspamd_session_watcher_push (task->s);
}

g_string_free (to_resolve, TRUE);
}
}
}
else {
msg_debug_task ("<%s> domain [%s] cannot be resolved for SURBL check %s",
param->task->message_id, param->host_resolve,
param->suffix->suffix);

}

rspamd_session_watcher_pop (param->task->s, param->w);
}

static void
free_redirector_session (void *ud)
{

+ 2
- 1
src/plugins/surbl.h View File

@@ -12,7 +12,8 @@
#define DEFAULT_SURBL_URL_EXPIRE 86400
#define DEFAULT_SURBL_SYMBOL "SURBL_DNS"
#define DEFAULT_SURBL_SUFFIX "multi.surbl.org"
#define SURBL_OPTION_NOIP 1
#define SURBL_OPTION_NOIP (1 << 0)
#define SURBL_OPTION_RESOLVEIP (1 << 1)
#define MAX_LEVELS 10

struct surbl_ctx {

Loading…
Cancel
Save