Ejemplo n.º 1
0
static gint
lua_util_decode_base64 (lua_State *L)
{
	struct rspamd_lua_text *t;
	const gchar *s = NULL;
	gsize inlen, outlen;
	gboolean zero_copy = FALSE, grab_own = FALSE;
	gint state = 0;
	guint save = 0;

	if (lua_type (L, 1) == LUA_TSTRING) {
		s = luaL_checklstring (L, 1, &inlen);
	}
	else if (lua_type (L, 1) == LUA_TUSERDATA) {
		t = lua_check_text (L, 1);

		if (t != NULL) {
			s = t->start;
			inlen = t->len;
			zero_copy = TRUE;
			if (t->own) {
				t->own = FALSE;
				grab_own = TRUE;
			}
		}
	}

	if (s != NULL) {
		if (zero_copy) {
			/* Decode in place */
			outlen = g_base64_decode_step (s, inlen, (guchar *)s, &state, &save);
			t = lua_newuserdata (L, sizeof (*t));
			rspamd_lua_setclass (L, "rspamd{text}", -1);
			t->start = s;
			t->len = outlen;
			t->own = grab_own;
		}
		else {
			t = lua_newuserdata (L, sizeof (*t));
			rspamd_lua_setclass (L, "rspamd{text}", -1);
			t->len = (inlen / 4) * 3 + 3;
			t->start = g_malloc (t->len);
			outlen = g_base64_decode_step (s, inlen, (guchar *)t->start,
					&state, &save);
			t->len = outlen;
			t->own = TRUE;
		}
	}
	else {
		lua_pushnil (L);
	}

	return 1;
}
Ejemplo n.º 2
0
static gint
lua_rsa_privkey_load (lua_State *L)
{
	RSA *rsa = NULL, **prsa;
	const gchar *filename;
	FILE *f;

	filename = luaL_checkstring (L, 1);
	if (filename != NULL) {
		f = fopen (filename, "r");
		if (f == NULL) {
			msg_err ("cannot open private key from file: %s, %s",
				filename,
				strerror (errno));
			lua_pushnil (L);
		}
		else {
			if (!PEM_read_RSAPrivateKey (f, &rsa, NULL, NULL)) {
				msg_err ("cannot open private key from file: %s, %s", filename,
					ERR_error_string (ERR_get_error (), NULL));
				lua_pushnil (L);
			}
			else {
				prsa = lua_newuserdata (L, sizeof (RSA *));
				rspamd_lua_setclass (L, "rspamd{rsa_privkey}", -1);
				*prsa = rsa;
			}
			fclose (f);
		}
	}
	else {
		lua_pushnil (L);
	}
	return 1;
}
Ejemplo n.º 3
0
/***
 * @function rspamd_cryptobox_hash.create([string])
 * Creates new hash context
 * @param {string} data optional string to hash
 * @return {cryptobox_hash} hash object
 */
