From 2237481903caa32c1b5d5042aaaca0f5ce11e0f1 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 23 Feb 2021 16:08:24 +0000 Subject: [PATCH] [Project] Rework API for the modified headers --- src/libmime/images.c | 4 ++-- src/libmime/mime_expressions.c | 6 +++--- src/libmime/mime_headers.c | 35 +++++++++++++++++++++++++--------- src/libmime/mime_headers.h | 7 +++++-- src/libmime/mime_parser.c | 22 ++++++++++----------- src/libserver/dkim.c | 8 ++++---- src/libserver/re_cache.c | 10 +++++----- src/lua/lua_mimepart.c | 6 +++--- src/lua/lua_task.c | 6 +++--- src/plugins/dkim_check.c | 2 +- 10 files changed, 63 insertions(+), 43 deletions(-) diff --git a/src/libmime/images.c b/src/libmime/images.c index b3baa8e4c..73ff43910 100644 --- a/src/libmime/images.c +++ b/src/libmime/images.c @@ -666,8 +666,8 @@ rspamd_image_process_part (struct rspamd_task *task, struct rspamd_mime_part *pa if (img) { /* Check Content-Id */ - rh = rspamd_message_get_header_from_hash (part->raw_headers, - "Content-Id"); + rh = rspamd_message_get_header_from_hash(part->raw_headers, + "Content-Id", FALSE); if (rh) { cid = rh->decoded; diff --git a/src/libmime/mime_expressions.c b/src/libmime/mime_expressions.c index ab863aa71..d0c1704ad 100644 --- a/src/libmime/mime_expressions.c +++ b/src/libmime/mime_expressions.c @@ -1264,8 +1264,8 @@ rspamd_header_exists (struct rspamd_task * task, GArray * args, void *unused) return FALSE; } - rh = rspamd_message_get_header_array (task, - (gchar *)arg->data); + rh = rspamd_message_get_header_array(task, + (gchar *) arg->data, FALSE); debug_task ("try to get header %s: %d", (gchar *)arg->data, (rh != NULL)); @@ -1653,7 +1653,7 @@ rspamd_raw_header_exists (struct rspamd_task *task, GArray * args, void *unused) return FALSE; } - return rspamd_message_get_header_array (task, arg->data) != NULL; + return rspamd_message_get_header_array(task, arg->data, FALSE) != NULL; } static gboolean diff --git a/src/libmime/mime_headers.c b/src/libmime/mime_headers.c index 7a1667539..832e1306d 100644 --- a/src/libmime/mime_headers.c +++ b/src/libmime/mime_headers.c @@ -1662,11 +1662,13 @@ rspamd_smtp_received_parse (struct rspamd_task *task, } struct rspamd_mime_header * -rspamd_message_get_header_from_hash (struct rspamd_mime_headers_table *headers, - const gchar *field) +rspamd_message_get_header_from_hash (struct rspamd_mime_headers_table *hdrs, + const gchar *field, + gboolean need_modified) { khiter_t k; - khash_t(rspamd_mime_headers_htb) *htb = &headers->htb; + khash_t(rspamd_mime_headers_htb) *htb = &hdrs->htb; + struct rspamd_mime_header *hdr; if (htb) { k = kh_get (rspamd_mime_headers_htb, htb, (gchar *) field); @@ -1675,19 +1677,34 @@ rspamd_message_get_header_from_hash (struct rspamd_mime_headers_table *headers, return NULL; } - return kh_value (htb, k); + hdr = kh_value (htb, k); + + if (!need_modified) { + if (hdr->flags & RSPAMD_HEADER_NON_EXISTING) { + return NULL; + } + + return hdr; + } + else { + if (hdr->flags & RSPAMD_HEADER_MODIFIED) { + return hdr->modified_chain; + } + + return hdr; + } } return NULL; } struct rspamd_mime_header * -rspamd_message_get_header_array (struct rspamd_task *task, - const gchar *field) +rspamd_message_get_header_array (struct rspamd_task *task, const gchar *field, + gboolean need_modified) { - return rspamd_message_get_header_from_hash ( + return rspamd_message_get_header_from_hash( MESSAGE_FIELD_CHECK (task, raw_headers), - field); + field, need_modified); } static void @@ -1743,7 +1760,7 @@ rspamd_message_set_modified_header (struct rspamd_task *task, if (k == kh_end (htb)) { hdr_elt = rspamd_mempool_alloc0 (task->task_pool, sizeof (*hdr_elt)); - hdr_elt->flags |= RSPAMD_HEADER_MODIFIED; + hdr_elt->flags |= RSPAMD_HEADER_MODIFIED|RSPAMD_HEADER_NON_EXISTING; hdr_elt->name = rspamd_mempool_strdup (task->task_pool, hdr_name); int r; diff --git a/src/libmime/mime_headers.h b/src/libmime/mime_headers.h index f01a8b649..ad8f1b68f 100644 --- a/src/libmime/mime_headers.h +++ b/src/libmime/mime_headers.h @@ -52,6 +52,7 @@ enum rspamd_mime_header_flags { RSPAMD_HEADER_MODIFIED = 1u << 15u, /* Means we need to check modified chain */ RSPAMD_HEADER_ADDED = 1u << 16u, /* A header has been artificially added */ RSPAMD_HEADER_REMOVED = 1u << 17u, /* A header has been artificially removed */ + RSPAMD_HEADER_NON_EXISTING = 1u << 18u, /* Header was not in the original message */ }; struct rspamd_mime_header { @@ -164,7 +165,8 @@ gchar *rspamd_mime_message_id_generate (const gchar *fqdn); */ struct rspamd_mime_header * rspamd_message_get_header_array (struct rspamd_task *task, - const gchar *field); + const gchar *field, + gboolean need_modified); /** * Get an array of header's values with specified header's name using raw headers @@ -174,7 +176,8 @@ rspamd_message_get_header_array (struct rspamd_task *task, */ struct rspamd_mime_header * rspamd_message_get_header_from_hash (struct rspamd_mime_headers_table *hdrs, - const gchar *field); + const gchar *field, + gboolean need_modified); /** * Modifies a header (or insert one if not found) diff --git a/src/libmime/mime_parser.c b/src/libmime/mime_parser.c index e74201f27..0d6659867 100644 --- a/src/libmime/mime_parser.c +++ b/src/libmime/mime_parser.c @@ -392,7 +392,7 @@ rspamd_mime_part_get_cte (struct rspamd_task *task, enum rspamd_cte cte = RSPAMD_CTE_UNKNOWN; gboolean parent_propagated = FALSE; - hdr = rspamd_message_get_header_from_hash (hdrs, "Content-Transfer-Encoding"); + hdr = rspamd_message_get_header_from_hash(hdrs, "Content-Transfer-Encoding", FALSE); if (hdr == NULL) { if (part->parent_part && part->parent_part->cte != RSPAMD_CTE_UNKNOWN && @@ -471,8 +471,8 @@ rspamd_mime_part_get_cd (struct rspamd_task *task, struct rspamd_mime_part *part rspamd_ftok_t srch; struct rspamd_content_type_param *found; - hdr = rspamd_message_get_header_from_hash (part->raw_headers, - "Content-Disposition"); + hdr = rspamd_message_get_header_from_hash(part->raw_headers, + "Content-Disposition", FALSE); if (hdr == NULL) { @@ -859,8 +859,8 @@ rspamd_mime_process_multipart_node (struct rspamd_task *task, } } - hdr = rspamd_message_get_header_from_hash (npart->raw_headers, - "Content-Type"); + hdr = rspamd_message_get_header_from_hash(npart->raw_headers, + "Content-Type", FALSE); } else { @@ -1402,9 +1402,9 @@ rspamd_mime_parse_message (struct rspamd_task *task, } } - hdr = rspamd_message_get_header_from_hash ( + hdr = rspamd_message_get_header_from_hash( MESSAGE_FIELD (task, raw_headers), - "Content-Type"); + "Content-Type", FALSE); } else { /* First apply heuristic, maybe we have just headers */ @@ -1432,9 +1432,9 @@ rspamd_mime_parse_message (struct rspamd_task *task, } } - hdr = rspamd_message_get_header_from_hash ( + hdr = rspamd_message_get_header_from_hash( MESSAGE_FIELD (task, raw_headers), - "Content-Type"); + "Content-Type", FALSE); task->flags |= RSPAMD_TASK_FLAG_BROKEN_HEADERS; } else { @@ -1488,8 +1488,8 @@ rspamd_mime_parse_message (struct rspamd_task *task, } } - hdr = rspamd_message_get_header_from_hash (npart->raw_headers, - "Content-Type"); + hdr = rspamd_message_get_header_from_hash(npart->raw_headers, + "Content-Type", FALSE); } else { body_pos = 0; diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c index 55a874e32..1cd6d09ff 100644 --- a/src/libserver/dkim.c +++ b/src/libserver/dkim.c @@ -2334,7 +2334,7 @@ rspamd_dkim_canonize_header (struct rspamd_dkim_common_ctx *ctx, } if (dkim_header == NULL) { - rh = rspamd_message_get_header_array (task, header_name); + rh = rspamd_message_get_header_array(task, header_name, FALSE); if (rh) { /* Check uniqueness of the header but we count from the bottom to top */ @@ -2451,7 +2451,7 @@ rspamd_dkim_canonize_header (struct rspamd_dkim_common_ctx *ctx, /* For signature check just use the saved dkim header */ if (ctx->header_canon_type == DKIM_CANON_SIMPLE) { /* We need to find our own signature and use it */ - rh = rspamd_message_get_header_array (task, header_name); + rh = rspamd_message_get_header_array(task, header_name, FALSE); if (rh) { /* We need to find our own signature */ @@ -3287,7 +3287,7 @@ rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector, /* Do oversigning */ guint count = 0; - rh = rspamd_message_get_header_array (task, dh->name); + rh = rspamd_message_get_header_array(task, dh->name, FALSE); if (rh) { DL_FOREACH (rh, cur) { @@ -3315,7 +3315,7 @@ rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector, } } else { - rh = rspamd_message_get_header_array (task, dh->name); + rh = rspamd_message_get_header_array(task, dh->name, FALSE); if (rh) { if (hstat.s.count > 0) { diff --git a/src/libserver/re_cache.c b/src/libserver/re_cache.c index d8e6d56d2..b3326bcff 100644 --- a/src/libserver/re_cache.c +++ b/src/libserver/re_cache.c @@ -1154,8 +1154,8 @@ rspamd_re_cache_exec_re (struct rspamd_task *task, case RSPAMD_RE_HEADER: case RSPAMD_RE_RAWHEADER: /* Get list of specified headers */ - rh = rspamd_message_get_header_array (task, - re_class->type_data); + rh = rspamd_message_get_header_array(task, + re_class->type_data, FALSE); if (rh) { ret = rspamd_re_cache_process_headers_list (task, rt, re, @@ -1177,8 +1177,8 @@ rspamd_re_cache_exec_re (struct rspamd_task *task, break; case RSPAMD_RE_MIMEHEADER: PTR_ARRAY_FOREACH (MESSAGE_FIELD (task, parts), i, mime_part) { - rh = rspamd_message_get_header_from_hash (mime_part->raw_headers, - re_class->type_data); + rh = rspamd_message_get_header_from_hash(mime_part->raw_headers, + re_class->type_data, FALSE); if (rh) { ret += rspamd_re_cache_process_headers_list (task, rt, re, @@ -1345,7 +1345,7 @@ rspamd_re_cache_exec_re (struct rspamd_task *task, * of the body content. */ - rh = rspamd_message_get_header_array (task, "Subject"); + rh = rspamd_message_get_header_array(task, "Subject", FALSE); if (rh) { scvec[0] = (guchar *)rh->decoded; diff --git a/src/lua/lua_mimepart.c b/src/lua/lua_mimepart.c index c12485ecb..fe8bb4246 100644 --- a/src/lua/lua_mimepart.c +++ b/src/lua/lua_mimepart.c @@ -1645,7 +1645,7 @@ lua_mimepart_get_header_common (lua_State *L, enum rspamd_lua_task_header_type h return rspamd_lua_push_header_array (L, name, - rspamd_message_get_header_from_hash (part->raw_headers, name), + rspamd_message_get_header_from_hash(part->raw_headers, name, FALSE), how, strong); } @@ -1782,8 +1782,8 @@ lua_mimepart_is_attachment (lua_State * L) /* if has_name and not (image and Content-ID_header_present) */ if (part->cd && part->cd->filename.len > 0) { if (part->part_type != RSPAMD_MIME_PART_IMAGE && - rspamd_message_get_header_from_hash (part->raw_headers, - "Content-Id") == NULL) { + rspamd_message_get_header_from_hash(part->raw_headers, + "Content-Id", FALSE) == NULL) { /* Filename is presented but no content id and not image */ lua_pushboolean (L, true); } diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 1095d1a60..f4dee6d65 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -2934,7 +2934,7 @@ lua_task_get_header_common (lua_State *L, enum rspamd_lua_task_header_type how) strong = lua_toboolean (L, 3); } - rh = rspamd_message_get_header_array (task, name); + rh = rspamd_message_get_header_array(task, name, FALSE); return rspamd_lua_push_header_array (L, name, rh, how, strong); } @@ -3988,7 +3988,7 @@ lua_task_get_reply_sender (lua_State *L) if (task) { - rh = rspamd_message_get_header_array (task, "Reply-To"); + rh = rspamd_message_get_header_array(task, "Reply-To", FALSE); if (rh) { lua_pushstring (L, rh->decoded); @@ -5082,7 +5082,7 @@ lua_task_get_date (lua_State *L) } } else { - h = rspamd_message_get_header_array (task, "Date"); + h = rspamd_message_get_header_array(task, "Date", FALSE); if (h) { time_t tt; diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c index c00b87b11..ab5d6ec43 100644 --- a/src/plugins/dkim_check.c +++ b/src/plugins/dkim_check.c @@ -1174,7 +1174,7 @@ dkim_symbol_callback (struct rspamd_task *task, rspamd_symcache_item_async_inc (task, item, M); /* Now check if a message has its signature */ - rh = rspamd_message_get_header_array (task, RSPAMD_DKIM_SIGNHEADER); + rh = rspamd_message_get_header_array(task, RSPAMD_DKIM_SIGNHEADER, FALSE); if (rh) { msg_debug_task ("dkim signature found"); -- 2.39.5