summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-04-02 11:59:38 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-04-02 12:00:23 +0100
commit3a8236c9344d6c757760a785510315d851bcbe62 (patch)
treebe97b46a8eedc63d43930c3bfd3d235cdf8318be
parent7243cd2f76e3c691b555770090a0cade43ada32b (diff)
downloadrspamd-3a8236c9344d6c757760a785510315d851bcbe62.tar.gz
rspamd-3a8236c9344d6c757760a785510315d851bcbe62.zip
[Fix] Fix parsing of non-RFC compatible Exim received
Issue: #1575
-rw-r--r--src/ragel/smtp_ip.rl6
-rw-r--r--src/ragel/smtp_received.rl5
-rw-r--r--src/ragel/smtp_received_parser.rl89
3 files changed, 48 insertions, 52 deletions
diff --git a/src/ragel/smtp_ip.rl b/src/ragel/smtp_ip.rl
index dae90a096..cd9bec64f 100644
--- a/src/ragel/smtp_ip.rl
+++ b/src/ragel/smtp_ip.rl
@@ -5,7 +5,8 @@
# Source: https://tools.ietf.org/html/rfc5321#section-4.1.3
Snum = digit{1,3};
- IPv4_address_literal = (Snum ("." Snum){3}) >IP4_start %IP4_end;
+ IPv4_addr = (Snum ("." Snum){3});
+ IPv4_address_literal = IPv4_addr >IP4_start %IP4_end;
IPv6_hex = xdigit{1,4};
IPv6_full = IPv6_hex (":" IPv6_hex){7};
IPv6_comp = (IPv6_hex (":" IPv6_hex){0,5})? "::"
@@ -14,6 +15,7 @@
IPv6v4_comp = (IPv6_hex (":" IPv6_hex){0,3})? "::"
(IPv6_hex (":" IPv6_hex){0,3} ":")?
IPv4_address_literal;
- IPv6_addr = IPv6_full | IPv6_comp | IPv6v4_full | IPv6v4_comp;
+ IPv6_simple = IPv6_full | IPv6_comp;
+ IPv6_addr = IPv6_simple | IPv6v4_full | IPv6v4_comp;
IPv6_address_literal = "IPv6:" %IP6_start IPv6_addr %IP6_end;
}%% \ No newline at end of file
diff --git a/src/ragel/smtp_received.rl b/src/ragel/smtp_received.rl
index 8b88d4ffe..ff3f10d19 100644
--- a/src/ragel/smtp_received.rl
+++ b/src/ragel/smtp_received.rl
@@ -27,9 +27,12 @@
( address_literal >Real_Domain_Start %Real_Domain_End FWS "(" TCP_info ")" ) |
address_literal >Real_IP_Start %Real_IP_End; # Not RFC conforming, but many MTA try this
+ exim_real_ip = "[" (IPv4_addr|IPv6_simple) >IP4_start %IP4_end "]"
+ >Real_IP_Start %Real_IP_End (":" digit{1,4})?;
+ exim_content = exim_real_ip;
ccontent = ctext | FWS | '(' @{ fcall balanced_ccontent; };
balanced_ccontent := ccontent* ')' @{ fret; };
- comment = "(" (FWS? ccontent)* FWS? ")";
+ comment = "(" (FWS? ccontent|exim_content)* FWS? ")";
CFWS = ((FWS? comment)+ FWS?) | FWS;
From_domain = "FROM"i FWS Extended_Domain >From_Start %From_End;
diff --git a/src/ragel/smtp_received_parser.rl b/src/ragel/smtp_received_parser.rl
index 12b1c1b5c..b22f34f03 100644
--- a/src/ragel/smtp_received_parser.rl
+++ b/src/ragel/smtp_received_parser.rl
@@ -134,12 +134,8 @@
action From_Start {
real_domain_start = NULL;
real_domain_end = NULL;
- real_ip_start = NULL;
- real_ip_end = NULL;
reported_domain_start = NULL;
reported_domain_end = NULL;
- reported_ip_start = NULL;
- reported_ip_end = NULL;
ip_start = NULL;
ip_end = NULL;
for_start = NULL;
@@ -149,12 +145,8 @@
action By_Start {
real_domain_start = NULL;
real_domain_end = NULL;
- real_ip_start = NULL;
- real_ip_end = NULL;
reported_domain_start = NULL;
reported_domain_end = NULL;
- reported_ip_start = NULL;
- reported_ip_end = NULL;
ip_start = NULL;
ip_end = NULL;
for_start = NULL;
@@ -162,55 +154,28 @@
}
action By_End {
- guint len;
-
if (real_domain_end && real_domain_start && real_domain_end > real_domain_start) {
- len = real_domain_end - real_domain_start;
- rh->by_hostname = rspamd_mempool_alloc (task->task_pool, len + 1);
- rspamd_strlcpy (rh->by_hostname, real_domain_start, len + 1);
+ tmplen = real_domain_end - real_domain_start;
+ rh->by_hostname = rspamd_mempool_alloc (task->task_pool, tmplen + 1);
+ rspamd_strlcpy (rh->by_hostname, real_domain_start, tmplen + 1);
}
else if (reported_domain_end && reported_domain_start && reported_domain_end > reported_domain_start) {
len = reported_domain_end - reported_domain_start;
- rh->by_hostname = rspamd_mempool_alloc (task->task_pool, len + 1);
- rspamd_strlcpy (rh->by_hostname, reported_domain_start, len + 1);
+ rh->by_hostname = rspamd_mempool_alloc (task->task_pool, tmplen + 1);
+ rspamd_strlcpy (rh->by_hostname, reported_domain_start, tmplen + 1);
}
}
action From_End {
- guint len;
-
if (real_domain_end && real_domain_start && real_domain_end > real_domain_start) {
- len = real_domain_end - real_domain_start;
- rh->real_hostname = rspamd_mempool_alloc (task->task_pool, len + 1);
- rspamd_strlcpy (rh->real_hostname, real_domain_start, len + 1);
+ tmplen = real_domain_end - real_domain_start;
+ rh->real_hostname = rspamd_mempool_alloc (task->task_pool, tmplen + 1);
+ rspamd_strlcpy (rh->real_hostname, real_domain_start, tmplen + 1);
}
if (reported_domain_end && reported_domain_start && reported_domain_end > reported_domain_start) {
- len = reported_domain_end - reported_domain_start;
- rh->from_hostname = rspamd_mempool_alloc (task->task_pool, len + 1);
- rspamd_strlcpy (rh->from_hostname, reported_domain_start, len + 1);
- }
- if (real_ip_end && real_ip_start && real_ip_end > real_ip_start) {
- len = real_ip_end - real_ip_start;
- rh->real_ip = rspamd_mempool_alloc (task->task_pool, len + 1);
- rspamd_strlcpy (rh->real_ip, real_ip_start, len + 1);
- }
- if (reported_ip_end && reported_ip_start && reported_ip_end > reported_ip_start) {
- len = reported_ip_end - reported_ip_start;
- rh->from_ip = rspamd_mempool_alloc (task->task_pool, len + 1);
- rspamd_strlcpy (rh->from_ip, reported_ip_start, len + 1);
- }
-
- if (rh->real_ip && !rh->from_ip) {
- rh->from_ip = rh->real_ip;
- }
- if (rh->real_hostname && !rh->from_hostname) {
- rh->from_hostname = rh->real_hostname;
- }
-
- if (rh->real_ip) {
- if (rspamd_parse_inet_address (&rh->addr, rh->real_ip, strlen (rh->real_ip))) {
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)rspamd_inet_address_destroy, rh->addr);
- }
+ tmplen = reported_domain_end - reported_domain_start;
+ rh->from_hostname = rspamd_mempool_alloc (task->task_pool, tmplen + 1);
+ rspamd_strlcpy (rh->from_hostname, reported_domain_start, tmplen + 1);
}
}
@@ -221,9 +186,9 @@
action For_End {
if (for_start && p > for_start) {
for_end = p;
- len = for_end - for_start;
- rh->for_mbox = rspamd_mempool_alloc (task->task_pool, len + 1);
- rspamd_strlcpy (rh->for_mbox, for_start, len + 1);
+ tmplen = for_end - for_start;
+ rh->for_mbox = rspamd_mempool_alloc (task->task_pool, tmplen + 1);
+ rspamd_strlcpy (rh->for_mbox, for_start, tmplen + 1);
}
}
@@ -287,6 +252,7 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l
int *data;
gsize size;
} st_storage;
+ guint tmplen;
memset (&st_storage, 0, sizeof (st_storage));
memset (rh, 0, sizeof (*rh));
@@ -313,6 +279,31 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l
%% write init;
%% write exec;
+ if (real_ip_end && real_ip_start && real_ip_end > real_ip_start) {
+ tmplen = real_ip_end - real_ip_start;
+ rh->real_ip = rspamd_mempool_alloc (task->task_pool, tmplen + 1);
+ rspamd_strlcpy (rh->real_ip, real_ip_start, tmplen + 1);
+ }
+ if (reported_ip_end && reported_ip_start && reported_ip_end > reported_ip_start) {
+ tmplen = reported_ip_end - reported_ip_start;
+ rh->from_ip = rspamd_mempool_alloc (task->task_pool, tmplen + 1);
+ rspamd_strlcpy (rh->from_ip, reported_ip_start, tmplen + 1);
+ }
+
+ if (rh->real_ip && !rh->from_ip) {
+ rh->from_ip = rh->real_ip;
+ }
+ if (rh->real_hostname && !rh->from_hostname) {
+ rh->from_hostname = rh->real_hostname;
+ }
+
+ if (rh->real_ip) {
+ if (rspamd_parse_inet_address (&rh->addr, rh->real_ip, strlen (rh->real_ip))) {
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t)rspamd_inet_address_destroy, rh->addr);
+ }
+ }
+
if (st_storage.data) {
free (st_storage.data);
}