static gint
lua_cryptobox_hash_create (lua_State *L)
{
	struct rspamd_lua_cryptobox_hash *h, **ph;
	const gchar *s = NULL;
	struct rspamd_lua_text *t;
	gsize len = 0;

	h = rspamd_lua_hash_create (NULL);

	if (lua_type (L, 1) == LUA_TSTRING) {
		s = lua_tolstring (L, 1, &len);
	}
	else if (lua_type (L, 1) == LUA_TUSERDATA) {
		t = lua_check_text (L, 1);

		if (!t) {
			return luaL_error (L, "invalid arguments");
		}

		s = t->start;
		len = t->len;
	}

	if (s) {
		rspamd_lua_hash_update (h, s, len);
	}

	ph = lua_newuserdata (L, sizeof (void *));
	*ph = h;
	rspamd_lua_setclass (L, "rspamd{cryptobox_hash}", -1);

	return 1;
}
Ejemplo n.º 4
0
/* Return table of statfiles indexed by name */
static gint
lua_classifier_get_statfiles (lua_State *L)
{
	struct rspamd_classifier_config *ccf = lua_check_classifier (L);
	GList *cur;
	struct rspamd_statfile_config *st, **pst;
	gint i;

	if (ccf) {
		lua_newtable (L);
		cur = g_list_first (ccf->statfiles);
		i = 1;
		while (cur) {
			st = cur->data;
			pst = lua_newuserdata (L, sizeof (struct rspamd_statfile_config *));
			rspamd_lua_setclass (L, "rspamd{statfile}", -1);
			*pst = st;
			lua_rawseti (L, -2, i++);

			cur = g_list_next (cur);
		}
	}
	else {
		lua_pushnil (L);
	}

	return 1;
}
Ejemplo n.º 5
0
static gint
lua_config_add_kv_map (lua_State *L)
{
	struct rspamd_config *cfg = lua_check_config (L);
	const gchar *map_line, *description;
	GHashTable **r, ***ud;

	if (cfg) {
		map_line = luaL_checkstring (L, 2);
		description = lua_tostring (L, 3);
		r = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (GHashTable *));
		*r = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal);
		if (!add_map (cfg, map_line, description, read_kv_list, fin_kv_list,
			(void **)r)) {
			msg_warn ("invalid hash map %s", map_line);
			g_hash_table_destroy (*r);
			lua_pushnil (L);
			return 1;
		}
		rspamd_mempool_add_destructor (cfg->cfg_pool,
			(rspamd_mempool_destruct_t)g_hash_table_destroy,
			*r);
		ud = lua_newuserdata (L, sizeof (GHashTable *));
		*ud = r;
		rspamd_lua_setclass (L, "rspamd{hash_table}", -1);

		return 1;
	}

	lua_pushnil (L);
	return 1;

}
Ejemplo n.º 6
0
/* Get statfile with specified label */
static gint
lua_classifier_get_statfile_by_label (lua_State *L)
{
	struct rspamd_classifier_config *ccf = lua_check_classifier (L);
	struct rspamd_statfile_config *st, **pst;
	const gchar *label;
	GList *cur;
	gint i;

	label = luaL_checkstring (L, 2);
	if (ccf && label) {
		cur = g_hash_table_lookup (ccf->labels, label);
		if (cur) {
			lua_newtable (L);
			i = 1;
			while (cur) {
				st = cur->data;
				pst =
					lua_newuserdata (L,
						sizeof (struct rspamd_statfile_config *));
				rspamd_lua_setclass (L, "rspamd{statfile}", -1);
				*pst = st;
				lua_rawseti (L, -2, i++);
				cur = g_list_next (cur);
			}
			return 1;
		}
	}
	lua_pushnil (L);
	return 1;
}
Ejemplo n.º 7
0
static gint
lua_config_add_radix_map (lua_State *L)
{
	struct rspamd_config *cfg = lua_check_config (L);
	const gchar *map_line, *description;
	radix_compressed_t **r, ***ud;

	if (cfg) {
		map_line = luaL_checkstring (L, 2);
		description = lua_tostring (L, 3);
		r = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (radix_compressed_t *));
		*r = radix_create_compressed ();
		if (!add_map (cfg, map_line, description, read_radix_list,
			fin_radix_list, (void **)r)) {
			msg_warn ("invalid radix map %s", map_line);
			radix_destroy_compressed (*r);
			lua_pushnil (L);
			return 1;
		}
		ud = lua_newuserdata (L, sizeof (radix_compressed_t *));
		*ud = r;
		rspamd_lua_setclass (L, "rspamd{radix}", -1);

		return 1;
	}

	lua_pushnil (L);
	return 1;

}
Ejemplo n.º 8
0
void
rspamd_lua_call_pre_filters (struct rspamd_task *task)
{
	struct lua_callback_data *cd;
	struct rspamd_task **ptask;
	GList *cur;

	cur = task->cfg->pre_filters;
	while (cur) {
		cd = cur->data;
		if (cd->cb_is_ref) {
			lua_rawgeti (cd->L, LUA_REGISTRYINDEX, cd->callback.ref);
		}
		else {
			lua_getglobal (cd->L, cd->callback.name);
		}
		ptask = lua_newuserdata (cd->L, sizeof (struct rspamd_task *));
		rspamd_lua_setclass (cd->L, "rspamd{task}", -1);
		*ptask = task;

		if (lua_pcall (cd->L, 1, 0, 0) != 0) {
			msg_info ("call to %s failed: %s",
				cd->cb_is_ref ? "local function" :
				cd->callback.name,
				lua_tostring (cd->L, -1));
		}
		cur = g_list_next (cur);
	}
}
Ejemplo n.º 9
0
static gint
lua_config_get_classifier (lua_State * L)
{
	struct rspamd_config *cfg = lua_check_config (L);
	struct rspamd_classifier_config *clc = NULL, **pclc = NULL;
	const gchar *name;
	GList *cur;

	if (cfg) {
		name = luaL_checkstring (L, 2);

		cur = g_list_first (cfg->classifiers);
		while (cur) {
			clc = cur->data;
			if (g_ascii_strcasecmp (clc->classifier->name, name) == 0) {
				pclc = &clc;
				break;
			}
			cur = g_list_next (cur);
		}
		if (pclc) {
			pclc = lua_newuserdata (L,
					sizeof (struct rspamd_classifier_config *));
			rspamd_lua_setclass (L, "rspamd{classifier}", -1);
			*pclc = clc;
			return 1;
		}
	}

	lua_pushnil (L);
	return 1;

}
Ejemplo n.º 10
0
/***
 * @function rspamd_fann.load(file)
 * Loads neural network from the file
 * @param {string} file filename where fann is stored
 * @return {fann} fann object
 */
