Browse Source

[Feature] Start moving to the new email address structure

tags/1.3.0
Vsevolod Stakhov 8 years ago
parent
commit
f40a090c9e
5 changed files with 132 additions and 209 deletions
  1. 12
    14
      src/libmime/message.c
  2. 26
    24
      src/libmime/mime_expressions.c
  3. 12
    13
      src/libserver/protocol.c
  4. 78
    141
      src/libserver/task.c
  5. 4
    17
      src/libserver/task.h

+ 12
- 14
src/libmime/message.c View File

@@ -21,6 +21,7 @@
#include "libutil/regexp.h"
#include "html.h"
#include "images.h"
#include "email_addr.h"
#include "utlist.h"
#include "tokenizers/tokenizers.h"

@@ -1475,14 +1476,21 @@ rspamd_message_from_data (struct rspamd_task *task, GByteArray *data,
const char *mb = NULL;
gchar *mid;
rspamd_ftok_t srch, *tok;
struct rspamd_email_address *addr;

g_assert (data != NULL);

message = g_mime_message_new (TRUE);
task->message = message;
if (task->from_envelope) {
g_mime_message_set_sender (task->message,
rspamd_task_get_sender (task));
addr = rspamd_task_get_sender (task);

if (addr->addr_len > 0) {
srch.begin = addr->addr;
srch.len = addr->addr_len;
g_mime_message_set_sender (task->message,
rspamd_mempool_ftokdup (task->task_pool, &srch));
}
}

srch.begin = "Content-Type";
@@ -1764,18 +1772,8 @@ rspamd_message_parse (struct rspamd_task *task)

if (first) {
rh = first->data;
task->from_envelope = internet_address_list_parse_string (rh->value);
if (task->from_envelope) {
#ifdef GMIME24
rspamd_mempool_add_destructor (task->task_pool,
(rspamd_mempool_destruct_t) g_object_unref,
task->from_envelope);
#else
rspamd_mempool_add_destructor (task->task_pool,
(rspamd_mempool_destruct_t) internet_address_list_destroy,
task->from_envelope);
#endif
}
task->from_envelope = rspamd_email_address_from_smtp (rh->decoded,
strlen (rh->decoded));
}
}


+ 26
- 24
src/libmime/mime_expressions.c View File

@@ -20,6 +20,7 @@
#include "message.h"
#include "mime_expressions.h"
#include "html.h"
#include "email_addr.h"
#include "lua/lua_common.h"

gboolean rspamd_compare_encoding (struct rspamd_task *task,
@@ -1424,7 +1425,7 @@ rspamd_raw_header_exists (struct rspamd_task *task, GArray * args, void *unused)
static gboolean
match_smtp_data (struct rspamd_task *task,
struct expression_argument *arg,
const gchar *what)
const gchar *what, gsize len)
{
rspamd_regexp_t *re;
gint r;
@@ -1438,12 +1439,12 @@ match_smtp_data (struct rspamd_task *task,
}


r = rspamd_regexp_search (re, what, 0, NULL, NULL, FALSE, NULL);
r = rspamd_regexp_search (re, what, len, NULL, NULL, FALSE, NULL);

return r;
}
else if (arg->type == EXPRESSION_ARGUMENT_NORMAL &&
g_ascii_strcasecmp (arg->data, what) == 0) {
g_ascii_strncasecmp (arg->data, what, len) == 0) {
return TRUE;
}

