aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2021-10-04 21:46:15 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2021-10-04 21:46:15 +0100
commit513b6c6ab95cb36b5405de394f24b59f4f2b9a3d (patch)
treedbb195369fa4b5776555217d84b0474139e22aec /src
parenta3752855c6c378da51b73a1e854b439eb472cc56 (diff)
downloadrspamd-513b6c6ab95cb36b5405de394f24b59f4f2b9a3d.tar.gz
rspamd-513b6c6ab95cb36b5405de394f24b59f4f2b9a3d.zip
[Project] Start using of the new received structure
Diffstat (limited to 'src')
-rw-r--r--src/libmime/message.c83
-rw-r--r--src/libmime/mime_headers.c12
-rw-r--r--src/libmime/received.cxx163
-rw-r--r--src/libmime/received.h19
4 files changed, 121 insertions, 156 deletions
diff --git a/src/libmime/message.c b/src/libmime/message.c
index e6fc5be94..1676e4218 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -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;
diff --git a/src/libmime/mime_headers.c b/src/libmime/mime_headers.c
index 7afb0e7a6..88675a629 100644
--- a/src/libmime/mime_headers.c
+++ b/src/libmime/mime_headers.c
@@ -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,
diff --git a/src/libmime/received.cxx b/src/libmime/received.cxx
index 78c9f1841..3d273081f 100644
--- a/src/libmime/received.cxx
+++ b/src/libmime/received.cxx
@@ -14,17 +14,14 @@
* 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);
+}
diff --git a/src/libmime/received.h b/src/libmime/received.h
index bc3c31e0d..845bf4357 100644
--- a/src/libmime/received.h
+++ b/src/libmime/received.h
@@ -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