static gint
lua_fann_load_file (lua_State *L)
{
#ifndef WITH_FANN
	return 0;
#else
	struct fann *f, **pfann;
	const gchar *fname;

	fname = luaL_checkstring (L, 1);

	if (fname != NULL) {
		f = fann_create_from_file (fname);

		if (f != NULL) {
			pfann = lua_newuserdata (L, sizeof (gpointer));
			*pfann = f;
			rspamd_lua_setclass (L, "rspamd{fann}", -1);
		}
		else {
			lua_pushnil (L);
		}
	}
	else {
		lua_pushnil (L);
	}

	return 1;
#endif
}
Ejemplo n.º 11
0
static void
lua_io_err_cb (GError * err, void *arg)
{
	struct lua_dispatcher_cbdata *cbdata = arg;
	rspamd_io_dispatcher_t **pdispatcher;

	/* callback (dispatcher, err) */
	lua_rawgeti (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_err);
	pdispatcher =
		lua_newuserdata (cbdata->L, sizeof (struct rspamd_io_dispatcher_s *));
	rspamd_lua_setclass (cbdata->L, "rspamd{io_dispatcher}", -1);
	*pdispatcher = cbdata->d;
	lua_pushstring (cbdata->L, err->message);

	if (lua_pcall (cbdata->L, 2, 0, 0) != 0) {
		msg_info ("call to session finalizer failed: %s",
			lua_tostring (cbdata->L, -1));
		lua_pop (cbdata->L, 1);
	}

	/* Unref callbacks */
	luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_read);
	if (cbdata->cbref_write) {
		luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_write);
	}
	luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_err);

	g_error_free (err);
	g_slice_free1 (sizeof (struct lua_dispatcher_cbdata), cbdata);
}
Ejemplo n.º 12
0
static gint
lua_rsa_privkey_create (lua_State *L)
{
	RSA *rsa = NULL, **prsa;
	const gchar *buf;
	BIO *bp;

	buf = luaL_checkstring (L, 1);
	if (buf != NULL) {
		bp = BIO_new_mem_buf ((void *)buf, -1);

		if (!PEM_read_bio_RSAPrivateKey (bp, &rsa, NULL, NULL)) {
			msg_err ("cannot parse private key: %s",
				ERR_error_string (ERR_get_error (), NULL));
			lua_pushnil (L);
		}
		else {
			prsa = lua_newuserdata (L, sizeof (RSA *));
			rspamd_lua_setclass (L, "rspamd{rsa_privkey}", -1);
			*prsa = rsa;
		}
		BIO_free (bp);
	}
	else {
		lua_pushnil (L);
	}
	return 1;
}
Ejemplo n.º 13
0
static gboolean
lua_html_node_foreach_cb (GNode *n, gpointer d)
{
	struct lua_html_traverse_ud *ud = d;
	struct html_tag *tag = n->data, **ptag;

	if (tag && (ud->tag_id == -1 || ud->tag_id == tag->id)) {

		lua_rawgeti (ud->L, LUA_REGISTRYINDEX, ud->cbref);

		ptag = lua_newuserdata (ud->L, sizeof (*ptag));
		*ptag = tag;
		rspamd_lua_setclass (ud->L, "rspamd{html_tag}", -1);
		lua_pushnumber (ud->L, tag->content_length);

		if (lua_pcall (ud->L, 2, 1, 0) != 0) {
			msg_err ("error in foreach_tag callback: %s", lua_tostring (ud->L, -1));
			lua_pop (ud->L, 1);
			return TRUE;
		}

		if (lua_toboolean (ud->L, -1)) {
			lua_pop (ud->L, 1);
			return TRUE;
		}

		lua_pop (ud->L, 1);
	}

	return FALSE;
}
Ejemplo n.º 14
0
static gboolean
lua_io_write_cb (void *arg)
{
	struct lua_dispatcher_cbdata *cbdata = arg;
	gboolean res = FALSE;
	rspamd_io_dispatcher_t **pdispatcher;

	if (cbdata->cbref_write) {
		lua_rawgeti (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_read);
		/* callback (dispatcher) */
		pdispatcher =
			lua_newuserdata (cbdata->L,
				sizeof (struct rspamd_io_dispatcher_s *));
		rspamd_lua_setclass (cbdata->L, "rspamd{io_dispatcher}", -1);
		*pdispatcher = cbdata->d;


		if (lua_pcall (cbdata->L, 1, 1, 0) != 0) {
			msg_info ("call to session finalizer failed: %s",
				lua_tostring (cbdata->L, -1));
			lua_pop (cbdata->L, 1);
		}

		res = lua_toboolean (cbdata->L, -1);
		lua_pop (cbdata->L, 1);
	}

	return res;
}
Ejemplo n.º 15
0
static gint
lua_util_load_rspamd_config (lua_State *L)
{
	struct rspamd_config *cfg, **pcfg;
	const gchar *cfg_name;

	cfg_name = luaL_checkstring (L, 1);

	if (cfg_name) {
		cfg = g_malloc0 (sizeof (struct rspamd_config));
		rspamd_init_cfg (cfg, FALSE);
		cfg->cache = rspamd_symbols_cache_new ();

		if (rspamd_config_read (cfg, cfg_name, NULL, NULL, NULL)) {
			msg_err ("cannot load config from %s", cfg_name);
			lua_pushnil (L);
		}
		else {
			rspamd_config_post_load (cfg);
			rspamd_symbols_cache_init (cfg->cache, cfg);
			pcfg = lua_newuserdata (L, sizeof (struct rspamd_config *));
			rspamd_lua_setclass (L, "rspamd{config}", -1);
			*pcfg = cfg;
		}
	}

	return 1;
}
Ejemplo n.º 16
0
static void
lua_html_push_image (lua_State *L, struct html_image *img)
{
	struct html_tag **ptag;

	lua_newtable (L);

	if (img->src) {
		lua_pushstring (L, "src");
		lua_pushstring (L, img->src);
		lua_settable (L, -3);
	}

	if (img->tag) {
		lua_pushstring (L, "tag");
		ptag = lua_newuserdata (L, sizeof (gpointer));
		*ptag = img->tag;
		rspamd_lua_setclass (L, "rspamd{html_tag}", -1);
		lua_settable (L, -3);
	}

	lua_pushstring (L, "height");
	lua_pushnumber (L, img->height);
	lua_settable (L, -3);
	lua_pushstring (L, "width");
	lua_pushnumber (L, img->width);
	lua_settable (L, -3);
	lua_pushstring (L, "embedded");
	lua_pushboolean (L, img->flags & RSPAMD_HTML_FLAG_IMAGE_EMBEDDED);
	lua_settable (L, -3);
}
Ejemplo n.º 17
0
static gint
lua_html_tag_get_extra (lua_State *L)
{
	struct html_tag *tag = lua_check_html_tag (L, 1);
	struct html_image *img;
	struct rspamd_url **purl;

	if (tag) {
		if (tag->extra) {
			if (tag->id == Tag_A || tag->id == Tag_IFRAME) {
				/* For A that's URL */
				purl = lua_newuserdata (L, sizeof (gpointer));
				*purl = tag->extra;
				rspamd_lua_setclass (L, "rspamd{url}", -1);
			}
			else if (tag->id == Tag_IMG) {
				img = tag->extra;
				lua_html_push_image (L, img);
			}
			else {
				/* Unknown extra ? */
				lua_pushnil (L);
			}
		}
		else {
			lua_pushnil (L);
		}
	}
	else {
		lua_error (L);
	}

	return 1;
}
Ejemplo n.º 18
0
static gint
lua_util_config_from_ucl (lua_State *L)
{
	struct rspamd_config *cfg, **pcfg;
	struct rspamd_rcl_section *top;
	GError *err = NULL;
	ucl_object_t *obj;

	obj = ucl_object_lua_import (L, 1);

	if (obj) {
		cfg = g_malloc0 (sizeof (struct rspamd_config));
		rspamd_init_cfg (cfg, FALSE);
		cfg->lua_state = L;
		cfg->rcl_obj = obj;
		cfg->cache = rspamd_symbols_cache_new ();
		top = rspamd_rcl_config_init ();

		if (!rspamd_rcl_parse (top, cfg, cfg->cfg_pool, cfg->rcl_obj, &err)) {
			msg_err ("rcl parse error: %s", err->message);
			ucl_object_unref (obj);
			lua_pushnil (L);
		}
		else {
			rspamd_config_post_load (cfg);
			rspamd_symbols_cache_init (cfg->cache, cfg);
			pcfg = lua_newuserdata (L, sizeof (struct rspamd_config *));
			rspamd_lua_setclass (L, "rspamd{config}", -1);
			*pcfg = cfg;
		}
	}

	return 1;
}
Ejemplo n.º 19
0
/**
 * Push error of redis request to lua callback
 * @param code
 * @param ud
 */
