]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Add a simple way to limit number of email addresses
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 19 May 2020 16:00:25 +0000 (17:00 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 19 May 2020 16:00:25 +0000 (17:00 +0100)
src/libmime/email_addr.c
src/libmime/email_addr.h
src/libmime/mime_headers.c
src/libserver/cfg_rcl.c
src/libserver/milter.c
src/libserver/protocol.c
src/lua/lua_util.c

index 4e09de6fb7ab8fec72057abff94a02ad49b547f0..1987c58c3da86e905c5acdf7f1c57964712fb75a 100644 (file)
@@ -48,7 +48,7 @@ rspamd_email_address_unescape (struct rspamd_email_address *addr)
 }
 
 struct rspamd_email_address *
-rspamd_email_address_from_smtp (const gchar *str, guint len)
+rspamd_email_address_from_smtp (const gchar *str, guint len, gint max_elements)
 {
        struct rspamd_email_address addr, *ret;
        gsize nlen;
@@ -203,10 +203,21 @@ static inline gboolean
 rspamd_email_address_check_and_add (const gchar *start, gsize len,
                                                                        GPtrArray *res,
                                                                        rspamd_mempool_t *pool,
-                                                                       GString *ns)
+                                                                       GString *ns,
+                                                                       gint max_elements)
 {
        struct rspamd_email_address addr;
 
+       g_assert (res != NULL);
+
+       if (max_elements > 0 && res->len >= max_elements) {
+               msg_info_pool_check ("reached maximum number of elements %d when adding %v",
+                               max_elements,
+                               ns);
+
+               return FALSE;
+       }
+
        /* The whole email is likely address */
        memset (&addr, 0, sizeof (addr));
        rspamd_smtp_addr_parse (start, len, &addr);
@@ -231,9 +242,10 @@ rspamd_email_address_check_and_add (const gchar *start, gsize len,
 }
 
 GPtrArray *
-rspamd_email_address_from_mime (rspamd_mempool_t *pool,
-               const gchar *hdr, guint len,
-               GPtrArray *src)
+rspamd_email_address_from_mime (rspamd_mempool_t *pool, const gchar *hdr,
+                                                               guint len,
+                                                               GPtrArray *src,
+                                                               gint max_elements)
 {
        GPtrArray *res = src;
        gboolean seen_at = FALSE;
@@ -253,6 +265,11 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
                rspamd_mempool_add_destructor (pool, rspamd_email_address_list_destroy,
                                res);
        }
+       else if (max_elements > 0 && res->len >= max_elements) {
+               msg_info_pool_check ("reached maximum number of elements %d", max_elements);
+
+               return res;
+       }
 
        ns = g_string_sized_new (len);
        cpy = g_string_sized_new (len);
@@ -371,7 +388,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
                                        }
 
                                        if (!rspamd_email_address_check_and_add (c, t - c + 1,
-                                                       res, pool, ns)) {
+                                                       res, pool, ns, max_elements)) {
                                                rspamd_email_address_add (pool, res, NULL, ns);
                                        }
 
@@ -407,7 +424,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
                case parse_addr:
                        if (*p == '>') {
                                if (!rspamd_email_address_check_and_add (c, p - c + 1,
-                                               res, pool, ns)) {
+                                               res, pool, ns, max_elements)) {
                                        rspamd_email_address_add (pool, res, NULL, ns);
                                }
 
