From fd70a499d4364d622ab47092703f3bfaa72a149f Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 14 Jun 2016 18:07:27 +0100 Subject: [PATCH] [Feature] Use new received parser instead of old one --- src/libmime/message.c | 354 +-------------------- src/libmime/parsers/smtp_received_parser.c | 200 +++++++----- src/lua/lua_task.c | 32 +- src/ragel/smtp_ip.rl | 2 +- src/ragel/smtp_received_parser.rl | 56 +++- 5 files changed, 206 insertions(+), 438 deletions(-) diff --git a/src/libmime/message.c b/src/libmime/message.c index e8f5cd96b..6206c9e7f 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -51,338 +51,6 @@ rspamd_message_quark (void) return g_quark_from_static_string ("mime-error"); } -static void -parse_qmail_recv (rspamd_mempool_t * pool, - gchar *line, - struct received_header *r) -{ - gchar *s, *p, t; - - /* We are interested only with received from network headers */ - if ((p = strstr (line, "from network")) == NULL) { - r->is_error = 2; - return; - } - - p += sizeof ("from network") - 1; - while (g_ascii_isspace (*p) || *p == '[') { - p++; - } - /* format is ip/host */ - s = p; - if (*p) { - while (g_ascii_isdigit (*++p) || *p == '.') ; - if (*p != '/') { - r->is_error = 1; - return; - } - else { - *p = '\0'; - r->real_ip = rspamd_mempool_strdup (pool, s); - *p = '/'; - /* Now try to parse hostname */ - s = ++p; - while (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == - '_') { - p++; - } - t = *p; - *p = '\0'; - r->real_hostname = rspamd_mempool_strdup (pool, s); - *p = t; - } - } -} - -static void -parse_recv_header (rspamd_mempool_t * pool, - struct raw_header *rh, - struct received_header *r) -{ - gchar *p, *s, t, **res = NULL; - gchar *line; - enum { - RSPAMD_RECV_STATE_INIT = 0, - RSPAMD_RECV_STATE_FROM, - RSPAMD_RECV_STATE_IP_BLOCK, - RSPAMD_RECV_STATE_BRACES_BLOCK, - RSPAMD_RECV_STATE_BY_BLOCK, - RSPAMD_RECV_STATE_PARSE_IP, - RSPAMD_RECV_STATE_PARSE_IP6, - RSPAMD_RECV_STATE_SKIP_SPACES, - RSPAMD_RECV_STATE_ERROR - } state = RSPAMD_RECV_STATE_INIT, next_state = RSPAMD_RECV_STATE_INIT; - gboolean is_exim = FALSE; - - line = rh->decoded; - if (line == NULL) { - return; - } - - g_strstrip (line); - p = line; - s = line; - - while (*p) { - switch (state) { - /* Initial state, search for from */ - case RSPAMD_RECV_STATE_INIT: - if (*p == 'f' || *p == 'F') { - if (g_ascii_tolower (*++p) == 'r' && g_ascii_tolower (*++p) == - 'o' && g_ascii_tolower (*++p) == 'm') { - p++; - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_FROM; - } - } - else if (g_ascii_tolower (*p) == 'b' && - g_ascii_tolower (*(p + 1)) == 'y') { - state = RSPAMD_RECV_STATE_IP_BLOCK; - } - else { - /* This can be qmail header, parse it separately */ - parse_qmail_recv (pool, line, r); - return; - } - break; - /* Read hostname */ - case RSPAMD_RECV_STATE_FROM: - if (*p == '[') { - /* This should be IP address */ - res = &r->from_ip; - state = RSPAMD_RECV_STATE_PARSE_IP; - next_state = RSPAMD_RECV_STATE_IP_BLOCK; - s = ++p; - } - else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == - '_') { - p++; - } - else { - t = *p; - *p = '\0'; - r->from_hostname = rspamd_mempool_strdup (pool, s); - *p = t; - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_IP_BLOCK; - } - break; - /* Try to extract additional info */ - case RSPAMD_RECV_STATE_IP_BLOCK: - /* Try to extract ip or () info or by */ - if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == - 'y') { - p += 2; - /* Skip spaces after by */ - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_BY_BLOCK; - } - else if (*p == '(') { - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; - p++; - } - else if (*p == '[') { - /* Got ip before '(' so extract it */ - s = ++p; - res = &r->from_ip; - state = RSPAMD_RECV_STATE_PARSE_IP; - next_state = RSPAMD_RECV_STATE_IP_BLOCK; - } - else { - p++; - } - break; - /* We are in () block. Here can be found real hostname and real ip, this is written by some MTA */ - case RSPAMD_RECV_STATE_BRACES_BLOCK: - /* End of block */ - if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || - *p == '_' || *p == ':') { - p++; - } - else if (*p == '[') { - s = ++p; - state = RSPAMD_RECV_STATE_PARSE_IP; - res = &r->real_ip; - next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; - } - else { - if (p > s) { - /* Got some real hostname */ - /* check whether it is helo or p is not space symbol */ - if (!g_ascii_isspace (*p) || *(p + 1) != '[') { - /* Exim style ([ip]:port helo=hostname) */ - if (*s == ':' && (g_ascii_isspace (*p) || *p == ')')) { - /* Ip ending */ - is_exim = TRUE; - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; - } - else if (p - s == 4 && memcmp (s, "helo=", 5) == 0) { - p++; - is_exim = TRUE; - if (r->real_hostname == NULL && r->from_hostname != - NULL) { - r->real_hostname = r->from_hostname; - } - s = p; - while (*p != ')' && !g_ascii_isspace (*p) && *p != - '\0') { - p++; - } - if (p > s) { - r->from_hostname = rspamd_mempool_alloc (pool, - p - s + 1); - rspamd_strlcpy (r->from_hostname, s, p - s + 1); - } - } - else if (p - s == 4 && memcmp (s, "port=", 5) == 0) { - p++; - is_exim = TRUE; - while (g_ascii_isdigit (*p)) { - p++; - } - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; - } - else if (*p == '=' && is_exim) { - /* Just skip unknown pairs */ - p++; - while (!g_ascii_isspace (*p) && *p != ')' && *p != - '\0') { - p++; - } - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; - } - else { - /* skip all */ - while (*p++ != ')' && *p != '\0') ; - state = RSPAMD_RECV_STATE_IP_BLOCK; - } - } - else { - /* Postfix style (hostname [ip]) */ - t = *p; - *p = '\0'; - r->real_hostname = rspamd_mempool_strdup (pool, s); - *p = t; - /* Now parse ip */ - p += 2; - s = p; - res = &r->real_ip; - state = RSPAMD_RECV_STATE_PARSE_IP; - next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; - continue; - } - if (*p == ')') { - p++; - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_IP_BLOCK; - } - } - else if (*p == ')') { - p++; - state = RSPAMD_RECV_STATE_SKIP_SPACES; - next_state = RSPAMD_RECV_STATE_IP_BLOCK; - } - else { - r->is_error = 1; - return; - } - } - break; - /* Got by word */ - case RSPAMD_RECV_STATE_BY_BLOCK: - /* Here can be only hostname */ - if ((g_ascii_isalnum (*p) || *p == '.' || *p == '-' - || *p == '_') && p[1] != '\0') { - p++; - } - else { - /* We got something like hostname */ - if (p[1] != '\0') { - t = *p; - *p = '\0'; - r->by_hostname = rspamd_mempool_strdup (pool, s); - *p = t; - } - else { - r->by_hostname = rspamd_mempool_strdup (pool, s); - } - /* Now end of parsing */ - if (is_exim) { - /* Adjust for exim received */ - if (r->real_ip == NULL && r->from_ip != NULL) { - r->real_ip = r->from_ip; - } - else if (r->from_ip == NULL && r->real_ip != NULL) { - r->from_ip = r->real_ip; - if (r->real_hostname == NULL && r->from_hostname != - NULL) { - r->real_hostname = r->from_hostname; - } - } - } - return; - } - break; - - /* Extract ip */ - case RSPAMD_RECV_STATE_PARSE_IP: - if (*p == 'I') { - /* IPv6: */ - state = RSPAMD_RECV_STATE_PARSE_IP6; - } - else { - while (g_ascii_isxdigit (*p) || *p == '.' || *p == ':') { - p++; - } - if (*p != ']') { - /* Not an ip in fact */ - state = RSPAMD_RECV_STATE_SKIP_SPACES; - p++; - } - else { - *p = '\0'; - *res = rspamd_mempool_strdup (pool, s); - *p = ']'; - p++; - state = RSPAMD_RECV_STATE_SKIP_SPACES; - } - } - break; - case RSPAMD_RECV_STATE_PARSE_IP6: - if (g_ascii_strncasecmp (p, "IPv6:", sizeof ("IPv6") - 1) == 0) { - p += sizeof ("IPv6") - 1; - s = p; - state = RSPAMD_RECV_STATE_PARSE_IP; - } - else { - state = RSPAMD_RECV_STATE_SKIP_SPACES; - } - break; - /* Skip spaces */ - case RSPAMD_RECV_STATE_SKIP_SPACES: - if (!g_ascii_isspace (*p)) { - state = next_state; - s = p; - } - else { - p++; - } - break; - default: - r->is_error = 1; - return; - break; - } - } - - r->is_error = 1; - return; -} - static void append_raw_header (struct rspamd_task *task, GHashTable *target, struct raw_header *rh) @@ -1779,15 +1447,13 @@ rspamd_message_parse (struct rspamd_task *task) rspamd_images_process (task); /* Parse received headers */ - first = - rspamd_message_get_header (task, "Received", FALSE); + first = rspamd_message_get_header (task, "Received", FALSE); 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); - + recv = rspamd_mempool_alloc0 (task->task_pool, + sizeof (struct received_header)); + rh = cur->data; + rspamd_smtp_recieved_parse (task, rh->decoded, strlen (rh->decoded), recv); /* * For the first header we must ensure that * received is consistent with the IP that we obtain through @@ -1795,22 +1461,19 @@ rspamd_message_parse (struct rspamd_task *task) */ if (i == 0) { gboolean need_recv_correction = FALSE; + rspamd_inet_addr_t *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) { - rspamd_inet_addr_t *raddr = NULL; - - if (!rspamd_parse_inet_address (&raddr, recv->real_ip, 0)) { + if (raddr) { need_recv_correction = TRUE; } else { if (rspamd_inet_address_compare (raddr, task->from_addr) != 0) { need_recv_correction = TRUE; } - - rspamd_inet_address_destroy (raddr); } } @@ -1825,11 +1488,14 @@ rspamd_message_parse (struct rspamd_task *task) trecv->real_ip = rspamd_mempool_strdup (task->task_pool, rspamd_inet_address_to_string (task->from_addr)); trecv->from_ip = trecv->real_ip; + trecv->addr = task->from_addr; if (task->hostname) { trecv->real_hostname = task->hostname; trecv->from_hostname = trecv->real_hostname; } + + g_ptr_array_add (task->received, trecv); } } diff --git a/src/libmime/parsers/smtp_received_parser.c b/src/libmime/parsers/smtp_received_parser.c index ffdfde8b4..c945208fb 100644 --- a/src/libmime/parsers/smtp_received_parser.c +++ b/src/libmime/parsers/smtp_received_parser.c @@ -1,7 +1,7 @@ #line 1 "../rspamd/src/ragel/smtp_received_parser.rl" -#line 201 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 237 "../rspamd/src/ragel/smtp_received_parser.rl" @@ -6183,7 +6183,7 @@ static const int smtp_received_parser_error = 0; static const int smtp_received_parser_en_main = 1; -#line 204 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 240 "../rspamd/src/ragel/smtp_received_parser.rl" static int rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t len, struct received_header *rh) @@ -6195,7 +6195,7 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l *reported_ip_start, *reported_ip_end, *ip_start, *ip_end; const char *p = data, *pe = data + len, *eof; - int cs; + int cs, in_v6 = 0; memset (rh, 0, sizeof (*rh)); real_domain_start = NULL; @@ -6220,7 +6220,7 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l cs = smtp_received_parser_start; } -#line 235 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 271 "../rspamd/src/ragel/smtp_received_parser.rl" #line 6226 "../rspamd/src/libmime/parsers/smtp_received_parser.c" { @@ -6292,23 +6292,26 @@ _match: case 24: #line 6 "../rspamd/src/ragel/smtp_received_parser.rl" { + in_v6 = 1; ip_start = p; } break; case 25: -#line 12 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 14 "../rspamd/src/ragel/smtp_received_parser.rl" { - ip_start = p; + if (!in_v6) { + ip_start = p; + } } break; case 9: -#line 19 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 25 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->user = p; } break; case 11: -#line 23 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 29 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->user) { addr->user_len = p - addr->user; @@ -6316,20 +6319,20 @@ _match: } break; case 17: -#line 29 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 35 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->domain = p; } break; case 19: -#line 39 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 45 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->domain = p; addr->flags |= RSPAMD_EMAIL_ADDR_IP; } break; case 21: -#line 44 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 50 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->domain) { addr->domain_len = p - addr->domain; @@ -6337,25 +6340,25 @@ _match: } break; case 13: -#line 50 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 56 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->flags |= RSPAMD_EMAIL_ADDR_HAS_BACKSLASH; } break; case 12: -#line 54 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 60 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->flags |= RSPAMD_EMAIL_ADDR_QUOTED; } break; case 16: -#line 73 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 79 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->addr = p; } break; case 30: -#line 77 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->addr) { addr->addr_len = p - addr->addr; @@ -6363,37 +6366,57 @@ _match: } break; case 4: -#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 89 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = p; } break; case 36: -#line 86 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 92 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_end = p; } break; case 5: -#line 96 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 102 "../rspamd/src/ragel/smtp_received_parser.rl" { - real_domain_start = p; + real_ip_start = p; } break; case 37: -#line 99 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 105 "../rspamd/src/ragel/smtp_received_parser.rl" { - real_domain_end = p; + if (ip_start && ip_end && ip_end > ip_start) { + real_ip_start = ip_start; + real_ip_end = ip_end; + } + else { + real_ip_end = p; + } + + ip_start = NULL; + ip_end = NULL; } break; case 38: -#line 135 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 160 "../rspamd/src/ragel/smtp_received_parser.rl" { - /* Do nothing here for now */ + 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); + } + 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); + } } break; case 39: -#line 139 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 175 "../rspamd/src/ragel/smtp_received_parser.rl" { guint len; @@ -6425,49 +6448,50 @@ _match: rh->from_hostname = rh->real_hostname; } - if (rh->real_ip && ip_start && ip_end && ip_end > ip_start) { - if (rspamd_parse_inet_address (&rh->addr, ip_start, ip_end - ip_start)) { + 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); } } } break; case 35: -#line 181 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 217 "../rspamd/src/ragel/smtp_received_parser.rl" { rh->type = RSPAMD_RECEIVED_SMTP; } break; case 32: -#line 184 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 220 "../rspamd/src/ragel/smtp_received_parser.rl" { rh->type = RSPAMD_RECEIVED_ESMTPS; } break; case 31: -#line 187 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 223 "../rspamd/src/ragel/smtp_received_parser.rl" { rh->type = RSPAMD_RECEIVED_ESMTP; } break; case 34: -#line 190 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 226 "../rspamd/src/ragel/smtp_received_parser.rl" { rh->type = RSPAMD_RECEIVED_LMTP; } break; case 33: -#line 193 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 229 "../rspamd/src/ragel/smtp_received_parser.rl" { rh->type = RSPAMD_RECEIVED_IMAP; } break; case 27: -#line 9 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 10 "../rspamd/src/ragel/smtp_received_parser.rl" { + in_v6 = 0; ip_end = p; } -#line 44 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 50 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->domain) { addr->domain_len = p - addr->domain; @@ -6475,11 +6499,13 @@ _match: } break; case 23: -#line 15 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 19 "../rspamd/src/ragel/smtp_received_parser.rl" { - ip_end = p; + if (!in_v6) { + ip_end = p; + } } -#line 44 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 50 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->domain) { addr->domain_len = p - addr->domain; @@ -6487,11 +6513,11 @@ _match: } break; case 10: -#line 19 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 25 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->user = p; } -#line 23 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 29 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->user) { addr->user_len = p - addr->user; @@ -6499,13 +6525,13 @@ _match: } break; case 28: -#line 33 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 39 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->domain) { addr->domain_len = p - addr->domain; } } -#line 77 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->addr) { addr->addr_len = p - addr->addr; @@ -6513,22 +6539,24 @@ _match: } break; case 20: -#line 39 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 45 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->domain = p; addr->flags |= RSPAMD_EMAIL_ADDR_IP; } -#line 12 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 14 "../rspamd/src/ragel/smtp_received_parser.rl" { - ip_start = p; + if (!in_v6) { + ip_start = p; + } } break; case 14: -#line 50 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 56 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->flags |= RSPAMD_EMAIL_ADDR_HAS_BACKSLASH; } -#line 23 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 29 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->user) { addr->user_len = p - addr->user; @@ -6536,39 +6564,39 @@ _match: } break; case 29: -#line 69 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 75 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->flags |= RSPAMD_EMAIL_ADDR_BRACED; } -#line 177 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 213 "../rspamd/src/ragel/smtp_received_parser.rl" { } break; case 15: -#line 73 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 79 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->addr = p; } -#line 19 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 25 "../rspamd/src/ragel/smtp_received_parser.rl" { addr->user = p; } break; case 22: -#line 77 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->addr) { addr->addr_len = p - addr->addr; } } -#line 177 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 213 "../rspamd/src/ragel/smtp_received_parser.rl" { } break; case 2: -#line 109 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 134 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = NULL; real_domain_end = NULL; @@ -6581,13 +6609,13 @@ _match: ip_start = NULL; ip_end = NULL; } -#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 89 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = p; } break; case 7: -#line 122 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 147 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = NULL; real_domain_end = NULL; @@ -6600,21 +6628,24 @@ _match: ip_start = NULL; ip_end = NULL; } -#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 89 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = p; } break; case 26: -#line 15 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 19 "../rspamd/src/ragel/smtp_received_parser.rl" { - ip_end = p; + if (!in_v6) { + ip_end = p; + } } -#line 9 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 10 "../rspamd/src/ragel/smtp_received_parser.rl" { + in_v6 = 0; ip_end = p; } -#line 44 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 50 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->domain) { addr->domain_len = p - addr->domain; @@ -6622,47 +6653,58 @@ _match: } break; case 18: -#line 33 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 39 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->domain) { addr->domain_len = p - addr->domain; } } -#line 77 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" { if (addr->addr) { addr->addr_len = p - addr->addr; } } -#line 177 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 213 "../rspamd/src/ragel/smtp_received_parser.rl" { } break; case 8: -#line 86 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 92 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_end = p; } -#line 92 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 98 "../rspamd/src/ragel/smtp_received_parser.rl" { reported_domain_end = p; } -#line 135 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 160 "../rspamd/src/ragel/smtp_received_parser.rl" { - /* Do nothing here for now */ + 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); + } + 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); + } } break; case 3: -#line 86 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 92 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_end = p; } -#line 92 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 98 "../rspamd/src/ragel/smtp_received_parser.rl" { reported_domain_end = p; } -#line 139 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 175 "../rspamd/src/ragel/smtp_received_parser.rl" { guint len; @@ -6694,15 +6736,15 @@ _match: rh->from_hostname = rh->real_hostname; } - if (rh->real_ip && ip_start && ip_end && ip_end > ip_start) { - if (rspamd_parse_inet_address (&rh->addr, ip_start, ip_end - ip_start)) { + 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); } } } break; case 1: -#line 109 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 134 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = NULL; real_domain_end = NULL; @@ -6715,17 +6757,17 @@ _match: ip_start = NULL; ip_end = NULL; } -#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 89 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = p; } -#line 89 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 95 "../rspamd/src/ragel/smtp_received_parser.rl" { reported_domain_start = p; } break; case 6: -#line 122 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 147 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = NULL; real_domain_end = NULL; @@ -6738,16 +6780,16 @@ _match: ip_start = NULL; ip_end = NULL; } -#line 83 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 89 "../rspamd/src/ragel/smtp_received_parser.rl" { real_domain_start = p; } -#line 89 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 95 "../rspamd/src/ragel/smtp_received_parser.rl" { reported_domain_start = p; } break; -#line 6751 "../rspamd/src/libmime/parsers/smtp_received_parser.c" +#line 6793 "../rspamd/src/libmime/parsers/smtp_received_parser.c" } _again: @@ -6759,7 +6801,7 @@ _again: _out: {} } -#line 236 "../rspamd/src/ragel/smtp_received_parser.rl" +#line 272 "../rspamd/src/ragel/smtp_received_parser.rl" return cs; } diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 7a756679b..cbcaf2ed5 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -1427,6 +1427,7 @@ lua_task_get_received_headers (lua_State * L) { struct rspamd_task *task = lua_check_task (L, 1); struct received_header *rh; + const gchar *proto; guint i, k = 1; if (task) { @@ -1445,12 +1446,35 @@ lua_task_get_received_headers (lua_State * L) lua_newtable (L); rspamd_lua_table_set (L, "from_hostname", rh->from_hostname); - lua_pushstring (L, "from_ip"); - rspamd_lua_ip_push_fromstring (L, rh->from_ip); - lua_settable (L, -3); + rspamd_lua_table_set (L, "from_ip", rh->from_ip); rspamd_lua_table_set (L, "real_hostname", rh->real_hostname); lua_pushstring (L, "real_ip"); - rspamd_lua_ip_push_fromstring (L, rh->real_ip); + rspamd_lua_ip_push (L, rh->addr); + lua_settable (L, -3); + lua_pushstring (L, "proto"); + + switch (rh->type) { + case RSPAMD_RECEIVED_SMTP: + proto = "smtp"; + break; + case RSPAMD_RECEIVED_ESMTP: + proto = "esmtp"; + break; + case RSPAMD_RECEIVED_ESMTPS: + proto = "esmtps"; + break; + case RSPAMD_RECEIVED_LMTP: + proto = "lmtp"; + break; + case RSPAMD_RECEIVED_IMAP: + proto = "imap"; + break; + case RSPAMD_RECEIVED_UNKNOWN: + default: + proto = "unknown"; + break; + } + lua_pushstring (L, proto); lua_settable (L, -3); rspamd_lua_table_set (L, "by_hostname", rh->by_hostname); lua_rawseti (L, -2, k ++); diff --git a/src/ragel/smtp_ip.rl b/src/ragel/smtp_ip.rl index b060b750a..dae90a096 100644 --- a/src/ragel/smtp_ip.rl +++ b/src/ragel/smtp_ip.rl @@ -15,5 +15,5 @@ (IPv6_hex (":" IPv6_hex){0,3} ":")? IPv4_address_literal; IPv6_addr = IPv6_full | IPv6_comp | IPv6v4_full | IPv6v4_comp; - IPv6_address_literal = "IPv6:" (IPv6_addr >IP6_start %IP6_end); + IPv6_address_literal = "IPv6:" %IP6_start IPv6_addr %IP6_end; }%% \ No newline at end of file diff --git a/src/ragel/smtp_received_parser.rl b/src/ragel/smtp_received_parser.rl index 6cc054a4d..339326900 100644 --- a/src/ragel/smtp_received_parser.rl +++ b/src/ragel/smtp_received_parser.rl @@ -4,16 +4,22 @@ action IP6_start { + in_v6 = 1; ip_start = p; } action IP6_end { + in_v6 = 0; ip_end = p; } action IP4_start { - ip_start = p; + if (!in_v6) { + ip_start = p; + } } action IP4_end { - ip_end = p; + if (!in_v6) { + ip_end = p; + } } action User_start { @@ -94,16 +100,35 @@ } action Real_IP_Start { - real_domain_start = p; + real_ip_start = p; } action Real_IP_End { - real_domain_end = p; + if (ip_start && ip_end && ip_end > ip_start) { + real_ip_start = ip_start; + real_ip_end = ip_end; + } + else { + real_ip_end = p; + } + + ip_start = NULL; + ip_end = NULL; } action Reported_IP_Start { - reported_domain_start = p; + reported_ip_start = p; } action Reported_IP_End { - reported_domain_end = p; + + if (ip_start && ip_end && ip_end > ip_start) { + reported_ip_start = ip_start; + reported_ip_end = ip_end; + } + else { + reported_ip_end = p; + } + + ip_start = NULL; + ip_end = NULL; } action From_Start { @@ -133,7 +158,18 @@ } action By_End { - /* Do nothing here for now */ + 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); + } + 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); + } } action From_End { @@ -167,8 +203,8 @@ rh->from_hostname = rh->real_hostname; } - if (rh->real_ip && ip_start && ip_end && ip_end > ip_start) { - if (rspamd_parse_inet_address (&rh->addr, ip_start, ip_end - ip_start)) { + 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); } } @@ -212,7 +248,7 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l *reported_ip_start, *reported_ip_end, *ip_start, *ip_end; const char *p = data, *pe = data + len, *eof; - int cs; + int cs, in_v6 = 0; memset (rh, 0, sizeof (*rh)); real_domain_start = NULL; -- 2.39.5