static void
lua_redis_push_error (const gchar *err,
	struct lua_redis_userdata *ud,
	gboolean connected)
{
	struct rspamd_task **ptask;

	/* Push error */
	lua_rawgeti (ud->L, LUA_REGISTRYINDEX, ud->cbref);
	ptask = lua_newuserdata (ud->L, sizeof (struct rspamd_task *));
	rspamd_lua_setclass (ud->L, "rspamd{task}", -1);

	*ptask = ud->task;
	/* String of error */
	lua_pushstring (ud->L, err);
	/* Data is nil */
	lua_pushnil (ud->L);
	if (lua_pcall (ud->L, 3, 0, 0) != 0) {
		msg_info ("call to callback failed: %s", lua_tostring (ud->L, -1));
	}

	if (connected) {
		rspamd_session_remove_event (ud->task->s, lua_redis_fin, ud);
	}
}
Ejemplo n.º 20
0
static gboolean
lua_io_read_cb (rspamd_ftok_t * in, void *arg)
{
	struct lua_dispatcher_cbdata *cbdata = arg;
	gboolean res;
	rspamd_io_dispatcher_t **pdispatcher;

	/* callback (dispatcher, data) */
	lua_rawgeti (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_read);
	pdispatcher =
		lua_newuserdata (cbdata->L, sizeof (struct rspamd_io_dispatcher_s *));
	rspamd_lua_setclass (cbdata->L, "rspamd{io_dispatcher}", -1);
	*pdispatcher = cbdata->d;
	lua_pushlstring (cbdata->L, in->begin, in->len);

	if (lua_pcall (cbdata->L, 2, 1, 0) != 0) {
		msg_info ("call to session finalizer failed: %s",
			lua_tostring (cbdata->L, -1));
		lua_pop (cbdata->L, 1);
	}

	res = lua_toboolean (cbdata->L, -1);
	lua_pop (cbdata->L, 1);

	return res;
}
Ejemplo n.º 21
0
/***
 * @function rspamd_fann.load_data(data)
 * Loads neural network from the data
 * @param {string} file filename where fann is stored
 * @return {fann} fann object
 */
