From c9cdf449078ce760c0528600370b35e3f26c2f08 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 21 Dec 2016 13:26:23 +0000 Subject: [Feature] Add parser for SMTP date --- src/ragel/smtp_date.rl | 183 ++++++++++++++++++++++++++++++++++++-- src/ragel/smtp_received_parser.rl | 5 +- 2 files changed, 179 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ragel/smtp_date.rl b/src/ragel/smtp_date.rl index eb5d0cdc5..23ab3caba 100644 --- a/src/ragel/smtp_date.rl +++ b/src/ragel/smtp_date.rl @@ -6,22 +6,189 @@ # SMTP date spec # Obtained from: http://tools.ietf.org/html/rfc5322#section_3.3 + + action Day_Start { + tmp = p; + } + action Day_End { + if (p > tmp) { + gulong n; + if (rspamd_strtoul (tmp, p - tmp, &n)) { + if (n > 0 && n <= 31) { + tm.tm_mday = n; + } + } + } + } + action Month_End { + + } + action Year_Start { + tmp = p; + } + action Year_End { + if (p > tmp) { + gulong n; + if (rspamd_strtoul (tmp, p - tmp, &n)) { + if (n < 1000) { + tm.tm_year = n + 1900; + } + else { + tm.tm_year = n; + } + } + } + } + action Hour_Start { + tmp = p; + } + action Hour_End { + if (p > tmp) { + gulong n; + if (rspamd_strtoul (tmp, p - tmp, &n)) { + if (n < 24) { + tm.tm_hour = n; + } + } + } + } + action Minute_Start { + tmp = p; + } + action Minute_End { + if (p > tmp) { + gulong n; + if (rspamd_strtoul (tmp, p - tmp, &n)) { + if (n < 60) { + tm.tm_min = n; + } + } + } + } + action Second_Start { + tmp = p; + } + action Second_End { + if (p > tmp) { + gulong n; + if (rspamd_strtoul (tmp, p - tmp, &n)) { + if (n <= 60) { /* Leap second */ + tm.tm_sec = n; + } + } + } + } + action TZ_Sign { + tmp = p - 1; + } + action TZ_Offset_Start { + + } + action TZ_Offset_End { + if (p > tmp + 1) { + rspamd_strtoul (tmp + 1, p - tmp - 1, (gulong *)&tz); + + if (*tmp == '-') { + tz = -(tz); + } + } + } + action Obs_Zone_End { + } + action DT_End { + } + + # Specific actions + # Months + action Month_Jan { + tm.tm_mon = 0; + } + action Month_Feb { + tm.tm_mon = 1; + } + action Month_Mar { + tm.tm_mon = 2; + } + action Month_Apr { + tm.tm_mon = 3; + } + action Month_May { + tm.tm_mon = 4; + } + action Month_Jun { + tm.tm_mon = 5; + } + action Month_Jul { + tm.tm_mon = 6; + } + action Month_Aug { + tm.tm_mon = 7; + } + action Month_Sep { + tm.tm_mon = 8; + } + action Month_Oct { + tm.tm_mon = 9; + } + action Month_Nov { + tm.tm_mon = 10; + } + action Month_Dec { + tm.tm_mon = 11; + } + # Obsoleted timezones + action TZ_UT { + tz = 0; + } + action TZ_GMT { + tz = 0; + } + action TZ_EST { + tz = -500; + } + action TZ_EDT { + tz = -400; + } + action TZ_CST { + tz = -600; + } + action TZ_CDT { + tz = -500; + } + action TZ_MST { + tz = -700; + } + action TZ_MDT { + tz = -600; + } + action TZ_PST { + tz = -800; + } + action TZ_PDT { + tz = -700; + } digit_2 = digit{2}; digit_4 = digit{4}; day_name = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun"; day_of_week = FWS? day_name; day = FWS? digit{1,2} FWS; - month = "Jan" | "Feb" | "Mar" | "Apr" | - "May" | "Jun" | "Jul" | "Aug" | - "Sep" | "Oct" | "Nov" | "Dec"; - year = FWS digit{4,} FWS; - date = day month year; + month = "Jan" %Month_Jan | "Feb" %Month_Feb | "Mar" %Month_Mar | "Apr" %Month_Apr | + "May" %Month_May | "Jun" %Month_Jun | "Jul" %Month_Jul | "Aug" %Month_Aug | + "Sep" %Month_Sep | "Oct" %Month_Oct | "Nov" %Month_Nov | "Dec" %Month_Dec; + year = FWS digit{2,} FWS; + date = day >Day_Start %Day_End month %Month_End year >Year_Start %Year_End; hour = digit_2; minute = digit_2; second = digit_2; - time_of_day = hour ":" minute (":" second )?; - zone = FWS ("+" | "-") digit_4; - time = time_of_day zone; + time_of_day = hour >Hour_Start %Hour_End ":" minute >Minute_Start %Minute_End (":" second >Second_Start %Second_End )?; + zone = FWS ("+" | "-") %TZ_Sign digit_4 >TZ_Offset_Start %TZ_Offset_End; + obs_zone = "UT" %TZ_UT | "GMT" %TZ_GMT | + "EST" %TZ_EST | "EDT" %TZ_EDT | + "CST" %TZ_CST | "CDT" %TZ_CDT | + "MST" %TZ_MST | "MDT" %TZ_MDT | + "PST" %TZ_PST | "PDT" %TZ_PDT | + [a-iA-I] | [k-zK-Z]; + time = time_of_day %DT_End (zone | obs_zone %Obs_Zone_End); date_time = (day_of_week ",")? date time; }%% \ No newline at end of file diff --git a/src/ragel/smtp_received_parser.rl b/src/ragel/smtp_received_parser.rl index c599e0495..cc4d37e0c 100644 --- a/src/ragel/smtp_received_parser.rl +++ b/src/ragel/smtp_received_parser.rl @@ -284,10 +284,12 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l *reported_domain_start, *reported_domain_end, *reported_ip_start, *reported_ip_end, *ip_start, *ip_end, *date_start, - *for_start, *for_end; + *for_start, *for_end, *tmp; + struct tm tm; const char *p = data, *pe = data + len, *eof; int cs, in_v6 = 0, *stack = NULL; gsize top = 0; + glong tz = 0; struct _ragel_st_storage { int *data; gsize size; @@ -295,6 +297,7 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l memset (&st_storage, 0, sizeof (st_storage)); memset (rh, 0, sizeof (*rh)); + memset (&tm, 0, sizeof (tm)); real_domain_start = NULL; real_domain_end = NULL; real_ip_start = NULL; -- cgit v1.2.3