while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) {
if (rspamd_strtoul (cur->key, cur->keylen, &remote_flag) &&
- ucl_object_toint_safe (cur, &local_flag)) {
+ ucl_object_toint_safe (cur, (int64_t *)&local_flag)) {
g_hash_table_insert (ctx->master_flags, GUINT_TO_POINTER (remote_flag),
GUINT_TO_POINTER (local_flag));
}
struct addr_list {
const gchar *name;
+ guint namelen;
const gchar *addr;
+ guint addrlen;
};
#define COMPARE_RCPT_LEN 3
void *unused)
{
struct expression_argument *arg;
- InternetAddressList *cur;
+ struct rspamd_email_address *cur;
double threshold;
struct addr_list *ar;
- gchar *c;
gint num, i, j, hits = 0, total = 0;
if (args == NULL) {
return FALSE;
}
- num = internet_address_list_length (task->rcpt_mime);
+ num = task->rcpt_mime->len;
if (num < MIN_RCPT_TO_COMPARE) {
return FALSE;
}
- ar =
- rspamd_mempool_alloc0 (task->task_pool, num *
- sizeof (struct addr_list));
+
+ ar = rspamd_mempool_alloc0 (task->task_pool, num * sizeof (struct addr_list));
/* Fill array */
- cur = task->rcpt_mime;
-#ifdef GMIME24
- for (i = 0; i < num; i++) {
- InternetAddress *iaelt =
- internet_address_list_get_address(cur, i);
- InternetAddressMailbox *iamb =
- INTERNET_ADDRESS_IS_MAILBOX(iaelt) ?
- INTERNET_ADDRESS_MAILBOX (iaelt) : NULL;
- if (iamb) {
- ar[i].name = internet_address_mailbox_get_addr (iamb);
- if (ar[i].name != NULL && (c = strchr (ar[i].name, '@')) != NULL) {
- ar[i].addr = c + 1;
- }
- }
- }
-#else
- InternetAddress *addr;
- i = 0;
- while (cur) {
- addr = internet_address_list_get_address (cur);
- if (addr && internet_address_get_type (addr) == INTERNET_ADDRESS_NAME) {
- ar[i].name = rspamd_mempool_strdup (task->task_pool,
- internet_address_get_addr (addr));
- if (ar[i].name != NULL && (c = strchr (ar[i].name, '@')) != NULL) {
- *c = '\0';
- ar[i].addr = c + 1;
- }
- cur = internet_address_list_next (cur);
- i++;
- }
- else {
- cur = internet_address_list_next (cur);
- }
+ PTR_ARRAY_FOREACH (task->rcpt_mime, i, cur) {
+ ar[i].name = cur->addr;
+ ar[i].namelen = cur->addr_len;
+ ar[i].addr = cur->domain;
+ ar[i].addrlen = cur->domain_len;
}
-#endif
/* Cycle all elements in array */
for (i = 0; i < num; i++) {
for (j = i + 1; j < num; j++) {
- if (ar[i].name && ar[j].name &&
- g_ascii_strncasecmp (ar[i].name, ar[j].name,
- COMPARE_RCPT_LEN) == 0) {
+ if (ar[i].namelen >= COMPARE_RCPT_LEN && ar[j].namelen >= COMPARE_RCPT_LEN &&
+ rspamd_lc_cmp (ar[i].name, ar[j].name, COMPARE_RCPT_LEN) == 0) {
/* Common name part */
hits++;
}
-#if 0
- /* XXX: when we have a typical mail that is headed towards
- * several users within the same domain, then this rule
- * leads to a false-positive.
- * We actually need to match host against tld, but this is currently
- * too expensive.
- *
- * TODO: think about normal representation of InternetAddress shit
- */
- else if (ar[i].addr && ar[j].addr &&
- g_ascii_strcasecmp (ar[i].addr, ar[j].addr) == 0) {
- /* Common address part, but different name */
- hits++;
- }
-#endif
+
total++;
}
}
}
static gboolean
-is_recipient_list_sorted (const InternetAddressList * ia)
+is_recipient_list_sorted (GPtrArray *ar)
{
- const InternetAddressList *cur;
- InternetAddress *addr;
- InternetAddressMailbox *addr_mb;
+ struct rspamd_email_address *addr;
gboolean res = TRUE;
- struct addr_list current = { NULL, NULL }, previous = {
- NULL, NULL
- };
-#ifdef GMIME24
- gint num, i;
-#endif
+ rspamd_ftok_t cur, prev;
+ gint i;
/* Do not check to short address lists */
- if (internet_address_list_length ((InternetAddressList *)ia) <
- MIN_RCPT_TO_COMPARE) {
+ if (ar == NULL || ar->len < MIN_RCPT_TO_COMPARE) {
return FALSE;
}
-#ifdef GMIME24
- num = internet_address_list_length ((InternetAddressList *)ia);
- cur = ia;
- for (i = 0; i < num; i++) {
- addr =
- internet_address_list_get_address ((InternetAddressList *)cur, i);
- if (INTERNET_ADDRESS_IS_MAILBOX (addr)) {
- addr_mb = INTERNET_ADDRESS_MAILBOX (addr);
- current.addr = (gchar *) internet_address_mailbox_get_addr (addr_mb);
- }
- if (previous.addr != NULL) {
- if (current.addr &&
- g_ascii_strcasecmp (current.addr, previous.addr) <= 0) {
+ PTR_ARRAY_FOREACH (ar, i, addr) {
+ cur.begin = addr->addr;
+ cur.len = addr->addr_len;
+
+ if (prev.len != 0) {
+ if (rspamd_ftok_casecmp (&cur, &prev) <= 0) {
res = FALSE;
break;
}
}
- previous.addr = current.addr;
- }
-#else
- cur = ia;
- while (cur) {
- addr = internet_address_list_get_address (cur);
- if (internet_address_get_type (addr) == INTERNET_ADDRESS_NAME) {
- current.addr = internet_address_get_addr (addr);
- if (previous.addr != NULL) {
- if (current.addr &&
- g_ascii_strcasecmp (current.addr, previous.addr) < 0) {
- res = FALSE;
- break;
- }
- }
- previous.addr = current.addr;
- }
- cur = internet_address_list_next (cur);
+
+ prev = cur;
}
-#endif
return res;
}
#include "unix-std.h"
#include "cryptobox.h"
#include "libutil/multipattern.h"
+#include "libmime/email_addr.h"
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
GError **err)
{
struct rspamd_rcl_struct_parser *pd = ud;
- InternetAddressList **target, *tmp_addr;
+ GPtrArray **target, *tmp_addr = NULL;
const gchar *val;
ucl_object_iter_t it;
const ucl_object_t *cur;
- target = (InternetAddressList **)(((gchar *)pd->user_struct) + pd->offset);
- if (*target == NULL) {
- *target = internet_address_list_new ();
- #ifdef GMIME24
- rspamd_mempool_add_destructor (pool,
- (rspamd_mempool_destruct_t) g_object_unref,
- *target);
- #else
- rspamd_mempool_add_destructor (pool,
- (rspamd_mempool_destruct_t) internet_address_list_destroy,
- *target);
- #endif
- }
-
+ target = (GPtrArray **)(((gchar *)pd->user_struct) + pd->offset);
it = ucl_object_iterate_new (obj);
while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
-
if (ucl_object_type (cur) == UCL_STRING) {
val = ucl_object_tostring (obj);
- tmp_addr = internet_address_list_parse_string (val);
-
- if (tmp_addr) {
- internet_address_list_append (*target, tmp_addr);
-#ifdef GMIME24
- g_object_unref (tmp_addr);
-#else
- internet_address_list_destroy (tmp_addr);
-#endif
- }
- else {
- g_set_error (err,
- CFG_RCL_ERROR,
- EINVAL,
- "cannot parse inet address: %s in %s", val,
- ucl_object_key (obj));
- ucl_object_iterate_free (it);
-
- return FALSE;
- }
+ tmp_addr = rspamd_email_address_from_mime (pool, val,
+ strlen (val), tmp_addr);
}
else {
g_set_error (err,
}
ucl_object_iterate_free (it);
+ *target = tmp_addr;
+
return TRUE;
}
const gchar *
rspamd_task_get_principal_recipient (struct rspamd_task *task)
{
- InternetAddress *iaelt = NULL;
const gchar *val;
struct rspamd_email_address *addr;
}
}
-#ifdef GMIME24
- InternetAddressMailbox *imb;
+ if (task->rcpt_mime != NULL && task->rcpt_mime->len > 0) {
+ addr = g_ptr_array_index (task->rcpt_mime, 0);
- if (task->rcpt_mime != NULL) {
- iaelt = internet_address_list_get_address (task->rcpt_mime, 0);
- }
-
- imb = INTERNET_ADDRESS_IS_MAILBOX(iaelt) ?
- INTERNET_ADDRESS_MAILBOX (iaelt) : NULL;
-
- if (imb) {
- val = internet_address_mailbox_get_addr (imb);
-
- return rspamd_task_cache_principal_recipient (task, val, strlen (val));
- }
-#else
- if (task->rcpt_mime != NULL) {
- iaelt = internet_address_list_get_address (task->rcpt_mime);
- }
-
- if (iaelt) {
- val = internet_address_get_addr (iaelt);
-
- return rspamd_task_cache_principal_recipient (task, val, strlen (val));
+ if (addr->addr) {
+ return rspamd_task_cache_principal_recipient (task, addr->addr,
+ addr->addr_len);
+ }
}
-#endif
return NULL;
}
break;
case RSPAMD_LOG_MIME_RCPT:
case RSPAMD_LOG_MIME_RCPTS:
- if (task->rcpt_mime &&
- internet_address_list_length (task->rcpt_mime) > 0) {
+ if (task->rcpt_mime && task->rcpt_mime->len > 0) {
ret = TRUE;
}
break;
}
break;
case RSPAMD_LOG_MIME_FROM:
- if (task->from_mime &&
- internet_address_list_length (task->from_mime) > 0) {
+ if (task->from_mime && task->from_mime->len > 0) {
ret = TRUE;
}
break;
static rspamd_fstring_t *
rspamd_task_write_ialist (struct rspamd_task *task,
- InternetAddressList *ialist, gint lim,
+ GPtrArray *addrs, gint lim,
struct rspamd_log_format *lf,
rspamd_fstring_t *logbuf)
{
rspamd_fstring_t *res = logbuf, *varbuf;
rspamd_ftok_t var = {.begin = NULL, .len = 0};
- InternetAddressMailbox *iamb;
- InternetAddress *ia = NULL;
+ struct rspamd_email_address *addr;
gint i, nchars = 0, cur_chars;
if (lim <= 0) {
- lim = internet_address_list_length (ialist);
+ lim = addrs->len;
}
-
varbuf = rspamd_fstring_new ();
- for (i = 0; i < lim; i++) {
- ia = internet_address_list_get_address (ialist, i);
-
- if (ia && INTERNET_ADDRESS_IS_MAILBOX (ia)) {
- iamb = INTERNET_ADDRESS_MAILBOX (ia);
- cur_chars = strlen (iamb->addr);
- varbuf = rspamd_fstring_append (varbuf, iamb->addr,
- cur_chars);
- nchars += cur_chars;
+ PTR_ARRAY_FOREACH (addrs, i, addr) {
+ if (i >= lim) {
+ break;
}
+ cur_chars = addr->addr_len;
+ varbuf = rspamd_fstring_append (varbuf, addr->addr,
+ cur_chars);
+ nchars += cur_chars;
if (varbuf->len > 0) {
if (i != lim - 1) {
g_array_append_val (ar, elt);
}
/* Number recipients */
- if (task->rcpt_mime && internet_address_list_length (task->rcpt_mime) > 0) {
+ if (task->rcpt_mime && task->rcpt_mime->len > 0) {
rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "recipients%d",
- (gint)internet_address_list_length (task->rcpt_mime));
+ (gint)task->rcpt_mime->len);
elt.begin = rspamd_mempool_strdup (task->task_pool, tmpbuf);
elt.len = strlen (elt.begin);
g_array_append_val (ar, elt);
guint64 d;
rspamd_cryptobox_hash_state_t bs;
guint64 val;
- gint i, j, k;
+ gint i, j;
gsize hlen, beg = 0;
enum rspamd_cryptobox_fast_hash_type ht;
guint64 res[SHINGLES_WINDOW * RSPAMD_SHINGLE_SIZE], seed;
return tbl_size;
}
-gboolean
-lua_push_internet_address (lua_State *L, InternetAddress *ia)
-{
- const char *addr, *at;
-
-#ifndef GMIME24
- if (internet_address_get_type (ia) == INTERNET_ADDRESS_NAME) {
- lua_newtable (L);
- addr = internet_address_get_addr (ia);
- rspamd_lua_table_set (L, "name", internet_address_get_name (ia));
- rspamd_lua_table_set (L, "addr", addr);
-
- if (addr) {
- at = strchr (addr, '@');
- if (at != NULL) {
- lua_pushstring(L, "user");
- lua_pushlstring(L, addr, at - addr);
- lua_settable (L, -3);
- lua_pushstring (L, "domain");
- lua_pushstring (L, at + 1);
- lua_settable (L, -3);
- }
- }
-
- return TRUE;
- }
- return FALSE;
-#else
- InternetAddressMailbox *iamb;
-
- if (ia && INTERNET_ADDRESS_IS_MAILBOX (ia)) {
- lua_newtable (L);
- iamb = INTERNET_ADDRESS_MAILBOX (ia);
- addr = internet_address_mailbox_get_addr (iamb);
-
- if (addr) {
- rspamd_lua_table_set (L, "name", internet_address_get_name (ia));
- rspamd_lua_table_set (L, "addr", addr);
- /* Set optional fields */
-
- at = strchr (addr, '@');
- if (at != NULL) {
- lua_pushstring(L, "user");
- lua_pushlstring(L, addr, at - addr);
- lua_settable (L, -3);
- lua_pushstring (L, "domain");
- lua_pushstring (L, at + 1);
- lua_settable (L, -3);
- }
- return TRUE;
- }
- }
-
- return FALSE;
-#endif
-}
-
-/*
- * Push internet addresses to lua as a table
- */
-void
-lua_push_internet_address_list (lua_State *L, InternetAddressList *addrs)
-{
- InternetAddress *ia;
- gint idx = 1;
-
-#ifndef GMIME24
- /* Gmime 2.2 version */
- InternetAddressList *cur;
-
- lua_newtable (L);
- cur = addrs;
- while (cur) {
- ia = internet_address_list_get_address (cur);
- if (lua_push_internet_address (L, ia)) {
- lua_rawseti (L, -2, idx++);
- }
- cur = internet_address_list_next (cur);
- }
-#else
- /* Gmime 2.4 version */
- gsize len, i;
-
- lua_newtable (L);
- if (addrs != NULL) {
- len = internet_address_list_length (addrs);
- for (i = 0; i < len; i++) {
- ia = internet_address_list_get_address (addrs, i);
- if (lua_push_internet_address (L, ia)) {
- lua_rawseti (L, -2, idx++);
- }
- }
- }
-#endif
-}
-
-
static void *
rspamd_lua_check_udata_common (lua_State *L, gint pos, const gchar *classname,
gboolean fatal)
*/
guint rspamd_lua_table_size (lua_State *L, gint tbl_pos);
-/**
- * Pushes a single InternetAddress as lua table
- * @param L
- * @param addrs
- */
-void lua_push_internet_address_list (lua_State *L, InternetAddressList *addrs);
-
-/**
- * Pushes internet address list to Lua as table of tables
- * @param L
- * @param ia
- * @return
- */
-gboolean lua_push_internet_address (lua_State *L, InternetAddress *ia);
+void lua_push_emails_address_list (lua_State *L, GPtrArray *addrs);
/**
* Log lua object to string
lua_push_email_address (lua_State *L, struct rspamd_email_address *addr)
{
if (addr) {
- lua_createtable (L, 0, 3);
+ lua_createtable (L, 0, 4);
if (addr->addr_len > 0) {
lua_pushstring (L, "addr");
lua_pushstring (L, "");
lua_settable (L, -3);
}
+
+ if (addr->name_len > 0) {
+ lua_pushstring (L, "name");
+ lua_pushlstring (L, addr->name, addr->name_len);
+ lua_settable (L, -3);
+ }
+ else {
+ lua_pushstring (L, "name");
+ lua_pushstring (L, "");
+ lua_settable (L, -3);
+ }
}
}
-static void
+void
lua_push_emails_address_list (lua_State *L, GPtrArray *addrs)
{
struct rspamd_email_address *addr;
lua_task_get_recipients (lua_State *L)
{
struct rspamd_task *task = lua_check_task (L, 1);
- InternetAddressList *addrs = NULL;
GPtrArray *ptrs = NULL;
gint what = 0;
break;
case RSPAMD_ADDRESS_MIME:
/* Here we check merely mime rcpt */
- addrs = task->rcpt_mime;
+ ptrs = task->rcpt_mime;
break;
case RSPAMD_ADDRESS_ANY:
default:
ptrs = task->rcpt_envelope;
}
else {
- addrs = task->rcpt_mime;
+ ptrs = task->rcpt_mime;
}
break;
}
-
- if (addrs) {
- lua_push_internet_address_list (L, addrs);
- }
- else if (ptrs) {
+ if (ptrs) {
lua_push_emails_address_list (L, ptrs);
}
else {
return 1;
}
-#define CHECK_ADDR(addr) do { \
- if (addr == NULL) { \
- ret = 0; \
- } \
- else { \
- ret = internet_address_list_length (addr) > 0 ? 1 : 0; \
- } \
-} while (0)
#define CHECK_EMAIL_ADDR(addr) do { \
if (addr == NULL) { \
break;
case RSPAMD_ADDRESS_MIME:
/* Here we check merely mime rcpt */
- CHECK_ADDR (task->from_mime);
+ CHECK_EMAIL_ADDR_LIST (task->from_mime);
break;
case RSPAMD_ADDRESS_ANY:
default:
CHECK_EMAIL_ADDR (task->from_envelope);
if (!ret) {
- CHECK_ADDR (task->from_mime);
+ CHECK_EMAIL_ADDR_LIST (task->from_mime);
}
break;
}
break;
case RSPAMD_ADDRESS_MIME:
/* Here we check merely mime rcpt */
- CHECK_ADDR (task->rcpt_mime);
+ CHECK_EMAIL_ADDR_LIST (task->rcpt_mime);
break;
case RSPAMD_ADDRESS_ANY:
default:
CHECK_EMAIL_ADDR_LIST (task->rcpt_envelope);
if (!ret) {
- CHECK_ADDR (task->rcpt_mime);
+ CHECK_EMAIL_ADDR_LIST (task->rcpt_mime);
}
break;
}
lua_task_get_from (lua_State *L)
{
struct rspamd_task *task = lua_check_task (L, 1);
- InternetAddressList *addrs = NULL;
+ GPtrArray *addrs = NULL;
struct rspamd_email_address *addr = NULL;
gint what = 0;
}
if (addrs) {
- lua_push_internet_address_list (L, addrs);
+ lua_push_emails_address_list (L, addrs);
}
else if (addr) {
/* Create table to preserve compatibility */
#include "libserver/url.h"
#include "unix-std.h"
#include "contrib/zstd/zstd.h"
+#include "libmime/email_addr.h"
#include <math.h>
#include <glob.h>
static gint
lua_util_parse_addr (lua_State *L)
{
- InternetAddressList *ia;
- InternetAddress *addr;
- const gchar *str = luaL_checkstring (L, 1);
- int i, cnt;
+ GPtrArray *addrs;
+ gsize len;
+ const gchar *str = luaL_checklstring (L, 1, &len);
+ rspamd_mempool_t *pool;
+ gboolean own_pool = FALSE;
if (str) {
- ia = internet_address_list_parse_string (str);
- if (ia == NULL) {
- lua_pushnil (L);
+ if (lua_type (L, 2) == LUA_TUSERDATA) {
+ pool = rspamd_lua_check_mempool (L, 2);
+
+ if (pool == NULL) {
+ return luaL_error (L, "invalid arguments");
+ }
}
else {
- cnt = internet_address_list_length (ia);
- lua_createtable (L, cnt, 0);
-
- for (i = 0; i < cnt; i ++) {
- addr = internet_address_list_get_address (ia, i);
-
- lua_createtable (L, 0, 2);
- lua_pushstring (L, "name");
- lua_pushstring (L, internet_address_get_name (addr));
- lua_settable (L, -3);
-
- if (INTERNET_ADDRESS_IS_MAILBOX (addr)) {
- lua_pushstring (L, "addr");
- lua_pushstring (L, internet_address_mailbox_get_addr (
- INTERNET_ADDRESS_MAILBOX (addr)));
- lua_settable (L, -3);
- }
+ pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "lua util");
+ own_pool = TRUE;
+ }
- lua_rawseti (L, -2, (i + 1));
- }
+ addrs = rspamd_email_address_from_mime (pool, str, len, NULL);
- g_object_unref (ia);
+ if (addrs == NULL) {
+ lua_pushnil (L);
+ }
+ else {
+ lua_push_emails_address_list (L, addrs);
}
+
+ rspamd_mempool_delete (pool);
}
else {
lua_pushnil (L);
static gint
lua_util_parse_mail_address (lua_State *L)
{
- InternetAddressList *ia;
- const gchar *str = luaL_checkstring (L, 1);
- gboolean ret = FALSE;
+ GPtrArray *addrs;
+ gsize len;
+ const gchar *str = luaL_checklstring (L, 1, &len);
+ rspamd_mempool_t *pool;
+ gboolean own_pool = FALSE;
if (str) {
- ia = internet_address_list_parse_string (str);
- if (ia != NULL) {
- ret = TRUE;
+ if (lua_type (L, 2) == LUA_TUSERDATA) {
+ pool = rspamd_lua_check_mempool (L, 2);
- lua_push_internet_address_list (L, ia);
-#ifdef GMIME24
- g_object_unref (ia);
-#else
- internet_address_list_destroy (ia);
-#endif
+ if (pool == NULL) {
+ return luaL_error (L, "invalid arguments");
+ }
+ }
+ else {
+ pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "lua util");
+ own_pool = TRUE;
}
- }
- if (!ret) {
+ addrs = rspamd_email_address_from_mime (pool, str, len, NULL);
+
+ if (addrs == NULL) {
+ lua_pushnil (L);
+ }
+ else {
+ lua_push_emails_address_list (L, addrs);
+ }
+
+ rspamd_mempool_delete (pool);
+ }
+ else {
lua_pushnil (L);
}