aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-02-21 18:09:13 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-02-21 18:09:13 +0000
commit9b822f875580954c51f4d1511c9f2e8c2c129a31 (patch)
tree7233469e0516134f351ae098bfb1014632b872b6 /src
parent6584be1e22e4352e5a45da9bf6d4adb2052e97cb (diff)
downloadrspamd-9b822f875580954c51f4d1511c9f2e8c2c129a31.tar.gz
rspamd-9b822f875580954c51f4d1511c9f2e8c2c129a31.zip
Fix interaction with clients with no local Received
Diffstat (limited to 'src')
-rw-r--r--src/libmime/message.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/libmime/message.c b/src/libmime/message.c
index 1d60771d7..0daa5d880 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -1555,13 +1555,13 @@ rspamd_message_parse (struct rspamd_task *task)
struct raw_header *rh;
struct mime_text_part *p1, *p2;
struct mime_foreach_data md;
- struct received_header *recv;
+ struct received_header *recv, *trecv;
gchar *url_str;
const gchar *url_end, *p, *end;
struct rspamd_url *subject_url;
gsize len;
goffset hdr_pos;
- gint rc, state = 0, diff, *pdiff;
+ gint rc, state = 0, diff, *pdiff, i;
guint tw, dw;
tmp = rspamd_mempool_alloc (task->task_pool, sizeof (GByteArray));
@@ -1675,14 +1675,59 @@ rspamd_message_parse (struct rspamd_task *task)
/* Parse received headers */
first =
rspamd_message_get_header (task, "Received", FALSE);
- cur = first;
- while (cur) {
+
+ for (cur = first, i = 0; cur != NULL; cur = g_list_next (cur), i ++) {
recv =
rspamd_mempool_alloc0 (task->task_pool,
sizeof (struct received_header));
parse_recv_header (task->task_pool, cur->data, recv);
+
+ /*
+ * For the first header we must ensure that
+ * received is consistent with the IP that we obtain through
+ * client.
+ */
+ if (i == 0) {
+ gboolean need_recv_correction = FALSE;
+
+ if (recv->real_ip == NULL) {
+ need_recv_correction = TRUE;
+ }
+ else if (!(task->flags & RSPAMD_TASK_FLAG_NO_IP) && task->from_addr) {
+ rspamd_inet_addr_t *raddr = NULL;
+
+ if (!rspamd_parse_inet_address (&raddr, recv->real_ip, 0)) {
+ need_recv_correction = TRUE;
+ }
+ else {
+ if (rspamd_inet_address_compare (raddr, task->from_addr) != 0) {
+ need_recv_correction = TRUE;
+ }
+
+ rspamd_inet_address_destroy (raddr);
+ }
+
+ }
+
+ 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, replace it with fake one");
+
+ trecv = rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct received_header));
+ trecv->real_ip = rspamd_mempool_strdup (task->task_pool,
+ rspamd_inet_address_to_string (task->from_addr));
+ trecv->from_ip = trecv->real_ip;
+
+ if (task->hostname) {
+ trecv->real_hostname = task->hostname;
+ trecv->from_hostname = trecv->real_hostname;
+ }
+ }
+ }
+
g_ptr_array_add (task->received, recv);
- cur = g_list_next (cur);
}
/* Extract data from received header if we were not given IP */