@@ -447,7 +464,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
                                if (seen_at) {
                                        /* The whole email is likely address */
                                        if (!rspamd_email_address_check_and_add (c, p - c,
-                                                       res, pool, ns)) {
+                                                       res, pool, ns, max_elements)) {
                                                if (res->len == 0) {
                                                        rspamd_email_address_add (pool, res, NULL, ns);
                                                }
@@ -469,7 +486,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
        case parse_addr:
                if (p > c) {
                        if (!rspamd_email_address_check_and_add (c, p - c,
-                                       res, pool, ns)) {
+                                       res, pool, ns, max_elements)) {
                                if (res->len == 0) {
                                        rspamd_email_address_add (pool, res, NULL, ns);
                                }
index 13e94f7ccb5556a582cc346243320a0caf2dfc10..2452fc7aa564121bf45521090852cfa9653752a0 100644 (file)
@@ -67,8 +67,9 @@ struct rspamd_task;
  * @param len length of string
  * @return
  */
-struct rspamd_email_address *rspamd_email_address_from_smtp (
-               const gchar *str, guint len);
+struct rspamd_email_address *rspamd_email_address_from_smtp (const gchar *str,
+               guint len,
+               gint max_elements);
 
 /**
  * Parses email address from the mime header, decodes names and return the array
@@ -79,10 +80,9 @@ struct rspamd_email_address *rspamd_email_address_from_smtp (
  * @param len
  * @return
  */
-GPtrArray *rspamd_email_address_from_mime (rspamd_mempool_t *pool,
-                                                                                  const gchar *hdr,
-                                                                                  guint len,
-                                                                                  GPtrArray *src);
+GPtrArray *
+rspamd_email_address_from_mime (rspamd_mempool_t *pool, const gchar *hdr, guint len,
+               GPtrArray *src, gint max_elements);
 
 /**
  * Destroys list of email addresses
index 582f11d7a3dadc1dec877b59ca04d5b64028f487..55d04d69a314d73b1fcf8758f300a7d9b6f29020 100644 (file)
@@ -62,25 +62,25 @@ rspamd_mime_header_check_special (struct rspamd_task *task,
        case 0x76F31A09F4352521ULL:     /* to */
                MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool,
                                rh->decoded, strlen (rh->decoded),
-                               MESSAGE_FIELD (task, rcpt_mime));
+                               MESSAGE_FIELD (task, rcpt_mime), -1);
                rh->flags |= RSPAMD_HEADER_TO|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE;
                break;
        case 0x7EB117C1480B76ULL:       /* cc */
                MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool,
                                rh->decoded, strlen (rh->decoded),
-                               MESSAGE_FIELD (task, rcpt_mime));
+                               MESSAGE_FIELD (task, rcpt_mime), -1);
                rh->flags |= RSPAMD_HEADER_CC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE;
                break;
        case 0xE4923E11C4989C8DULL:     /* bcc */
                MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool,
                                rh->decoded, strlen (rh->decoded),