static gint
lua_fann_load_data (lua_State *L)
{
#ifndef WITH_FANN
	return 0;
#else
	struct fann *f, **pfann;
	gint fd;
	struct rspamd_lua_text *t;
	gchar fpath[PATH_MAX];

	if (lua_type (L, 1) == LUA_TUSERDATA) {
		t = lua_check_text (L, 1);

		if (!t) {
			return luaL_error (L, "text required");
		}
	}
	else {
		t = g_alloca (sizeof (*t));
		t->start = lua_tolstring (L, 1, (gsize *)&t->len);
		t->flags = 0;
	}

	/* We need to save data to file because of libfann stupidity */
	rspamd_strlcpy (fpath, "/tmp/rspamd-fannXXXXXXXXXX", sizeof (fpath));
	fd = mkstemp (fpath);

	if (fd == -1) {
		msg_warn ("cannot create tempfile: %s", strerror (errno));
		lua_pushnil (L);
	}
	else {
		if (write (fd, t->start, t->len) == -1) {
			msg_warn ("cannot write tempfile: %s", strerror (errno));
			lua_pushnil (L);
			unlink (fpath);
			close (fd);

			return 1;
		}

		f = fann_create_from_file (fpath);
		unlink (fpath);
		close (fd);

		if (f != NULL) {
			pfann = lua_newuserdata (L, sizeof (gpointer));
			*pfann = f;
			rspamd_lua_setclass (L, "rspamd{fann}", -1);
		}
		else {
			lua_pushnil (L);
		}
	}

	return 1;
#endif
}
Ejemplo n.º 22
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;

}
Ejemplo n.º 23
0
/***
 * @function rspamd_fann:data()
 * Returns serialized neural network
 * @return {rspamd_text} fann data
 */