@@ -1454,9 +1455,10 @@ static gboolean
rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
{
struct expression_argument *arg;
InternetAddressList *ia = NULL;
const gchar *type, *what = NULL;
gint i, ialen;
struct rspamd_email_address *addr;
GPtrArray *rcpts;
const gchar *type, *str = NULL;
guint i;

if (args == NULL) {
msg_warn_task ("no parameters to function");
@@ -1475,7 +1477,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
case 'f':
case 'F':
if (g_ascii_strcasecmp (type, "from") == 0) {
what = rspamd_task_get_sender (task);
addr = rspamd_task_get_sender (task);
}
else {
msg_warn_task ("bad argument to function: %s", type);
@@ -1485,7 +1487,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
case 'h':
case 'H':
if (g_ascii_strcasecmp (type, "helo") == 0) {
what = task->helo;
str = task->helo;
}
else {
msg_warn_task ("bad argument to function: %s", type);
@@ -1495,7 +1497,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
case 'u':
case 'U':
if (g_ascii_strcasecmp (type, "user") == 0) {
what = task->user;
str = task->user;
}
else {
msg_warn_task ("bad argument to function: %s", type);
@@ -1505,7 +1507,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
case 's':
case 'S':
if (g_ascii_strcasecmp (type, "subject") == 0) {
what = task->subject;
str = task->subject;
}
else {
msg_warn_task ("bad argument to function: %s", type);
@@ -1515,7 +1517,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
case 'r':
case 'R':
if (g_ascii_strcasecmp (type, "rcpt") == 0) {
ia = task->rcpt_mime;
rcpts = task->rcpt_envelope;
}
else {
msg_warn_task ("bad argument to function: %s", type);
@@ -1528,7 +1530,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
}
}

if (what == NULL && ia == NULL) {
if (str == NULL && addr == NULL && rcpts == NULL) {
/* Not enough data so regexp would NOT be found anyway */
return FALSE;
}
@@ -1536,22 +1538,22 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused)
/* We would process only one more argument, others are ignored */
if (args->len >= 2) {
arg = &g_array_index (args, struct expression_argument, 1);

if (arg) {
if (what != NULL) {
return match_smtp_data (task, arg, what);
if (str != NULL) {
return match_smtp_data (task, arg, str, strlen (str));
}
else if (addr != NULL && addr->addr) {
return match_smtp_data (task, arg, addr->addr, addr->addr_len);
}
else {
if (ia != NULL) {
ialen = internet_address_list_length(ia);
for (i = 0; i < ialen; i ++) {
InternetAddress *iaelt =
internet_address_list_get_address(ia, i);
InternetAddressMailbox *iamb =
INTERNET_ADDRESS_IS_MAILBOX(iaelt) ?
INTERNET_ADDRESS_MAILBOX (iaelt) : NULL;
if (iamb &&
if (rcpts != NULL) {
for (i = 0; i < rcpts->len; i ++) {
addr = g_ptr_array_index (rcpts, i);

if (addr && addr->addr &&
match_smtp_data (task, arg,
internet_address_mailbox_get_addr(iamb))) {
addr->addr, addr->addr_len)) {
return TRUE;
}
}

+ 12
- 13
src/libserver/protocol.c View File

@@ -21,6 +21,7 @@
#include "message.h"
#include "utlist.h"
#include "http.h"
#include "email_addr.h"
#include "worker_private.h"

/* Max line size */
@@ -268,6 +269,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
rspamd_ftok_t *hn_tok, *hv_tok, srch;
gboolean fl, has_ip = FALSE;
struct rspamd_http_header *h;
struct rspamd_email_address *addr;

LL_FOREACH (msg->headers, h)
{
@@ -305,8 +307,9 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
case 'f':
case 'F':
IF_HEADER (FROM_HEADER) {
if (!rspamd_task_add_sender (task,
rspamd_mempool_ftokdup (task->task_pool, hv_tok))) {
task->from_envelope = rspamd_email_address_from_smtp (hv->str,
hv->len);
if (!task->from_envelope) {
msg_err_task ("bad from header: '%V'", hv);
}
}
@@ -343,8 +346,12 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
case 'r':
case 'R':
IF_HEADER (RCPT_HEADER) {
if (!rspamd_task_add_recipient (task,
rspamd_mempool_ftokdup (task->task_pool, hv_tok))) {
addr = rspamd_email_address_from_smtp (hv->str, hv->len);

if (addr) {
g_ptr_array_add (task->rcpt_envelope, addr);
}
else {
msg_err_task ("bad from header: '%T'", h->value);
}
debug_task ("read rcpt header, value: %V", hv);
@@ -656,15 +663,7 @@ urls_protocol_cb (gpointer key, gpointer value, gpointer ud)
has_user = TRUE;
}
else if (task->from_envelope) {
InternetAddress *ia;

ia = internet_address_list_get_address (task->from_envelope, 0);

if (ia && INTERNET_ADDRESS_IS_MAILBOX (ia)) {
InternetAddressMailbox *iamb = INTERNET_ADDRESS_MAILBOX (ia);

user_field = iamb->addr;
}
user_field = task->from_envelope->addr;
}

msg_info_task ("<%s> %s: %s; ip: %s; URL: %*s",

+ 78
- 141
src/libserver/task.c View File

@@ -19,6 +19,7 @@
#include "protocol.h"
#include "message.h"
#include "lua/lua_common.h"
#include "email_addr.h"
#include "composites.h"
#include "stat_api.h"
#include "unix-std.h"
@@ -162,6 +163,7 @@ rspamd_task_free (struct rspamd_task *task)
{
struct mime_part *p;
struct mime_text_part *tp;
struct rspamd_email_address *addr;
guint i;

if (task) {
@@ -188,6 +190,15 @@ rspamd_task_free (struct rspamd_task *task)
}
}

for (i = 0; i < task->rcpt_envelope->len; i ++) {
addr = g_ptr_array_index (task->rcpt_envelope, i);
rspamd_email_address_unref (addr);
}

if (task->from_envelope) {
rspamd_email_address_unref (task->from_envelope);
}

if (task->images) {
g_list_free (task->images);
}
@@ -530,48 +541,22 @@ rspamd_task_process (struct rspamd_task *task, guint stages)
return ret;
}

const gchar *
struct rspamd_email_address*
rspamd_task_get_sender (struct rspamd_task *task)
{
InternetAddress *iaelt = NULL;
#ifdef GMIME24
InternetAddressMailbox *imb;

if (task->from_envelope != NULL) {
iaelt = internet_address_list_get_address (task->from_envelope, 0);
}
else if (task->from_mime != NULL) {
iaelt = internet_address_list_get_address (task->from_mime, 0);
}
imb = INTERNET_ADDRESS_IS_MAILBOX(iaelt) ?
INTERNET_ADDRESS_MAILBOX (iaelt) : NULL;

return (imb ? internet_address_mailbox_get_addr (imb) : NULL);
#else
if (task->from_envelope != NULL) {
iaelt = internet_address_list_get_address (task->from_envelope);
}
else if (task->from_mime != NULL) {
iaelt = internet_address_list_get_address (task->from_mime);
}

return (iaelt != NULL ? internet_address_get_addr (iaelt) : NULL);
#endif
return task->from_envelope;
}

static const gchar *
rspamd_task_cache_principal_recipient (struct rspamd_task *task,
const gchar *rcpt)
const gchar *rcpt, gsize len)
{
gchar *rcpt_lc;
gsize len;

if (rcpt == NULL) {
return NULL;
}

len = strlen (rcpt);

rcpt_lc = rspamd_mempool_alloc (task->task_pool, len + 1);
rspamd_strlcpy (rcpt_lc, rcpt, len + 1);
rspamd_str_lc (rcpt_lc, len);
@@ -586,6 +571,7 @@ rspamd_task_get_principal_recipient (struct rspamd_task *task)
{
InternetAddress *iaelt = NULL;
const gchar *val;
struct rspamd_email_address *addr;

val = rspamd_mempool_get_variable (task->task_pool, "recipient");

@@ -594,16 +580,22 @@ rspamd_task_get_principal_recipient (struct rspamd_task *task)
}

if (task->deliver_to) {
return rspamd_task_cache_principal_recipient (task, task->deliver_to);
return rspamd_task_cache_principal_recipient (task, task->deliver_to,
strlen (task->deliver_to));
}
if (task->rcpt_envelope != NULL) {
addr = g_ptr_array_index (task->rcpt_envelope, 0);

if (addr->addr) {
return rspamd_task_cache_principal_recipient (task, addr->addr,
addr->addr_len);
}
}

#ifdef GMIME24
InternetAddressMailbox *imb;

if (task->rcpt_envelope != NULL) {
iaelt = internet_address_list_get_address (task->rcpt_envelope, 0);
}
else if (task->rcpt_mime != NULL) {
if (task->rcpt_mime != NULL) {
iaelt = internet_address_list_get_address (task->rcpt_mime, 0);
}

@@ -613,99 +605,23 @@ rspamd_task_get_principal_recipient (struct rspamd_task *task)
if (imb) {
val = internet_address_mailbox_get_addr (imb);

return rspamd_task_cache_principal_recipient (task, val);
return rspamd_task_cache_principal_recipient (task, val, strlen (val));
}
#else
if (task->rcpt_envelope != NULL) {
iaelt = internet_address_list_get_address (task->rcpt_envelope);
}
else if (task->rcpt_mime != NULL) {
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);
return rspamd_task_cache_principal_recipient (task, val, strlen (val));
}
#endif

return NULL;
}

gboolean
rspamd_task_add_recipient (struct rspamd_task *task, const gchar *rcpt)
{
InternetAddressList *tmp_addr;

if (task->rcpt_envelope == NULL) {
task->rcpt_envelope = internet_address_list_new ();
#ifdef GMIME24
rspamd_mempool_add_destructor (task->task_pool,
(rspamd_mempool_destruct_t) g_object_unref,
task->rcpt_envelope);
#else
rspamd_mempool_add_destructor (task->task_pool,
(rspamd_mempool_destruct_t) internet_address_list_destroy,
task->rcpt_envelope);
#endif
}
tmp_addr = internet_address_list_parse_string (rcpt);

if (tmp_addr) {
internet_address_list_append (task->rcpt_envelope, tmp_addr);
#ifdef GMIME24
g_object_unref (tmp_addr);
#else
internet_address_list_destroy (tmp_addr);
#endif
return TRUE;
}

return FALSE;
}

gboolean
rspamd_task_add_sender (struct rspamd_task *task, const gchar *sender)
{
InternetAddressList *tmp_addr;

if (task->from_envelope == NULL) {
task->from_envelope = internet_address_list_new ();
#ifdef GMIME24
rspamd_mempool_add_destructor (task->task_pool,
(rspamd_mempool_destruct_t) g_object_unref,
task->from_envelope);
#else
rspamd_mempool_add_destructor (task->task_pool,
(rspamd_mempool_destruct_t) internet_address_list_destroy,
task->from_envelope);
#endif
}

if (strcmp (sender, "<>") == 0) {
/* Workaround for gmime */
internet_address_list_add (task->from_envelope,
internet_address_mailbox_new ("", ""));
return TRUE;
}
else {
tmp_addr = internet_address_list_parse_string (sender);

if (tmp_addr) {
internet_address_list_append (task->from_envelope, tmp_addr);
#ifdef GMIME24
g_object_unref (tmp_addr);
#else
internet_address_list_destroy (tmp_addr);
#endif
return TRUE;
}
}

return FALSE;
}

gboolean
rspamd_learn_task_spam (struct rspamd_task *task,
gboolean is_spam,
@@ -753,12 +669,7 @@ rspamd_task_log_check_condition (struct rspamd_task *task,
break;
case RSPAMD_LOG_SMTP_RCPT:
case RSPAMD_LOG_SMTP_RCPTS:
if (task->rcpt_envelope &&
internet_address_list_length (task->rcpt_envelope) > 0) {
ret = TRUE;
}
else if (task->rcpt_mime &&
internet_address_list_length (task->rcpt_mime) > 0) {
if (task->rcpt_envelope && task->rcpt_envelope->len > 0) {
ret = TRUE;
}
break;
@@ -770,12 +681,7 @@ rspamd_task_log_check_condition (struct rspamd_task *task,
}
break;
case RSPAMD_LOG_SMTP_FROM:
if (task->from_envelope &&
internet_address_list_length (task->from_envelope) > 0) {
ret = TRUE;
}
else if (task->from_mime &&
internet_address_list_length (task->from_mime) > 0) {
if (task->from_envelope) {
ret = TRUE;
}
break;
@@ -965,6 +871,49 @@ rspamd_task_write_ialist (struct rspamd_task *task,
return res;
}

static rspamd_fstring_t *
rspamd_task_write_addr_list (struct rspamd_task *task,
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};
struct rspamd_email_address *addr;
gint i;

if (lim <= 0) {
lim = addrs->len;
}

varbuf = rspamd_fstring_new ();

for (i = 0; i < lim; i++) {
addr = g_ptr_array_index (addrs, i);

if (addr->addr) {
varbuf = rspamd_fstring_append (varbuf, addr->addr, addr->addr_len);
}

if (varbuf->len > 0) {
if (i != lim - 1) {
varbuf = rspamd_fstring_append (varbuf, ",", 1);
}
}
}

if (varbuf->len > 0) {
var.begin = varbuf->str;
var.len = varbuf->len;
res = rspamd_task_log_write_var (task, logbuf,
&var, (const rspamd_ftok_t *) lf->data);
}

rspamd_fstring_free (varbuf);

return res;
}

static rspamd_fstring_t *
rspamd_task_log_variable (struct rspamd_task *task,
struct rspamd_log_format *lf, rspamd_fstring_t *logbuf)
@@ -1040,12 +989,8 @@ rspamd_task_log_variable (struct rspamd_task *task,
/* InternetAddress vars */
case RSPAMD_LOG_SMTP_FROM:
if (task->from_envelope) {
return rspamd_task_write_ialist (task, task->from_envelope, 1, lf,
logbuf);
}
else if (task->from_mime) {
return rspamd_task_write_ialist (task, task->from_mime, 1, lf,
logbuf);
var.begin = task->from_envelope->addr;
var.len = task->from_envelope->addr_len;
}
break;
case RSPAMD_LOG_MIME_FROM:
@@ -1056,11 +1001,7 @@ rspamd_task_log_variable (struct rspamd_task *task,
break;
case RSPAMD_LOG_SMTP_RCPT:
if (task->rcpt_envelope) {
return rspamd_task_write_ialist (task, task->rcpt_envelope, 1, lf,
logbuf);
}
else if (task->rcpt_mime) {
return rspamd_task_write_ialist (task, task->rcpt_mime, 1, lf,
return rspamd_task_write_addr_list (task, task->rcpt_envelope, 1, lf,
logbuf);
}
break;
@@ -1072,11 +1013,7 @@ rspamd_task_log_variable (struct rspamd_task *task,
break;
case RSPAMD_LOG_SMTP_RCPTS:
if (task->rcpt_envelope) {
return rspamd_task_write_ialist (task, task->rcpt_envelope, -1, lf,
logbuf);
}
else if (task->rcpt_mime) {
return rspamd_task_write_ialist (task, task->rcpt_mime, -1, lf,
return rspamd_task_write_addr_list (task, task->rcpt_envelope, -1, lf,
logbuf);
}
break;

+ 4
- 17
src/libserver/task.h View File

@@ -151,17 +151,11 @@ struct rspamd_task {
GHashTable *results; /**< hash table of metric_result indexed by
* metric's name */
GPtrArray *tokens; /**< statistics tokens */
#if 0
GPtrArray *rcpt_mime; /**< list of all recipients (rspamd_email_address) */
GPtrArray *rcpt_envelope; /**< list of all recipients (rspamd_email_address) */
struct rspamd_email_address *from_mime;
struct rspamd_email_address *from_envelope;
#else

InternetAddressList *rcpt_mime;
InternetAddressList *rcpt_envelope;
GPtrArray *rcpt_envelope; /**< array of rspamd_email_address */
InternetAddressList *from_mime;
InternetAddressList *from_envelope;
#endif
struct rspamd_email_address *from_envelope;

GList *messages; /**< list of messages that would be reported */
struct rspamd_re_runtime *re_rt; /**< regexp runtime */
@@ -237,7 +231,7 @@ gboolean rspamd_task_process (struct rspamd_task *task, guint stages);
* @param task
* @return
*/
const gchar *rspamd_task_get_sender (struct rspamd_task *task);
struct rspamd_email_address* rspamd_task_get_sender (struct rspamd_task *task);

/**
* Return addresses in the following precendence:
@@ -256,13 +250,6 @@ const gchar *rspamd_task_get_principal_recipient (struct rspamd_task *task);
* @return TRUE if an address has been parsed and added
*/
gboolean rspamd_task_add_recipient (struct rspamd_task *task, const gchar *rcpt);
/**
* Add a sender for a task
* @param task task object
* @param sender string representation of sender's address
* @return TRUE if an address has been parsed and added
*/
gboolean rspamd_task_add_sender (struct rspamd_task *task, const gchar *sender);

/**
* Learn specified statfile with message in a task

Loading…
Cancel
Save