-                               MESSAGE_FIELD (task, rcpt_mime));
+                               MESSAGE_FIELD (task, rcpt_mime), -1);
                rh->flags |= RSPAMD_HEADER_BCC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE;
                break;
        case 0x41E1985EDC1CBDE4ULL:     /* from */
                MESSAGE_FIELD (task, from_mime) = rspamd_email_address_from_mime (task->task_pool,
                                rh->decoded, strlen (rh->decoded),
-                               MESSAGE_FIELD (task, from_mime));
+                               MESSAGE_FIELD (task, from_mime), -1);
                rh->flags |= RSPAMD_HEADER_FROM|RSPAMD_HEADER_SENDER|RSPAMD_HEADER_UNIQUE;
                break;
        case 0x43A558FC7C240226ULL:     /* message-id */ {
@@ -129,7 +129,7 @@ rspamd_mime_header_check_special (struct rspamd_task *task,
        case 0xEE4AA2EAAC61D6F4ULL:     /* return-path */
                if (task->from_envelope == NULL) {
                        task->from_envelope = rspamd_email_address_from_smtp (rh->decoded,
-                                       strlen (rh->decoded));
+                                       strlen (rh->decoded), -1);
                }
                rh->flags = RSPAMD_HEADER_RETURN_PATH|RSPAMD_HEADER_UNIQUE;
                break;
index ff256c413aadb3bd30d036f170624b705477ca04..dc568297bfb9030434a0e17e15c91ec208ad2367 100644 (file)
@@ -3392,7 +3392,7 @@ rspamd_rcl_parse_struct_mime_addr (rspamd_mempool_t *pool,
                if (ucl_object_type (cur) == UCL_STRING) {
                        val = ucl_object_tostring (obj);
                        tmp_addr = rspamd_email_address_from_mime (pool, val,
-                                       strlen (val), tmp_addr);
+                                       strlen (val), tmp_addr, -1);
                }
                else {
                        g_set_error (err,
index dc398912d0d3610f373cffbe70b845130ca82bcd..4713b737142e999fbf39ab93589cbec72c99fb8c 100644 (file)
@@ -603,7 +603,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
                                cpy = rspamd_mempool_alloc (priv->pool, zero - pos);
                                memcpy (cpy, pos, zero - pos);
                                msg_debug_milter ("got mail: %*s", (int)(zero - pos), cpy);
-                               addr = rspamd_email_address_from_smtp (cpy, zero - pos);
+                               addr = rspamd_email_address_from_smtp (cpy, zero - pos, -1);
 
                                if (addr) {
                                        session->from = addr;
@@ -618,7 +618,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
                                /* That actually should not happen */
                                cpy = rspamd_mempool_alloc (priv->pool, end - pos);
                                memcpy (cpy, pos, end - pos);
-                               addr = rspamd_email_address_from_smtp (cpy, end - pos);
+                               addr = rspamd_email_address_from_smtp (cpy, end - pos, -1);
 
                                if (addr) {
                                        session->from = addr;
@@ -707,7 +707,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
                                memcpy (cpy, pos, end - pos);
 
                                msg_debug_milter ("got rcpt: %*s", (int)(zero - pos), cpy);
-                               addr = rspamd_email_address_from_smtp (cpy, zero - pos);
+                               addr = rspamd_email_address_from_smtp (cpy, zero - pos, -1);
 
                                if (addr) {
                                        if (!session->rcpts) {
@@ -726,7 +726,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
                                msg_debug_milter ("got weird rcpt: %*s", (int)(end - pos),
                                                pos);
                                /* That actually should not happen */
-                               addr = rspamd_email_address_from_smtp (cpy, end - pos);
+                               addr = rspamd_email_address_from_smtp (cpy, end - pos, -1);
 
                                if (addr) {
                                        if (!session->rcpts) {
index 9d127606409fb20d76c4ec480eb4acd53f372faa..1d51ff28fe5aab6a4f3b2deb2528d61783168d2f 100644 (file)
@@ -292,7 +292,7 @@ rspamd_protocol_process_recipients (struct rspamd_task *task,
                        else if (*p == ',' && start_addr != NULL && p > start_addr) {
                                /* We have finished address, check what we have */
                                addr = rspamd_email_address_from_smtp (start_addr,
-                                               p - start_addr);
+                                               p - start_addr, -1);
 
                                if (addr) {
                                        if (task->rcpt_envelope == NULL) {
@@ -322,7 +322,7 @@ rspamd_protocol_process_recipients (struct rspamd_task *task,
        if (start_addr && p > start_addr) {
                switch (state) {
                case normal_string:
-                       addr = rspamd_email_address_from_smtp (start_addr, end - start_addr);
+                       addr = rspamd_email_address_from_smtp (start_addr, end - start_addr, -1);
 
                        if (addr) {
                                if (task->rcpt_envelope == NULL) {
@@ -495,7 +495,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
                                IF_HEADER (FROM_HEADER) {
                                        task->from_envelope = rspamd_email_address_from_smtp (
                                                        hv_tok->begin,
-                                                       hv_tok->len);
+                                                       hv_tok->len, -1);
                                        msg_debug_protocol ("read from header, value: %T", hv_tok);
 
                                        if (!task->from_envelope) {
index 5948f4b4b8a6bf1f83f1c883c2dbd0262ecae500..4d2758c5e97382a48aeaf53bd15f55b869bc483d 100644 (file)
@@ -1650,7 +1650,7 @@ lua_util_parse_mail_address (lua_State *L)
                        own_pool = TRUE;
                }
 
-               addrs = rspamd_email_address_from_mime (pool, str, len, NULL);
+               addrs = rspamd_email_address_from_mime (pool, str, len, NULL, -1);
 
                if (addrs == NULL) {
                        lua_pushnil (L);