Exemple #1
0
static void
process_regexp_item (struct rspamd_task *task, void *user_data)
{
	struct regexp_module_item *item = user_data;
	gint res = FALSE;

	/* Non-threaded version */
	if (item->lua_function) {
		/* Just call function */
		res = FALSE;
		if (!rspamd_lua_call_expression_func (item->lua_function, task, NULL,
				&res)) {
			msg_err_task ("error occurred when checking symbol %s",
					item->symbol);
		}
	}
	else {
		/* Process expression */
		if (item->expr) {
			res = rspamd_process_expression (item->expr, 0, task);
		}
		else {
			msg_warn_task ("FIXME: %s symbol is broken with new expressions",
					item->symbol);
		}
	}

	if (res) {
		rspamd_task_insert_result (task, item->symbol, res, NULL);
	}
}
Exemple #2
0
/* Return result mark for statfile */
double
rspamd_lua_call_cls_post_callbacks (struct rspamd_classifier_config *ccf,
	struct rspamd_task *task,
	double in,
	lua_State *L)
{
	struct classifier_callback_data *cd;
	struct rspamd_classifier_config **pccf;
	struct rspamd_task **ptask;
	double out = in;
	GList *cur;

	/* Go throught all callbacks and call them, appending results to list */
	cur = g_list_first (ccf->pre_callbacks);
	while (cur) {
		cd = cur->data;
		lua_getglobal (L, cd->name);

		pccf = lua_newuserdata (L, sizeof (struct rspamd_classifier_config *));
		rspamd_lua_setclass (L, "rspamd{classifier}", -1);
		*pccf = ccf;

		ptask = lua_newuserdata (L, sizeof (struct rspamd_task *));
		rspamd_lua_setclass (L, "rspamd{task}", -1);
		*ptask = task;

		lua_pushnumber (L, out);

		if (lua_pcall (L, 3, 1, 0) != 0) {
			msg_warn_task ("error running function %s: %s", cd->name,
				lua_tostring (L, -1));
			lua_pop (L, 1);
		}
		else {
			if (lua_isnumber (L, 1)) {
				out = lua_tonumber (L, 1);
			}
			lua_pop (L, 1);
		}

		cur = g_list_next (cur);
	}

	return out;

}
Exemple #3
0
/* Called when we have connected to the redis server and got stats */
static void
rspamd_redis_connected (redisAsyncContext *c, gpointer r, gpointer priv)
{
	struct redis_stat_runtime *rt = REDIS_RUNTIME (priv);
	redisReply *reply = r;
	struct rspamd_task *task;
	glong val = 0;

	task = rt->task;

	if (c->err == 0) {
		if (r != NULL) {
			if (G_UNLIKELY (reply->type == REDIS_REPLY_INTEGER)) {
				val = reply->integer;
			}
			else if (reply->type == REDIS_REPLY_STRING) {
				rspamd_strtol (reply->str, reply->len, &val);
			}
			else {
				if (reply->type != REDIS_REPLY_NIL) {
					msg_err_task ("bad learned type for %s: %d",
						rt->stcf->symbol, reply->type);
				}

				val = 0;
			}

			if (val < 0) {
				msg_warn_task ("invalid number of learns for %s: %L",
						rt->stcf->symbol, val);
				val = 0;
			}

			rt->learned = val;
			msg_debug_task ("connected to redis server, tokens learned for %s: %uL",
					rt->redis_object_expanded, rt->learned);
			rspamd_upstream_ok (rt->selected);
		}
	}
	else {
		msg_err_task ("error getting reply from redis server %s: %s",
				rspamd_upstream_name (rt->selected), c->errstr);
		rspamd_upstream_fail (rt->selected);
	}

}
Exemple #4
0
static GList *
call_classifier_pre_callback (struct rspamd_classifier_config *ccf,
	struct rspamd_task *task,
	lua_State *L,
	gboolean is_learn,
	gboolean is_spam)
{
	struct rspamd_classifier_config **pccf;
	struct rspamd_task **ptask;
	struct rspamd_statfile_config **pst;
	GList *res = NULL;

	pccf = lua_newuserdata (L, sizeof (struct rspamd_classifier_config *));
	rspamd_lua_setclass (L, "rspamd{classifier}", -1);
	*pccf = ccf;

	ptask = lua_newuserdata (L, sizeof (struct rspamd_task *));
	rspamd_lua_setclass (L, "rspamd{task}", -1);
	*ptask = task;

	lua_pushboolean (L, is_learn);
	lua_pushboolean (L, is_spam);

	if (lua_pcall (L, 4, 1, 0) != 0) {
		msg_warn_task ("error running pre classifier callback %s",
			lua_tostring (L, -1));
		lua_pop (L, 1);
	}
	else {
		if (lua_istable (L, -1)) {
			lua_pushnil (L);
			while (lua_next (L, -2)) {
				pst = rspamd_lua_check_udata (L, -1, "rspamd{statfile}");
				if (pst) {
					res = g_list_prepend (res, *pst);
				}
				lua_pop (L, 1);
			}
		}
		lua_pop (L, 1);
	}

	return res;
}
Exemple #5
0
gboolean
rspamd_task_load_message (struct rspamd_task *task,
	struct rspamd_http_message *msg, const gchar *start, gsize len)
{
	guint control_len, r;
	struct ucl_parser *parser;
	ucl_object_t *control_obj;
	gchar filepath[PATH_MAX], *fp;
	gint fd, flen;
	gpointer map;
	struct stat st;

