@@ -0,0 +1,77 @@ | |||
%%{ | |||
machine smtp_addr_parser; | |||
action User_start { | |||
addr->user = p; | |||
addr->addr = p; | |||
} | |||
action User_end { | |||
if (addr->user) { | |||
addr->user_len = p - addr->user; | |||
} | |||
} | |||
action Domain_start { | |||
addr->domain = p; | |||
} | |||
action Domain_end { | |||
if (addr->domain) { | |||
addr->domain_len = p - addr->domain; | |||
} | |||
} | |||
action Domain_addr_start { | |||
addr->domain = p; | |||
addr->flags |= RSPAMD_EMAIL_ADDR_IP; | |||
} | |||
action Domain_addr_end { | |||
if (addr->domain) { | |||
addr->domain_len = p - addr->domain; | |||
} | |||
} | |||
action Quoted_addr { | |||
addr->flags |= RSPAMD_EMAIL_ADDR_QUOTED; | |||
} | |||
action Empty_addr { | |||
addr->flags |= RSPAMD_EMAIL_ADDR_EMPTY; | |||
addr->addr = ""; | |||
} | |||
action Valid_addr { | |||
addr->flags |= RSPAMD_EMAIL_ADDR_VALID; | |||
} | |||
action Angled_addr { | |||
addr->flags |= RSPAMD_EMAIL_ADDR_BRACED; | |||
} | |||
include smtp_address "smtp_address.rl"; | |||
main := SMTPAddr; | |||
}%% | |||
%% write data; | |||
static int | |||
rspamd_smtp_addr_parse (const char *data, size_t len, struct rspamd_email_address *addr) | |||
{ | |||
const char *p = data, *pe = data + len, *eof; | |||
int cs; | |||
g_assert (addr != NULL); | |||
memset (addr, 0, sizeof (*addr)); | |||
addr->raw = data; | |||
addr->raw_len = len; | |||
eof = pe; | |||
%% write init; | |||
%% write exec; | |||
return cs; | |||
} |
@@ -0,0 +1,50 @@ | |||
%%{ | |||
machine smtp_address; | |||
include smtp_ip "smtp_ip.rl"; | |||
# SMTP address spec | |||
# Obtained from: https://tools.ietf.org/html/rfc5321#section-4.1.2 | |||
LF = "\n"; | |||
CR = "\r"; | |||
CRLF = "\r\n"; | |||
DQUOTE = '"'; | |||
atext = alpha | digit | "!" | "#" | "$" | "%" | "&" | | |||
"'" | "*" | "+" | "_" | "/" | "=" | "?" | "^" | | |||
"_" | "`" | "{" | "|" | "}" | "~"; | |||
dcontent = 33..90 | 94..126; | |||
Let_dig = alpha | digit; | |||
Ldh_str = ( alpha | digit | "_" )* Let_dig; | |||
quoted_pairSMTP = "\\" 32..126; | |||
qtextSMTP = 32..33 | 35..91 | 93..126; | |||
Atom = atext+; | |||
Dot_string = Atom ("." Atom)*; | |||
QcontentSMTP = qtextSMTP | quoted_pairSMTP; | |||
Quoted_string = ( DQUOTE QcontentSMTP* DQUOTE ) %Quoted_addr; | |||
Local_part = ( Dot_string | Quoted_string ) >User_start %User_end; | |||
String = Atom | Quoted_string; | |||
Standardized_tag = Ldh_str; | |||
General_address_literal = Standardized_tag ":" dcontent+; | |||
address_literal = "[" ( IPv4_address_literal | | |||
IPv6_address_literal | | |||
General_address_literal ) >Domain_addr_start %Domain_addr_end "]"; | |||
sub_domain = Let_dig Ldh_str?; | |||
Domain = sub_domain ("." sub_domain)*; | |||
Atdomain = "@" Domain; | |||
Adl = Atdomain ( "," Atdomain )*; | |||
Mailbox = Local_part "@" (address_literal | Domain >Domain_start %Domain_end); | |||
UnangledPath = ( Adl ":" )? Mailbox; | |||
AngledPath = "<" UnangledPath ">"; | |||
Path = AngledPath %Angled_addr | UnangledPath; | |||
SMTPAddr = space* (Path | "<>" %Empty_addr ) %Valid_addr space*; | |||
}%% |
@@ -0,0 +1,19 @@ | |||
%%{ | |||
machine smtp_ip; | |||
# Parses IPv4/IPv6 address | |||
# Source: https://tools.ietf.org/html/rfc5321#section-4.1.3 | |||
Snum = digit{1,3}; | |||
IPv4_address_literal = Snum ("." Snum){3}; | |||
IPv6_hex = xdigit{1,4}; | |||
IPv6_full = IPv6_hex (":" IPv6_hex){7}; | |||
IPv6_comp = (IPv6_hex (":" IPv6_hex){0,5})? "::" | |||
(IPv6_hex (":" IPv6_hex){0,5})?; | |||
IPv6v4_full = IPv6_hex (":" IPv6_hex){5} ":" IPv4_address_literal; | |||
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_address_literal = "IPv6:" IPv6_addr; | |||
}%% |