static gint
lua_fann_data (lua_State *L)
{
#ifndef WITH_FANN
	return 0;
#else
	struct fann *f = rspamd_lua_check_fann (L, 1);
	gint fd;
	struct rspamd_lua_text *res;
	gchar fpath[PATH_MAX];
	gpointer map;
	gsize sz;

	if (f == NULL) {
		return luaL_error (L, "invalid arguments");
	}

	/* We need to save data to file because of libfann stupidity */
	rspamd_strlcpy (fpath, "/tmp/rspamd-fannXXXXXXXXXX", sizeof (fpath));
	fd = mkstemp (fpath);

	if (fd == -1) {
		msg_warn ("cannot create tempfile: %s", strerror (errno));
		lua_pushnil (L);
	}
	else {
		if (fann_save (f, fpath) == -1) {
			msg_warn ("cannot write tempfile: %s", strerror (errno));
			lua_pushnil (L);
			unlink (fpath);
			close (fd);

			return 1;
		}


		(void)lseek (fd, 0, SEEK_SET);
		map = rspamd_file_xmap (fpath, PROT_READ, &sz, TRUE);
		unlink (fpath);
		close (fd);

		if (map != NULL) {
			res = lua_newuserdata (L, sizeof (*res));
			res->len = sz;
			res->start = map;
			res->flags = RSPAMD_TEXT_FLAG_OWN|RSPAMD_TEXT_FLAG_MMAPED;
			rspamd_lua_setclass (L, "rspamd{text}", -1);
		}
		else {
			lua_pushnil (L);
		}

	}

	return 1;
#endif
}
Ejemplo n.º 24
0
/**
 * Sign file using specified rsa key and signature
 *
 * arguments:
 * (rsa_privkey, rsa_signature, string)
 *
 * returns:
 * true - if string match rsa signature
 * false - otherwise
 */