	if (msg) {
		rspamd_protocol_handle_headers (task, msg);
	}

	if (task->flags & RSPAMD_TASK_FLAG_FILE) {
		g_assert (task->msg.len > 0);

		r = rspamd_strlcpy (filepath, task->msg.start,
				MIN (sizeof (filepath), task->msg.len + 1));

		rspamd_decode_url (filepath, filepath, r + 1);
		flen = strlen (filepath);

		if (filepath[0] == '"' && flen > 2) {
			/* We need to unquote filepath */
			fp = &filepath[1];
			fp[flen - 2] = '\0';
		}
		else {
			fp = &filepath[0];
		}

		if (access (fp, R_OK) == -1 || stat (fp, &st) == -1) {
			g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
					"Invalid file (%s): %s", fp, strerror (errno));
			return FALSE;
		}

		fd = open (fp, O_RDONLY);

		if (fd == -1) {
			g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
					"Cannot open file (%s): %s", fp, strerror (errno));
			return FALSE;
		}

		map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);


		if (map == MAP_FAILED) {
			close (fd);
			g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
					"Cannot mmap file (%s): %s", fp, strerror (errno));
			return FALSE;
		}

		close (fd);
		task->msg.start = map;
		task->msg.len = st.st_size;

		rspamd_mempool_add_destructor (task->task_pool, rspamd_task_unmapper, task);
	}
	else {
		debug_task ("got input of length %z", task->msg.len);
		task->msg.start = start;
		task->msg.len = len;

		if (task->msg.len == 0) {
			msg_warn_task ("message has invalid message length: %ud",
					task->msg.len);
			g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
					"Invalid length");
			return FALSE;
		}

		if (task->flags & RSPAMD_TASK_FLAG_HAS_CONTROL) {
			/* We have control chunk, so we need to process it separately */
			if (task->msg.len < task->message_len) {
				msg_warn_task ("message has invalid message length: %ud and total len: %ud",
						task->message_len, task->msg.len);
				g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
						"Invalid length");
				return FALSE;
			}
			control_len = task->msg.len - task->message_len;

			if (control_len > 0) {
				parser = ucl_parser_new (UCL_PARSER_KEY_LOWERCASE);

				if (!ucl_parser_add_chunk (parser, task->msg.start, control_len)) {
					msg_warn_task ("processing of control chunk failed: %s",
							ucl_parser_get_error (parser));
					ucl_parser_free (parser);
				}
				else {
					control_obj = ucl_parser_get_object (parser);
					ucl_parser_free (parser);
					rspamd_protocol_handle_control (task, control_obj);
					ucl_object_unref (control_obj);
				}

				task->msg.start += control_len;
				task->msg.len -= control_len;
			}
		}
	}

	return TRUE;
}