Beispiel #1
0
static gboolean
lua_tcp_arg_toiovec (lua_State *L, gint pos, rspamd_mempool_t *pool,
		struct iovec *vec)
{
	struct rspamd_lua_text *t;
	gsize len;
	const gchar *str;

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

		if (t) {
			vec->iov_base = (void *)t->start;
			vec->iov_len = t->len;
		}
		else {
			return FALSE;
		}
	}
	else if (lua_type (L, pos) == LUA_TSTRING) {
		str = luaL_checklstring (L, pos, &len);
		vec->iov_base = rspamd_mempool_alloc (pool, len + 1);
		rspamd_strlcpy (vec->iov_base, str, len + 1);
		vec->iov_len = len;
	}
	else {
		return FALSE;
	}

	return TRUE;
}
Beispiel #2
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;
}
Beispiel #3
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
}
Beispiel #4
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;
}
Beispiel #5
0
static gint
lua_util_encode_base64 (lua_State *L)
{
	struct rspamd_lua_text *t;
	const gchar *s = NULL;
	gchar *out;
	gsize inlen, outlen;
	guint str_lim = 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;
		}
	}

	if (lua_gettop (L) > 1) {
		str_lim = luaL_checknumber (L, 2);
	}

	if (s == NULL) {
		lua_pushnil (L);
	}
	else {
		out = rspamd_encode_base64 (s, inlen, str_lim, &outlen);

		if (out != NULL) {
			t = lua_newuserdata (L, sizeof (*t));
			rspamd_lua_setclass (L, "rspamd{text}", -1);
			t->start = out;
			t->len = outlen;
			/* Need destruction */
			t->own = TRUE;
		}
		else {
			lua_pushnil (L);
		}
	}

	return 1;
}
Beispiel #6
0
/***
 * @function rspamd_cryptobox.verify_memory(pk, sig, data)
 * Check memory using specified cryptobox key and signature
 * @param {pubkey} pk public key to verify
 * @param {sig} signature to check
 * @param {string} data data to check signature against
 * @return {boolean} `true` - if string matches cryptobox signature
 */
static gint
lua_cryptobox_verify_memory (lua_State *L)
{
	struct rspamd_cryptobox_pubkey *pk;
	rspamd_fstring_t *signature;
	struct rspamd_lua_text *t;
	const gchar *data;
	gsize len;
	gint ret;

	pk = lua_check_cryptobox_pubkey (L, 1);
	signature = lua_check_cryptobox_sign (L, 2);

	if (lua_isuserdata (L, 3)) {
		t = lua_check_text (L, 3);

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

		data = t->start;
		len = t->len;
	}
	else {
		data = luaL_checklstring (L, 3, &len);
	}

	if (pk != NULL && signature != NULL && data != NULL) {
		ret = rspamd_cryptobox_verify (signature->str, data, len,
				rspamd_pubkey_get_pk (pk, NULL), RSPAMD_CRYPTOBOX_MODE_25519);

		if (ret) {
			lua_pushboolean (L, 1);
		}
		else {
			lua_pushboolean (L, 0);
		}
	}
	else {
		return luaL_error (L, "invalid arguments");
	}

	return 1;
}
Beispiel #7
0
/***
 * @function rspamd_cryptobox.sign_memory(kp, data)
 * Sign data using specified keypair
 * @param {keypair} kp keypair to sign
 * @param {string} data
 * @return {cryptobox_signature} signature object
 */
static gint
lua_cryptobox_sign_memory (lua_State *L)
{
	struct rspamd_cryptobox_keypair *kp;
	const gchar *data;
	struct rspamd_lua_text *t;
	gsize len = 0;
	rspamd_fstring_t *sig, **psig;

	kp = lua_check_cryptobox_keypair (L, 1);

	if (lua_isuserdata (L, 2)) {
		t = lua_check_text (L, 2);

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

		data = t->start;
		len = t->len;
	}
	else {
		data = luaL_checklstring (L, 2, &len);
	}


	if (!kp || !data) {
		return luaL_error (L, "invalid arguments");
	}

	sig = rspamd_fstring_sized_new (rspamd_cryptobox_signature_bytes (
			rspamd_keypair_alg (kp)));
	rspamd_cryptobox_sign (sig->str, &sig->len, data,
			len, rspamd_keypair_component (kp, RSPAMD_KEYPAIR_COMPONENT_SK,
					NULL), rspamd_keypair_alg (kp));

	psig = lua_newuserdata (L, sizeof (void *));
	*psig = sig;
	rspamd_lua_setclass (L, "rspamd{cryptobox_signature}", -1);

	return 1;
}
Beispiel #8
0
/***
 * @method cryptobox_hash:update(data)
 * Updates hash with the specified data (hash should not be finalized using `hex` or `bin` methods)
 * @param {string} data data to hash
 */
