]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Start using of the new received structure
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 4 Oct 2021 20:46:15 +0000 (21:46 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 4 Oct 2021 20:46:15 +0000 (21:46 +0100)
src/libmime/message.c
src/libmime/mime_headers.c
src/libmime/received.cxx
src/libmime/received.h

index e6fc5be94789614364c2faaee23573cc9243c0c2..1676e4218798224d7ba5464535e2eccb7a4c5c75 100644 (file)
@@ -39,6 +39,7 @@
 #include "lua/lua_common.h"
 #include "contrib/uthash/utlist.h"
 #include "contrib/t1ha/t1ha.h"
+#include "received.h"
 
 #define GTUBE_SYMBOL "GTUBE"
 
@@ -1114,7 +1115,6 @@ rspamd_message_new (struct rspamd_task *task)
 gboolean
 rspamd_message_parse (struct rspamd_task *task)
 {
-       struct rspamd_received_header *recv, *trecv;
        const gchar *p;
        gsize len;
        guint i;
@@ -1221,86 +1221,7 @@ rspamd_message_parse (struct rspamd_task *task)
                task->queue_id = "undef";
        }
 
-       if (MESSAGE_FIELD (task, received)) {
-               gboolean need_recv_correction = FALSE;
-               rspamd_inet_addr_t *raddr;
-
-               recv = MESSAGE_FIELD (task, received);
-               /*
-                * For the first header we must ensure that
-                * received is consistent with the IP that we obtain through
-                * client.
-                */
-
-               raddr = recv->addr;
-               if (recv->real_ip == NULL || (task->cfg && task->cfg->ignore_received)) {
-                       need_recv_correction = TRUE;
-               }
-               else if (!(task->flags & RSPAMD_TASK_FLAG_NO_IP) && task->from_addr) {
-                       if (!raddr) {
-                               need_recv_correction = TRUE;
-                       }
-                       else {
-                               if (rspamd_inet_address_compare (raddr, task->from_addr, FALSE) != 0) {
-                                       need_recv_correction = TRUE;
-                               }
-                       }
-               }
-
-               if (need_recv_correction && !(task->flags & RSPAMD_TASK_FLAG_NO_IP)
-                               && task->from_addr) {
-                       msg_debug_task ("the first received seems to be"
-                                       " not ours, prepend it with fake one");
-
-                       trecv = rspamd_mempool_alloc0 (task->task_pool,
-                                       sizeof (struct rspamd_received_header));
-                       trecv->flags |= RSPAMD_RECEIVED_FLAG_ARTIFICIAL;
-
-                       if (task->flags & RSPAMD_TASK_FLAG_SSL) {
-                               trecv->flags |= RSPAMD_RECEIVED_FLAG_SSL;
-                       }
-
-                       if (task->user) {
-                               trecv->flags |= RSPAMD_RECEIVED_FLAG_AUTHENTICATED;
-                       }
-
-                       trecv->real_ip = rspamd_mempool_strdup (task->task_pool,
-                                       rspamd_inet_address_to_string (task->from_addr));
-                       trecv->from_ip = trecv->real_ip;
-                       trecv->by_hostname = rspamd_mempool_get_variable (task->task_pool,
-                                       RSPAMD_MEMPOOL_MTA_NAME);
-                       trecv->addr = rspamd_inet_address_copy (task->from_addr);
-                       rspamd_mempool_add_destructor (task->task_pool,
-                                       (rspamd_mempool_destruct_t)rspamd_inet_address_free,
-                                       trecv->addr);
-
-                       if (task->hostname) {
-                               trecv->real_hostname = task->hostname;
-                               trecv->from_hostname = trecv->real_hostname;
-                       }
-
-                       DL_PREPEND (MESSAGE_FIELD (task, received), trecv);
-               }
-       }
-
-       /* Extract data from received header if we were not given IP */
-       if (MESSAGE_FIELD (task, received) && (task->flags & RSPAMD_TASK_FLAG_NO_IP) &&
-                       (task->cfg && !task->cfg->ignore_received)) {
-               recv = MESSAGE_FIELD (task, received);
-               if (recv->real_ip) {
-                       if (!rspamd_parse_inet_address (&task->from_addr,
-                                       recv->real_ip,
-                                       strlen (recv->real_ip),
-                                       RSPAMD_INET_ADDRESS_PARSE_NO_UNIX)) {
-                               msg_warn_task ("cannot get IP from received header: '%s'",
-                                               recv->real_ip);
-                               task->from_addr = NULL;
-                       }
-               }
-               if (recv->real_hostname) {
-                       task->hostname = recv->real_hostname;
-               }
-       }
+       rspamd_received_maybe_fix_task(task);
 
        struct rspamd_mime_part *part;
 
index 7afb0e7a6c2aafbcfc64d441145ea17f60e139cd..88675a62932014ab2ca8e9c33609cffd701dd78b 100644 (file)
@@ -38,7 +38,6 @@ rspamd_mime_header_check_special (struct rspamd_task *task,
                struct rspamd_mime_header *rh)
 {
        guint64 h;
-       struct rspamd_received_header *recv;
        const gchar *p, *end;
        gchar *id;
        gint max_recipients = -1, len;
@@ -51,16 +50,9 @@ rspamd_mime_header_check_special (struct rspamd_task *task,
 
        switch (h) {
        case 0x88705DC4D9D61ABULL:      /* received */
-               recv = rspamd_mempool_alloc0 (task->task_pool,
-                               sizeof (struct rspamd_received_header));
-               recv->hdr = rh;
-
-               if (rspamd_smtp_received_parse (task, rh->decoded,
-                               strlen (rh->decoded), recv) != -1) {
-                       DL_APPEND (MESSAGE_FIELD (task, received), recv);
+               if (rspamd_received_header_parse(task, rh->decoded, strlen (rh->decoded), rh)) {
+                       rh->flags |= RSPAMD_HEADER_RECEIVED;
                }
-
-               rh->flags |= RSPAMD_HEADER_RECEIVED;
                break;
        case 0x76F31A09F4352521ULL:     /* to */
                MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool,
index 78c9f1841b4d0ec3a1ea164da140eaacc3aef2d7..3d273081f2eab6018ee2eca434a627a5dd68f3ef 100644 (file)
  * limitations under the License.
  */
 
+#include <mempool_vars_internal.h>
 #include "config.h"
-#include "received.h"
-#include "libserver/task.h"
 #include "libserver/url.h"
+#include "libserver/cfg_file.h"
 #include "mime_string.hxx"
 #include "smtp_parsers.h"
 #include "message.h"
-
-#include <vector>
-#include <string_view>
-#include <utility>
+#include "received.hxx"
 #include "frozen/string.h"
 #include "frozen/unordered_map.h"
 
@@ -39,64 +36,6 @@ enum class received_part_type {
        RSPAMD_RECEIVED_PART_UNKNOWN,
 };
 
-static inline auto
-received_char_filter(UChar32 uc) -> UChar32
-{
-       if (u_isprint(uc)) {
-               return u_tolower(uc);
-       }
-
-       return 0;
-}
-
-
-struct received_header {
-       mime_string from_hostname;
-       std::string_view from_ip;
-       mime_string real_hostname;
-       mime_string real_ip;
-       mime_string by_hostname;
-       std::string_view for_mbox;
-       struct rspamd_email_address *for_addr = nullptr;
-       rspamd_inet_addr_t *addr = nullptr;
-       struct rspamd_mime_header *hdr = nullptr;
-       time_t timestamp = 0;
-       int flags = 0; /* See enum rspamd_received_type */
-
-       received_header() noexcept
-                       : from_hostname(received_char_filter),
-                         real_hostname(received_char_filter),
-                         real_ip(received_char_filter),
-                         by_hostname(received_char_filter),
-                         for_mbox(received_char_filter) {}
-
-       ~received_header() {
-               if (for_addr) {
-                       rspamd_email_address_free(for_addr);
-               }
-       }
-};
-
-class received_header_chain {
-public:
-       explicit received_header_chain(struct rspamd_task *_task) : task(_task) {
-               headers.reserve(2);
-               rspamd_mempool_add_destructor(task->task_pool,
-                               received_header_chain::received_header_chain_pool_dtor, this);
-       }
-
-       auto new_received() -> received_header & {
-               headers.emplace_back();
-               return headers.back();
-       }
-private:
-       static auto received_header_chain_pool_dtor(void *ptr) -> void {
-               delete static_cast<received_header_chain *>(ptr);
-       }
-       std::vector<received_header> headers;
-       struct rspamd_task *task;
-};
-
 struct received_part {
        received_part_type type;
        mime_string data;
@@ -642,7 +581,7 @@ received_process_from(struct rspamd_task *task,
        }
 }
 
-auto
+static auto
 received_header_parse(struct rspamd_task *task, const std::string_view &in,
                                          struct rspamd_mime_header *hdr) -> bool
 {
@@ -734,6 +673,94 @@ received_header_parse(struct rspamd_task *task, const std::string_view &in,
        return true;
 }
 
+static auto
+received_maybe_fix_task(struct rspamd_task *task) -> bool
+{
+       auto *recv_chain_ptr = static_cast<received_header_chain *>(MESSAGE_FIELD(task, received_headers));
+
+       if (recv_chain_ptr) {
+               auto need_recv_correction = false;
+
+               auto top_recv_maybe = recv_chain_ptr->get_received(0);
+
+               if (top_recv_maybe.has_value()) {
+                       auto &top_recv = top_recv_maybe.value().get();
+
+                       const auto *raddr = top_recv.addr;
+                       if (top_recv.real_ip.size() == 0 || (task->cfg && task->cfg->ignore_received)) {
+                               need_recv_correction = true;
+                       }
+                       else if (!(task->flags & RSPAMD_TASK_FLAG_NO_IP) && task->from_addr) {
+                               if (!raddr) {
+                                       need_recv_correction = true;
+                               }
+                               else {
+                                       if (rspamd_inet_address_compare(raddr, task->from_addr, FALSE) != 0) {
+                                               need_recv_correction = true;
+                                       }
+                               }
+                       }
+
+                       if (need_recv_correction && !(task->flags & RSPAMD_TASK_FLAG_NO_IP)
+                                       && task->from_addr) {
+                               msg_debug_task ("the first received seems to be"
+                                                               " not ours, prepend it with fake one");
+
+                               auto trecv = recv_chain_ptr->new_received(received_header_chain::append_type::append_head);
+                               trecv.flags |= RSPAMD_RECEIVED_FLAG_ARTIFICIAL;
+
+                               if (task->flags & RSPAMD_TASK_FLAG_SSL) {
+                                       trecv.flags |= RSPAMD_RECEIVED_FLAG_SSL;
+                               }
+
+                               if (task->user) {
+                                       trecv.flags |= RSPAMD_RECEIVED_FLAG_AUTHENTICATED;
+                               }
+
+                               trecv.real_ip.assign_copy(std::string_view(rspamd_inet_address_to_string(task->from_addr)));
+                               trecv.from_ip = trecv.real_ip.as_view();
+
+                               const auto *mta_name = (const char*)rspamd_mempool_get_variable(task->task_pool,
+                                               RSPAMD_MEMPOOL_MTA_NAME);
+
+                               if (mta_name) {
+                                       trecv.by_hostname.assign_copy(std::string_view(mta_name));
+                               }
+                               trecv.addr = rspamd_inet_address_copy(task->from_addr);
+
+                               if (task->hostname) {
+                                       trecv.real_hostname.assign_copy(std::string_view(task->hostname));
+                                       trecv.from_hostname.assign_copy(trecv.real_hostname);
+                               }
+
+                               return true;
+                       }
+
+                       /* Extract data from received header if we were not given IP */
+                       if (!need_recv_correction && (task->flags & RSPAMD_TASK_FLAG_NO_IP) &&
+                               (task->cfg && !task->cfg->ignore_received)) {
+                               if (!top_recv.real_ip.empty()) {
+                                       if (!rspamd_parse_inet_address (&task->from_addr,
+                                                       top_recv.real_ip.data(),
+                                                       top_recv.real_ip.size(),
+                                                       RSPAMD_INET_ADDRESS_PARSE_NO_UNIX)) {
+                                               msg_warn_task ("cannot get IP from received header: '%s'",
+                                                               top_recv.real_ip.data());
+                                               task->from_addr = nullptr;
+                                       }
+                               }
+                               if (!top_recv.real_hostname.empty()) {
+                                       task->hostname = top_recv.real_hostname.data();
+                               }
+
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+}
+
 } // namespace rspamd::mime
 
 bool
@@ -743,3 +770,9 @@ rspamd_received_header_parse(struct rspamd_task *task,
 {
        return rspamd::mime::received_header_parse(task, std::string_view{data, sz}, hdr);
 }
+
+bool
+rspamd_received_maybe_fix_task(struct rspamd_task *task)
+{
+       return rspamd::mime::received_maybe_fix_task(task);
+}
index bc3c31e0db3f0ce300bcfda227b2d87d63d2c116..845bf4357c51d9810b27fc464e5361b308ac535f 100644 (file)
@@ -24,6 +24,9 @@
 #ifdef  __cplusplus
 extern "C" {
 #endif
+/*
+ * C bindings for C++ received code
+ */
 
 enum rspamd_received_type {
        RSPAMD_RECEIVED_SMTP = 1u << 0u,
@@ -58,9 +61,25 @@ struct rspamd_email_address;
 struct rspamd_received_header_chain;
 struct rspamd_mime_header;
 
+/**
+ * Parse received header from an input header data
+ * @param task
+ * @param data
+ * @param sz
+ * @param hdr
+ * @return
+ */
 bool rspamd_received_header_parse(struct rspamd_task *task,
                const char *data, size_t sz, struct rspamd_mime_header *hdr);
 
+
+/**
+ * Process task data and the most top received and fix either part if needed
+ * @param task
+ * @return
+ */
+bool rspamd_received_maybe_fix_task(struct rspamd_task *task);
+
 #ifdef  __cplusplus
 }
 #endif