static gint
lua_rsa_sign_file (lua_State *L)
{
	RSA *rsa;
	rspamd_fstring_t *signature, **psig;
	const gchar *filename;
	gchar *data = NULL, *data_sig;
	gint ret, fd;
	struct stat st;

	rsa = lua_check_rsa_privkey (L, 1);
	filename = luaL_checkstring (L, 2);

	if (rsa != NULL && filename != NULL) {
		fd = open (filename, O_RDONLY);
		if (fd == -1) {
			msg_err ("cannot open file %s: %s", filename, strerror (errno));
			lua_pushnil (L);
		}
		else {
			if (fstat (fd, &st) == -1 ||
				(data =
				mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd,
				0)) == MAP_FAILED) {
				msg_err ("cannot mmap file %s: %s", filename, strerror (errno));
				lua_pushnil (L);
			}
			else {
				signature = rspamd_fstring_sized_new (RSA_size (rsa));
				data_sig = g_compute_checksum_for_string (G_CHECKSUM_SHA256,
						data,
						st.st_size);
				ret = RSA_sign (NID_sha1, data_sig, strlen (data_sig),
						signature->str, (guint *)&signature->len, rsa);
				if (ret == 0) {
					msg_info ("cannot make a signature for data: %s",
						ERR_error_string (ERR_get_error (), NULL));
					lua_pushnil (L);
					rspamd_fstring_free (signature);
				}
				else {
					psig = lua_newuserdata (L, sizeof (rspamd_fstring_t *));
					rspamd_lua_setclass (L, "rspamd{rsa_signature}", -1);
					*psig = signature;
				}
				g_free (data_sig);
				munmap (data, st.st_size);
			}
			close (fd);
		}
	}
	else {
		lua_pushnil (L);
	}

	return 1;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
0
static void
lua_metric_symbol_callback (struct rspamd_task *task, gpointer ud)
{
	struct lua_callback_data *cd = ud;
	struct rspamd_task **ptask;
	gint level = lua_gettop (cd->L), nresults;

	if (cd->cb_is_ref) {
		lua_rawgeti (cd->L, LUA_REGISTRYINDEX, cd->callback.ref);
	}
	else {
		lua_getglobal (cd->L, cd->callback.name);
	}
	ptask = lua_newuserdata (cd->L, sizeof (struct rspamd_task *));
	rspamd_lua_setclass (cd->L, "rspamd{task}", -1);
	*ptask = task;

	if (lua_pcall (cd->L, 1, LUA_MULTRET, 0) != 0) {
		msg_info ("call to (%s)%s failed: %s", cd->symbol,
			cd->cb_is_ref ? "local function" : cd->callback.name,
			lua_tostring (cd->L, -1));
	}

	nresults = lua_gettop (cd->L) - level;
	if (nresults >= 1) {
		/* Function returned boolean, so maybe we need to insert result? */
		gboolean res;
		GList *opts = NULL;
		gint i;
		gdouble flag = 1.0;

		if (lua_type (cd->L, level + 1) == LUA_TBOOLEAN) {
			res = lua_toboolean (cd->L, level + 1);
			if (res) {
				gint first_opt = 2;

				if (lua_type (cd->L, level + 2) == LUA_TNUMBER) {
					flag = lua_tonumber (cd->L, level + 2);
					/* Shift opt index */
					first_opt = 3;
				}

				for (i = lua_gettop (cd->L); i >= level + first_opt; i --) {
					if (lua_type (cd->L, i) == LUA_TSTRING) {
						const char *opt = lua_tostring (cd->L, i);

						opts = g_list_prepend (opts,
							rspamd_mempool_strdup (task->task_pool, opt));
					}
				}
				rspamd_task_insert_result (task, cd->symbol, flag, opts);
			}
		}
		lua_pop (cd->L, nresults);
	}
}
Ejemplo n.º 27
0
static gboolean rspamd_lua_call_expression_func(
		struct ucl_lua_funcdata *lua_data, struct rspamd_task *task,
		GArray *args, gint *res)
{
	lua_State *L = lua_data->L;
	struct rspamd_task **ptask;
	struct expression_argument *arg;
	gint pop = 0, i, nargs = 0;

	lua_rawgeti (L, LUA_REGISTRYINDEX, lua_data->idx);
	/* Now we got function in top of stack */
	ptask = lua_newuserdata (L, sizeof(struct rspamd_task *));
	rspamd_lua_setclass (L, "rspamd{task}", -1);
	*ptask = task;

	/* Now push all arguments */
	if (args) {
		for (i = 0; i < (gint)args->len; i ++) {
			arg = &g_array_index (args, struct expression_argument, i);
			if (arg) {
				switch (arg->type) {
				case EXPRESSION_ARGUMENT_NORMAL:
					lua_pushstring (L, (const gchar *) arg->data);
					break;
				case EXPRESSION_ARGUMENT_BOOL:
					lua_pushboolean (L, (gboolean) GPOINTER_TO_SIZE(arg->data));
					break;
				default:
					msg_err_task ("cannot pass custom params to lua function");
					return FALSE;
				}
			}
		}
		nargs = args->len;
	}

	if (lua_pcall (L, nargs + 1, 1, 0) != 0) {
		msg_info_task ("call to lua function failed: %s", lua_tostring (L, -1));
		return FALSE;
	}
	pop++;

	if (lua_type (L, -1) == LUA_TNUMBER) {
		*res = lua_tonumber (L, -1);
	}
	else if (lua_type (L, -1) == LUA_TBOOLEAN) {
		*res = lua_toboolean (L, -1);
	}
	else {
		msg_info_task ("lua function must return a boolean");
	}

	lua_pop (L, pop);

	return TRUE;
}
Ejemplo n.º 28
0
static gint
lua_util_create_event_base (lua_State *L)
{
	struct event_base **pev_base;

	pev_base = lua_newuserdata (L, sizeof (struct event_base *));
	rspamd_lua_setclass (L, "rspamd{ev_base}", -1);
	*pev_base = event_init ();

	return 1;
}
Ejemplo n.º 29
0
static void
lua_url_single_inserter (struct rspamd_url *url, gsize start_offset,
		gsize end_offset, gpointer ud)
{
	lua_State *L = ud;
	struct rspamd_lua_url *lua_url;

	lua_url = lua_newuserdata (L, sizeof (struct rspamd_lua_url));
	rspamd_lua_setclass (L, "rspamd{url}", -1);
	lua_url->url = url;
}
Ejemplo n.º 30
0
/***
 * @function rspamd_cryptobox_pubkey.create(data[, type[, alg]])
 * Loads public key from base32 encoded file
 * @param {base32 string} base32 string with the key
 * @param {string} type optional 'sign' or 'kex' for signing and encryption
 * @param {string} alg optional 'default' or 'nist' for curve25519/nistp256 keys
 * @return {cryptobox_pubkey} new public key
 */
