summaryrefslogtreecommitdiffstats
path: root/src/ragel
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-23 11:33:18 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-23 14:45:27 +0100
commit6832271dbc2771c7e3b2512fef2dcc054ab55c49 (patch)
tree5e7c944fabf2bcb92f8be6aa5e70d8940ba05167 /src/ragel
parentd4c86a2cd8a4f326870079d1bcf1cc2b005deec4 (diff)
downloadrspamd-6832271dbc2771c7e3b2512fef2dcc054ab55c49.tar.gz
rspamd-6832271dbc2771c7e3b2512fef2dcc054ab55c49.zip
[Feature] Add parsers for SMTP address in ragel
Diffstat (limited to 'src/ragel')
-rw-r--r--src/ragel/smtp_addr_parser.rl77
-rw-r--r--src/ragel/smtp_address.rl50
-rw-r--r--src/ragel/smtp_ip.rl19
3 files changed, 146 insertions, 0 deletions
diff --git a/src/ragel/smtp_addr_parser.rl b/src/ragel/smtp_addr_parser.rl
new file mode 100644
index 000000000..5d08d7d4f
--- /dev/null
+++ b/src/ragel/smtp_addr_parser.rl
@@ -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;
+}
diff --git a/src/ragel/smtp_address.rl b/src/ragel/smtp_address.rl
new file mode 100644
index 000000000..c0333acd9
--- /dev/null
+++ b/src/ragel/smtp_address.rl
@@ -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*;
+
+}%%
diff --git a/src/ragel/smtp_ip.rl b/src/ragel/smtp_ip.rl
new file mode 100644
index 000000000..b6b0080f3
--- /dev/null
+++ b/src/ragel/smtp_ip.rl
@@ -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;
+}%% \ No newline at end of file