Example #1
0
gint
dkim_module_config (struct rspamd_config *cfg)
{
	const ucl_object_t *value;
	gint res = TRUE, cb_id = -1, check_id = -1;
	guint cache_size;
	gboolean got_trusted = FALSE;

	if (!rspamd_config_is_module_enabled (cfg, "dkim")) {
		return TRUE;
	}

	dkim_module_ctx->whitelist_ip = radix_create_compressed ();

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "symbol_reject")) != NULL) {
		dkim_module_ctx->symbol_reject = ucl_obj_tostring (value);
	}
	else {
		dkim_module_ctx->symbol_reject = DEFAULT_SYMBOL_REJECT;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim",
		"symbol_tempfail")) != NULL) {
		dkim_module_ctx->symbol_tempfail = ucl_obj_tostring (value);
	}
	else {
		dkim_module_ctx->symbol_tempfail = DEFAULT_SYMBOL_TEMPFAIL;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "symbol_allow")) != NULL) {
		dkim_module_ctx->symbol_allow = ucl_obj_tostring (value);
	}
	else {
		dkim_module_ctx->symbol_allow = DEFAULT_SYMBOL_ALLOW;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "symbol_na")) != NULL) {
		dkim_module_ctx->symbol_na = ucl_obj_tostring (value);
	}
	else {
		dkim_module_ctx->symbol_na = DEFAULT_SYMBOL_NA;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim",
		"dkim_cache_size")) != NULL) {
		cache_size = ucl_obj_toint (value);
	}
	else {
		cache_size = DEFAULT_CACHE_SIZE;
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "time_jitter")) != NULL) {
		dkim_module_ctx->time_jitter = ucl_obj_todouble (value);
	}
	else {
		dkim_module_ctx->time_jitter = DEFAULT_TIME_JITTER;
	}

	if ((value =
			rspamd_config_get_module_opt (cfg, "dkim", "max_sigs")) != NULL) {
		dkim_module_ctx->max_sigs = ucl_object_toint (value);
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "whitelist")) != NULL) {

		rspamd_config_radix_from_ucl (cfg, value, "DKIM whitelist",
				&dkim_module_ctx->whitelist_ip, NULL);
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "domains")) != NULL) {
		if (!rspamd_map_add_from_ucl (cfg, value,
			"DKIM domains", rspamd_kv_list_read, rspamd_kv_list_fin,
			(void **)&dkim_module_ctx->dkim_domains)) {
			msg_warn_config ("cannot load dkim domains list from %s",
				ucl_obj_tostring (value));
		}
		else {
			got_trusted = TRUE;
		}
	}

	if (!got_trusted && (value =
			rspamd_config_get_module_opt (cfg, "dkim", "trusted_domains")) != NULL) {
		if (!rspamd_map_add_from_ucl (cfg, value,
				"DKIM domains", rspamd_kv_list_read, rspamd_kv_list_fin,
				(void **)&dkim_module_ctx->dkim_domains)) {
			msg_warn_config ("cannot load dkim domains list from %s",
					ucl_obj_tostring (value));
		}
		else {
			got_trusted = TRUE;
		}
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim",
		"strict_multiplier")) != NULL) {
		dkim_module_ctx->strict_multiplier = ucl_obj_toint (value);
	}
	else {
		dkim_module_ctx->strict_multiplier = 1;
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "trusted_only")) != NULL) {
		dkim_module_ctx->trusted_only = ucl_obj_toboolean (value);
	}
	else {
		dkim_module_ctx->trusted_only = FALSE;
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "skip_multi")) != NULL) {
		dkim_module_ctx->skip_multi = ucl_obj_toboolean (value);
	}
	else {
		dkim_module_ctx->skip_multi = FALSE;
	}

	if (dkim_module_ctx->trusted_only && !got_trusted) {
		msg_err_config (
			"trusted_only option is set and no trusted domains are defined; disabling dkim module completely as it is useless in this case");
	}
	else {
		cb_id = rspamd_symbols_cache_add_symbol (cfg->cache,
			dkim_module_ctx->symbol_reject,
			0,
			dkim_symbol_callback,
			NULL,
			SYMBOL_TYPE_NORMAL|SYMBOL_TYPE_FINE,
			-1);
		rspamd_symbols_cache_add_symbol (cfg->cache,
			dkim_module_ctx->symbol_na,
			0,
			NULL, NULL,
			SYMBOL_TYPE_VIRTUAL|SYMBOL_TYPE_FINE,
			cb_id);
		rspamd_symbols_cache_add_symbol (cfg->cache,
			dkim_module_ctx->symbol_tempfail,
			0,
			NULL, NULL,
			SYMBOL_TYPE_VIRTUAL|SYMBOL_TYPE_FINE,
			cb_id);
		rspamd_symbols_cache_add_symbol (cfg->cache,
			dkim_module_ctx->symbol_allow,
			0,
			NULL, NULL,
			SYMBOL_TYPE_VIRTUAL|SYMBOL_TYPE_FINE,
			cb_id);

		dkim_module_ctx->dkim_hash = rspamd_lru_hash_new (
				cache_size,
				g_free, /* Keys are just C-strings */
				dkim_module_key_dtor);

		msg_info_config ("init internal dkim module");
#ifndef HAVE_OPENSSL
		msg_warn_config (
			"openssl is not found so dkim rsa check is disabled, only check body hash, it is NOT safe to trust these results");
#endif
	}

	if ((value = rspamd_config_get_module_opt (cfg, "dkim", "sign_condition"))
			!= NULL) {
		const gchar *lua_script;

		lua_script = ucl_object_tostring (value);

		if (lua_script) {
			if (luaL_dostring (cfg->lua_state, lua_script) != 0) {
				msg_err_config ("cannot execute lua script for fuzzy "
						"learn condition: %s", lua_tostring (cfg->lua_state, -1));
			}
			else {
				if (lua_type (cfg->lua_state, -1) == LUA_TFUNCTION) {
					dkim_module_ctx->sign_condition_ref = luaL_ref (cfg->lua_state,
							LUA_REGISTRYINDEX);

					dkim_module_ctx->dkim_sign_hash = rspamd_lru_hash_new (
									128,
									g_free, /* Keys are just C-strings */
									(GDestroyNotify)rspamd_dkim_sign_key_unref);
					check_id = rspamd_symbols_cache_add_symbol (cfg->cache,
							"DKIM_SIGN",
							0,
							dkim_sign_callback,
							NULL,
							SYMBOL_TYPE_CALLBACK|SYMBOL_TYPE_FINE,
							-1);
					msg_info_config ("init condition script for DKIM signing");

					/*
					 * Allow dkim signing to be executed only after dkim check
					 */
					if (cb_id > 0) {
						rspamd_symbols_cache_add_delayed_dependency (cfg->cache,
								"DKIM_SIGN", dkim_module_ctx->symbol_reject);
					}

					rspamd_config_add_metric_symbol (cfg, DEFAULT_METRIC,
							"DKIM_SIGN", 0.0, "DKIM signature fake symbol",
							"dkim", RSPAMD_SYMBOL_FLAG_IGNORE, 1);

				}
				else {
					msg_err_config ("lua script must return "
							"function(task) and not %s",
							lua_typename (cfg->lua_state,
									lua_type (cfg->lua_state, -1)));
				}
			}
		}
	}

	return res;
}
Example #2
0
gint
fuzzy_check_module_config (struct rspamd_config *cfg)
{
	const ucl_object_t *value, *cur;
	gint res = TRUE, cb_id;

	if (!rspamd_config_is_module_enabled (cfg, "fuzzy_check")) {
		return TRUE;
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check", "symbol")) != NULL) {
		fuzzy_module_ctx->default_symbol = ucl_obj_tostring (value);
	}
	else {
		fuzzy_module_ctx->default_symbol = DEFAULT_SYMBOL;
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check",
		"min_length")) != NULL) {
		fuzzy_module_ctx->min_hash_len = ucl_obj_toint (value);
	}
	else {
		fuzzy_module_ctx->min_hash_len = 0;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check",
		"min_bytes")) != NULL) {
		fuzzy_module_ctx->min_bytes = ucl_obj_toint (value);
	}
	else {
		fuzzy_module_ctx->min_bytes = 0;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check",
		"min_height")) != NULL) {
		fuzzy_module_ctx->min_height = ucl_obj_toint (value);
	}
	else {
		fuzzy_module_ctx->min_height = 0;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check",
		"min_width")) != NULL) {
		fuzzy_module_ctx->min_width = ucl_obj_toint (value);
	}
	else {
		fuzzy_module_ctx->min_width = 0;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check", "timeout")) != NULL) {
		fuzzy_module_ctx->io_timeout = ucl_obj_todouble (value) * 1000;
	}
	else {
		fuzzy_module_ctx->io_timeout = DEFAULT_IO_TIMEOUT;
	}

	if ((value =
				 rspamd_config_get_module_opt (cfg,
						 "fuzzy_check",
						 "retransmits")) != NULL) {
		fuzzy_module_ctx->retransmits = ucl_obj_toint (value);
	}
	else {
		fuzzy_module_ctx->retransmits = DEFAULT_RETRANSMITS;
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check",
		"whitelist")) != NULL) {
		fuzzy_module_ctx->whitelist = radix_create_compressed ();
		if (!rspamd_map_add (cfg, ucl_obj_tostring (value),
			"Fuzzy whitelist", rspamd_radix_read, rspamd_radix_fin,
			(void **)&fuzzy_module_ctx->whitelist)) {
			radix_add_generic_iplist (ucl_obj_tostring (value),
					&fuzzy_module_ctx->whitelist);
		}
	}
	else {
		fuzzy_module_ctx->whitelist = NULL;
	}

	if ((value =
		rspamd_config_get_module_opt (cfg, "fuzzy_check", "rule")) != NULL) {

		cb_id = rspamd_symbols_cache_add_symbol (cfg->cache,
					"FUZZY_CALLBACK", 0, fuzzy_symbol_callback, NULL,
					SYMBOL_TYPE_CALLBACK|SYMBOL_TYPE_FINE,
					-1);

		LL_FOREACH (value, cur) {
			fuzzy_parse_rule (cfg, cur, cb_id);
		}
Example #3
0
gint
dkim_module_config (struct rspamd_config *cfg)
{
	const ucl_object_t *value;
	gint res = TRUE, cb_id;
	guint cache_size, cache_expire;
	gboolean got_trusted = FALSE;

	if (!rspamd_config_is_module_enabled (cfg, "dkim")) {
		return TRUE;
	}

	dkim_module_ctx->whitelist_ip = radix_create_compressed ();

	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "symbol_reject")) != NULL) {
		dkim_module_ctx->symbol_reject = ucl_obj_tostring (value);
	}
	else {
		dkim_module_ctx->symbol_reject = DEFAULT_SYMBOL_REJECT;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim",
		"symbol_tempfail")) != NULL) {
		dkim_module_ctx->symbol_tempfail = ucl_obj_tostring (value);
	}
	else {
		dkim_module_ctx->symbol_tempfail = DEFAULT_SYMBOL_TEMPFAIL;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "symbol_allow")) != NULL) {
		dkim_module_ctx->symbol_allow = ucl_obj_tostring (value);
	}
	else {
		dkim_module_ctx->symbol_allow = DEFAULT_SYMBOL_ALLOW;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim",
		"dkim_cache_size")) != NULL) {
		cache_size = ucl_obj_toint (value);
	}
	else {
		cache_size = DEFAULT_CACHE_SIZE;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim",
		"dkim_cache_expire")) != NULL) {
		cache_expire = ucl_obj_todouble (value);
	}
	else {
		cache_expire = DEFAULT_CACHE_MAXAGE;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "time_jitter")) != NULL) {
		dkim_module_ctx->time_jitter = ucl_obj_todouble (value);
	}
	else {
		dkim_module_ctx->time_jitter = DEFAULT_TIME_JITTER;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "whitelist")) != NULL) {
		if (!rspamd_map_add (cfg, ucl_obj_tostring (value),
			"DKIM whitelist", rspamd_radix_read, rspamd_radix_fin,
			(void **)&dkim_module_ctx->whitelist_ip)) {
			radix_add_generic_iplist (ucl_obj_tostring (value),
				&dkim_module_ctx->whitelist_ip);
		}
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "domains")) != NULL) {
		if (!rspamd_map_add (cfg, ucl_obj_tostring (value),
			"DKIM domains", rspamd_kv_list_read, rspamd_kv_list_fin,
			(void **)&dkim_module_ctx->dkim_domains)) {
			msg_warn ("cannot load dkim domains list from %s",
				ucl_obj_tostring (value));
		}
		else {
			got_trusted = TRUE;
		}
	}
	if (!got_trusted && (value =
			rspamd_config_get_module_opt (cfg, "dkim", "trusted_domains")) != NULL) {
		if (!rspamd_map_add (cfg, ucl_obj_tostring (value),
				"DKIM domains", rspamd_kv_list_read, rspamd_kv_list_fin,
				(void **)&dkim_module_ctx->dkim_domains)) {
			msg_warn ("cannot load dkim domains list from %s",
					ucl_obj_tostring (value));
		}
		else {
			got_trusted = TRUE;
		}
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim",
		"strict_multiplier")) != NULL) {
		dkim_module_ctx->strict_multiplier = ucl_obj_toint (value);
	}
	else {
		dkim_module_ctx->strict_multiplier = 1;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "trusted_only")) != NULL) {
		dkim_module_ctx->trusted_only = ucl_obj_toboolean (value);
	}
	else {
		dkim_module_ctx->trusted_only = FALSE;
	}
	if ((value =
		rspamd_config_get_module_opt (cfg, "dkim", "skip_multi")) != NULL) {
		dkim_module_ctx->skip_multi = ucl_obj_toboolean (value);
	}
	else {
		dkim_module_ctx->skip_multi = FALSE;
	}

	if (dkim_module_ctx->trusted_only && !got_trusted) {
		msg_err (
			"trusted_only option is set and no trusted domains are defined; disabling dkim module completely as it is useless in this case");
	}
	else {
		cb_id = rspamd_symbols_cache_add_symbol_normal (cfg->cache,
			dkim_module_ctx->symbol_reject,
			1,
			dkim_symbol_callback,
			NULL);
		rspamd_symbols_cache_add_symbol_virtual (cfg->cache,
			dkim_module_ctx->symbol_tempfail,
			1,
			cb_id);
		rspamd_symbols_cache_add_symbol_virtual (cfg->cache,
			dkim_module_ctx->symbol_allow,
			1,
			cb_id);

		dkim_module_ctx->dkim_hash = rspamd_lru_hash_new (
				cache_size,
				cache_expire,
				g_free,
				(GDestroyNotify)rspamd_dkim_key_free);


#ifndef HAVE_OPENSSL
		msg_warn (
			"openssl is not found so dkim rsa check is disabled, only check body hash, it is NOT safe to trust these results");
#endif
	}

	return res;
}
Example #4
0
gint
regexp_module_config (struct rspamd_config *cfg)
{
	struct regexp_module_item *cur_item;
	const ucl_object_t *sec, *value, *elt;
	ucl_object_iter_t it = NULL;
	gint res = TRUE, id;

	if (!rspamd_config_is_module_enabled (cfg, "regexp")) {
		return TRUE;
	}

	sec = ucl_object_find_key (cfg->rcl_obj, "regexp");
	if (sec == NULL) {
		msg_err_config ("regexp module enabled, but no rules are defined");
		return TRUE;
	}

	regexp_module_ctx->max_size = 0;

	while ((value = ucl_iterate_object (sec, &it, true)) != NULL) {
		if (g_ascii_strncasecmp (ucl_object_key (value), "max_size",
			sizeof ("max_size") - 1) == 0) {
			regexp_module_ctx->max_size = ucl_obj_toint (value);
			rspamd_mime_expression_set_re_limit (regexp_module_ctx->max_size);
		}
		else if (g_ascii_strncasecmp (ucl_object_key (value), "max_threads",
			sizeof ("max_threads") - 1) == 0) {
			msg_warn_config ("regexp module is now single threaded, max_threads is ignored");
		}
		else if (value->type == UCL_STRING) {
			cur_item = rspamd_mempool_alloc0 (regexp_module_ctx->regexp_pool,
					sizeof (struct regexp_module_item));
			cur_item->symbol = ucl_object_key (value);
			if (!read_regexp_expression (regexp_module_ctx->regexp_pool,
				cur_item, ucl_object_key (value),
				ucl_obj_tostring (value), cfg)) {
				res = FALSE;
			}
			else {
				rspamd_symbols_cache_add_symbol (cfg->cache,
						cur_item->symbol,
						0,
						process_regexp_item,
						cur_item,
						SYMBOL_TYPE_NORMAL, -1);
			}
		}
		else if (value->type == UCL_USERDATA) {
			/* Just a lua function */
			cur_item = rspamd_mempool_alloc0 (regexp_module_ctx->regexp_pool,
					sizeof (struct regexp_module_item));
			cur_item->symbol = ucl_object_key (value);
			cur_item->lua_function = ucl_object_toclosure (value);
			rspamd_symbols_cache_add_symbol (cfg->cache,
				cur_item->symbol,
				0,
				process_regexp_item,
				cur_item,
				SYMBOL_TYPE_NORMAL, -1);
		}
		else if (value->type == UCL_OBJECT) {
			const gchar *description = NULL, *group = NULL,
					*metric = DEFAULT_METRIC;
			gdouble score = 0.0;
			gboolean one_shot = FALSE, is_lua = FALSE, valid_expression = TRUE;

			/* We have some lua table, extract its arguments */
			elt = ucl_object_find_key (value, "callback");

			if (elt == NULL || elt->type != UCL_USERDATA) {

				/* Try plain regexp expression */
				elt = ucl_object_find_any_key (value, "regexp", "re", NULL);

				if (elt != NULL && ucl_object_type (elt) == UCL_STRING) {
					cur_item = rspamd_mempool_alloc0 (regexp_module_ctx->regexp_pool,
							sizeof (struct regexp_module_item));
					cur_item->symbol = ucl_object_key (value);
					if (!read_regexp_expression (regexp_module_ctx->regexp_pool,
							cur_item, ucl_object_key (value),
							ucl_obj_tostring (elt), cfg)) {
						res = FALSE;
					}
					else {
						valid_expression = TRUE;
					}
				}
				else {
					msg_err_config (
							"no callback/expression defined for regexp symbol: "
									"%s", ucl_object_key (value));
				}
			}
			else {
				is_lua = TRUE;
				cur_item = rspamd_mempool_alloc0 (
						regexp_module_ctx->regexp_pool,
						sizeof (struct regexp_module_item));
				cur_item->symbol = ucl_object_key (value);
				cur_item->lua_function = ucl_object_toclosure (value);
			}

			if (cur_item && (is_lua || valid_expression)) {
				id = rspamd_symbols_cache_add_symbol (cfg->cache,
						cur_item->symbol,
						0,
						process_regexp_item,
						cur_item,
						SYMBOL_TYPE_NORMAL, -1);

				elt = ucl_object_find_key (value, "condition");

				if (elt != NULL && ucl_object_type (elt) == UCL_USERDATA) {
					struct ucl_lua_funcdata *conddata;

					conddata = ucl_object_toclosure (elt);
					rspamd_symbols_cache_add_condition (cfg->cache, id,
							conddata->L, conddata->idx);
				}

				elt = ucl_object_find_key (value, "metric");

				if (elt) {
					metric = ucl_object_tostring (elt);
				}

				elt = ucl_object_find_key (value, "description");

				if (elt) {
					description = ucl_object_tostring (elt);
				}

				elt = ucl_object_find_key (value, "group");

				if (elt) {
					group = ucl_object_tostring (elt);
				}

				elt = ucl_object_find_key (value, "score");

				if (elt) {
					score = ucl_object_todouble (elt);
				}

				elt = ucl_object_find_key (value, "one_shot");

				if (elt) {
					one_shot = ucl_object_toboolean (elt);
				}

				rspamd_config_add_metric_symbol (cfg, metric, cur_item->symbol,
						score, description, group, one_shot, FALSE);
			}
		}
		else {
			msg_warn_config ("unknown type of attribute %s for regexp module",
				ucl_object_key (value));
		}
	}

	return res;
}