static gint
lua_cryptobox_pubkey_create (lua_State *L)
{
	struct rspamd_cryptobox_pubkey *pkey = NULL, **ppkey;
	const gchar *buf, *arg;
	gsize len;
	gint type = RSPAMD_KEYPAIR_SIGN;
	gint alg = RSPAMD_CRYPTOBOX_MODE_25519;

	buf = luaL_checklstring (L, 1, &len);
	if (buf != NULL) {
		if (lua_type (L, 2) == LUA_TSTRING) {
			/* keypair type */
			arg = lua_tostring (L, 2);

			if (strcmp (arg, "sign") == 0) {
				type = RSPAMD_KEYPAIR_SIGN;
			}
			else if (strcmp (arg, "kex") == 0) {
				type = RSPAMD_KEYPAIR_KEX;
			}
		}
		if (lua_type (L, 3) == LUA_TSTRING) {
			/* algorithm */
			arg = lua_tostring (L, 3);

			if (strcmp (arg, "default") == 0 || strcmp (arg, "curve25519") == 0) {
				type = RSPAMD_CRYPTOBOX_MODE_25519;
			}
			else if (strcmp (arg, "nist") == 0) {
				type = RSPAMD_CRYPTOBOX_MODE_NIST;
			}
		}

		pkey = rspamd_pubkey_from_base32 (buf, len, type, alg);

		if (pkey == NULL) {
			msg_err ("cannot load pubkey from string");
			lua_pushnil (L);
		}
		else {
			ppkey = lua_newuserdata (L, sizeof (void *));
			rspamd_lua_setclass (L, "rspamd{cryptobox_pubkey}", -1);
			*ppkey = pkey;
		}

	}
	else {
		return luaL_error (L, "bad input arguments");
	}

	return 1;
}