static gint
lua_cryptobox_hash_update (lua_State *L)
{
	rspamd_cryptobox_hash_state_t *h = lua_check_cryptobox_hash (L, 1);
	const gchar *data;
	struct rspamd_lua_text *t;
	gsize len;

	if (lua_isuserdata (L, 2)) {
		t = lua_check_text (L, 2);

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

		data = t->start;
		len = t->len;
	}
	else {
		data = luaL_checklstring (L, 2, &len);
	}

	if (lua_isnumber (L, 3)) {
		gsize nlen = lua_tonumber (L, 3);

		if (nlen > len) {
			return luaL_error (L, "invalid length: %d while %d is available",
					(int)nlen, (int)len);
		}

		len = nlen;
	}

	if (h && data) {
		rspamd_cryptobox_hash_update (h, data, len);
	}
	else {
		return luaL_error (L, "invalid arguments");
	}

	return 0;
}
Beispiel #9
0
/***
 * @function rspamd_cryptobox_signature.create(data)
 * Creates signature object from raw data
 * @param {data} raw signature data
 * @return {cryptobox_signature} signature object
 */
static gint
lua_cryptobox_signature_create (lua_State *L)
{
	rspamd_fstring_t *sig, **psig;
	struct rspamd_lua_text *t;
	const gchar *data;
	gsize dlen;

	if (lua_isuserdata (L, 1)) {
		t = lua_check_text (L, 1);

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

		data = t->start;
		dlen = t->len;
	}
	else {
		data = luaL_checklstring (L, 1, &dlen);
	}

	if (data != NULL) {
		if (dlen == rspamd_cryptobox_signature_bytes (RSPAMD_CRYPTOBOX_MODE_25519)) {
			sig = rspamd_fstring_new_init (data, dlen);
			psig = lua_newuserdata (L, sizeof (rspamd_fstring_t *));
			rspamd_lua_setclass (L, "rspamd{cryptobox_signature}", -1);
			*psig = sig;
		}
	}
	else {
		return luaL_error (L, "bad input arguments");
	}

	return 1;
}
Beispiel #10
0
static gint
lua_util_tokenize_text (lua_State *L)
{
	const gchar *in = NULL;
	gsize len, pos, ex_len, i;
	GList *exceptions = NULL, *cur;
	struct rspamd_lua_text *t;
	struct process_exception *ex;
	GArray *res;
	rspamd_fstring_t *w;
	gboolean compat = FALSE;

	if (lua_type (L, 1) == LUA_TSTRING) {
		in = luaL_checklstring (L, 1, &len);
	}
	else if (lua_type (L, 1) == LUA_TTABLE) {
		t = lua_check_text (L, 1);

		if (t) {
			in = t->start;
			len = t->len;
		}
	}

	if (in == NULL) {
		lua_pushnil (L);
		return 1;
	}

	if (lua_gettop (L) > 1 && lua_type (L, 2) == LUA_TTABLE) {
		lua_pushvalue (L, 2);
		lua_pushnil (L);

		while (lua_next (L, -2) != 0) {
			if (lua_type (L, -1) == LUA_TTABLE) {
				lua_rawgeti (L, -1, 1);
				pos = luaL_checknumber (L, -1);
				lua_pop (L, 1);
				lua_rawgeti (L, -1, 2);
				ex_len = luaL_checknumber (L, -1);
				lua_pop (L, 1);

				if (ex_len > 0) {
					ex = g_slice_alloc (sizeof (*ex));
					ex->pos = pos;
					ex->len = ex_len;
					exceptions = g_list_prepend (exceptions, ex);
				}
			}
			lua_pop (L, 1);
		}

		lua_pop (L, 1);
	}

	if (lua_gettop (L) > 2 && lua_type (L, 3) == LUA_TBOOLEAN) {
		compat = lua_toboolean (L, 3);
	}

	if (exceptions) {
		exceptions = g_list_reverse (exceptions);
	}

	res = rspamd_tokenize_text ((gchar *)in, len, TRUE, 0, exceptions, compat);

	if (res == NULL) {
		lua_pushnil (L);
	}
	else {
		lua_newtable (L);

		for (i = 0; i < res->len; i ++) {
			w = &g_array_index (res, rspamd_fstring_t, i);
			lua_pushlstring (L, w->begin, w->len);
			lua_rawseti (L, -2, i + 1);
		}
	}

	cur = exceptions;
	while (cur) {
		ex = cur->data;
		g_slice_free1 (sizeof (*ex), ex);
		cur = g_list_next (cur);
	}

	g_list_free (exceptions);

	return 1;
}