} | } | ||||
} | } | ||||
include smtp_whitespace "smtp_whitespace.rl"; | |||||
include smtp_base "smtp_base.rl"; | |||||
include content_disposition "content_disposition.rl"; | include content_disposition "content_disposition.rl"; | ||||
main := content_disposition; | main := content_disposition; |
} | } | ||||
} | } | ||||
include smtp_base "smtp_base.rl"; | |||||
include smtp_ip "smtp_ip.rl"; | include smtp_ip "smtp_ip.rl"; | ||||
include smtp_whitespace "smtp_whitespace.rl"; | |||||
include smtp_address "smtp_address.rl"; | include smtp_address "smtp_address.rl"; | ||||
main := SMTPAddr; | main := SMTPAddr; |
%%{ | %%{ | ||||
machine smtp_address; | machine smtp_address; | ||||
# SMTP address spec | |||||
# Source: https://tools.ietf.org/html/rfc5321#section-4.1.2 | |||||
# Dependencies: smtp_base + smtp_ip | |||||
# Required actions: | |||||
# - User_has_backslash | |||||
# - User_end | |||||
# - Quoted_addr | |||||
# - Domain_start | |||||
# - Domain_end | |||||
# - Addr_end | |||||
# - Addr_has_angle | |||||
# - Valid_addr | |||||
# - Empty_addr | |||||
# + from deps: | |||||
# - IP4_start | |||||
# - IP4_end | |||||
# - IP6_start | |||||
# - IP6_end | |||||
# - Domain_addr_start | |||||
# - Domain_addr_end | |||||
# SMTP address spec | # SMTP address spec | ||||
# Obtained from: https://tools.ietf.org/html/rfc5321#section-4.1.2 | # Obtained from: https://tools.ietf.org/html/rfc5321#section-4.1.2 | ||||
Local_part = Dot_string >User_start %User_end | Quoted_string; | Local_part = Dot_string >User_start %User_end | Quoted_string; | ||||
String = Atom | Quoted_string; | 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 "]"; | |||||
non_conformant_address_literal = IPv4_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); | Mailbox = Local_part "@" (address_literal | Domain >Domain_start %Domain_end); | ||||
UnangledPath = ( Adl ":" )? Mailbox >Addr_start %Addr_end "."?; | |||||
UnangledPath = ( Adl ":" )? Mailbox >Domain_start %Addr_end "."?; | |||||
AngledPath = "<" UnangledPath ">" %Addr_has_angle; | AngledPath = "<" UnangledPath ">" %Addr_has_angle; | ||||
Path = AngledPath | UnangledPath; | Path = AngledPath | UnangledPath; | ||||
SMTPAddr = space* (Path | "<>" %Empty_addr ) %Valid_addr space*; | SMTPAddr = space* (Path | "<>" %Empty_addr ) %Valid_addr space*; | ||||
}%% | }%% |
%%{ | %%{ | ||||
machine smtp_date_parser; | machine smtp_date_parser; | ||||
include smtp_whitespace "smtp_whitespace.rl"; | |||||
include smtp_base "smtp_base.rl"; | |||||
include smtp_date "smtp_date.rl"; | include smtp_date "smtp_date.rl"; | ||||
main := date_time; | main := date_time; |
# Parses IPv4/IPv6 address | # Parses IPv4/IPv6 address | ||||
# Source: https://tools.ietf.org/html/rfc5321#section-4.1.3 | # Source: https://tools.ietf.org/html/rfc5321#section-4.1.3 | ||||
# Dependencies: none | |||||
# Required actions: | |||||
# - IP4_start | |||||
# - IP4_end | |||||
# - IP6_start | |||||
# - IP6_end | |||||
# - Domain_addr_start | |||||
# - Domain_addr_end | |||||
Snum = digit{1,3}; | Snum = digit{1,3}; | ||||
IPv4_addr = (Snum ("." Snum){3}); | IPv4_addr = (Snum ("." Snum){3}); | ||||
IPv6_simple = IPv6_full | IPv6_comp; | IPv6_simple = IPv6_full | IPv6_comp; | ||||
IPv6_addr = IPv6_simple | IPv6v4_full | IPv6v4_comp; | IPv6_addr = IPv6_simple | IPv6v4_full | IPv6v4_comp; | ||||
IPv6_address_literal = "IPv6:" %IP6_start IPv6_addr %IP6_end; | IPv6_address_literal = "IPv6:" %IP6_start IPv6_addr %IP6_end; | ||||
General_address_literal = Standardized_tag ":" dcontent+; | |||||
address_literal = "[" ( IPv4_address_literal | | |||||
IPv6_address_literal | | |||||
General_address_literal ) >Domain_addr_start %Domain_addr_end "]"; | |||||
non_conformant_address_literal = IPv4_address_literal >Domain_addr_start %Domain_addr_end; | |||||
}%% | }%% |
ccontent = ctext | FWS | '(' @{ fcall balanced_ccontent; }; | ccontent = ctext | FWS | '(' @{ fcall balanced_ccontent; }; | ||||
balanced_ccontent := ccontent* ')' @{ fret; }; | balanced_ccontent := ccontent* ')' @{ fret; }; | ||||
comment = "(" ((FWS? ccontent)* FWS?) >Comment_Start %Comment_End ")"; | |||||
CFWS = ((FWS? comment)+ FWS?) | FWS; | |||||
comment = "(" ((WSP* ccontent)* WSP*) >Comment_Start %Comment_End ")"; | |||||
CFWS = WSP* (comment+ WSP*)*; | |||||
From_domain = "FROM"i FWS Extended_Domain >From_Start %From_End; | From_domain = "FROM"i FWS Extended_Domain >From_Start %From_End; | ||||
By_domain = "BY"i FWS Extended_Domain >By_Start %By_End; | By_domain = "BY"i FWS Extended_Domain >By_Start %By_End; | ||||
Retarded_Domain = TCP_info; | |||||
From_domain_retarded = "FROM"i FWS Retarded_Domain >From_Start %From_End; | |||||
Via = CFWS "VIA"i FWS Link; | Via = CFWS "VIA"i FWS Link; | ||||
With = CFWS "WITH"i FWS Protocol; | With = CFWS "WITH"i FWS Protocol; | ||||
Opt_info = Via? With? ID? For? Additional_Registered_Clauses?; | Opt_info = Via? With? ID? For? Additional_Registered_Clauses?; | ||||
# Here we make From part optional just because many received headers lack it | # Here we make From part optional just because many received headers lack it | ||||
Received = From_domain? CFWS? By_domain? CFWS? Opt_info CFWS? ";" FWS date_time >Date_Start %Date_End CFWS?; | Received = From_domain? CFWS? By_domain? CFWS? Opt_info CFWS? ";" FWS date_time >Date_Start %Date_End CFWS?; | ||||
Received_retarded = From_domain_retarded CFWS? By_domain? CFWS? Opt_info CFWS? ";" FWS date_time >Date_Start %Date_End CFWS?; | |||||
prepush { | prepush { | ||||
if (top >= st_storage.size) { | if (top >= st_storage.size) { |
cstart = NULL; | cstart = NULL; | ||||
} | } | ||||
include smtp_whitespace "smtp_whitespace.rl"; | |||||
include smtp_base "smtp_base.rl"; | |||||
include smtp_ip "smtp_ip.rl"; | include smtp_ip "smtp_ip.rl"; | ||||
include smtp_date "smtp_date.rl"; | include smtp_date "smtp_date.rl"; | ||||
include smtp_address"smtp_address.rl"; | include smtp_address"smtp_address.rl"; | ||||
include smtp_received "smtp_received.rl"; | include smtp_received "smtp_received.rl"; | ||||
main := Received; | main := Received; | ||||
retarded := Received_retarded; | |||||
}%% | }%% | ||||
gsize size; | gsize size; | ||||
} st_storage; | } st_storage; | ||||
guint tmplen; | guint tmplen; | ||||
gboolean retarded_checked = FALSE; | |||||
memset (&st_storage, 0, sizeof (st_storage)); | memset (&st_storage, 0, sizeof (st_storage)); | ||||
memset (rh, 0, sizeof (*rh)); | memset (rh, 0, sizeof (*rh)); | ||||
eof = pe; | eof = pe; | ||||
%% write init; | %% write init; | ||||
reexec_retarded: | |||||
%% write exec; | %% write exec; | ||||
%% write exports; | |||||
if (!real_ip_end && !retarded_checked) { | |||||
cs = smtp_received_parser_en_retarded; | |||||
retarded_checked = TRUE; | |||||
goto reexec_retarded; | |||||
} | |||||
if (real_ip_end && real_ip_start && real_ip_end > real_ip_start) { | if (real_ip_end && real_ip_start && real_ip_end > real_ip_start) { | ||||
tmplen = real_ip_end - real_ip_start; | tmplen = real_ip_end - real_ip_start; |
%%{ | |||||
machine smtp_whitespace; | |||||
WSP = " "; | |||||
CRLF = "\r\n" | ("\r" [^\n]) | ([^\r] "\n"); | |||||
DQUOTE = '"'; | |||||
# Printable US-ASCII characters not including specials | |||||
atext = alpha | digit | "!" | "#" | "$" | "%" | "&" | | |||||
"'" | "*" | "+" | "_" | "/" | "=" | "?" | "^" | | |||||
"-" | "`" | "{" | "|" | "}" | "~"; | |||||
# Printable US-ASCII characters not including "[", "]", or "\" | |||||
dtext = 33..90 | 94..126; | |||||
# Printable US-ASCII characters not including "(", ")", or "\" | |||||
ctext = 33..39 | 42..91 | 93..126; | |||||
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)*; | |||||
dot_atom_text = atext+ ("." atext+)*; | |||||
#FWS = ((WSP* CRLF)? WSP+); | |||||
FWS = WSP+; # We work with unfolded headers, so we can simplify machine | |||||
}%% |