From ee3c9fcb75091b1d28cfcaf2535232ffe3dc465a Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 28 Mar 2017 22:07:40 +0200 Subject: [PATCH] "%y" - in the fail2ban parsed year without century should be always relative current century (>= 2000); cover several format specifiers and different "assume" cases (without year, without date, greater as now, etc.); --- fail2ban/server/strptime.py | 27 +++++------------ fail2ban/tests/datedetectortestcase.py | 41 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/fail2ban/server/strptime.py b/fail2ban/server/strptime.py index d98b2e1b..55bdcc8c 100644 --- a/fail2ban/server/strptime.py +++ b/fail2ban/server/strptime.py @@ -108,13 +108,9 @@ def reGroupDictStrptime(found_dict, msec=False): # worthless without day of the week if key == 'y': year = int(val) - # Open Group specification for strptime() states that a %y - #value in the range of [00, 68] is in the century 2000, while - #[69,99] is in the century 1900 - if year <= 68: + # Fail2ban year should be always in the current century (>= 2000) + if year <= 2000: year += 2000 - else: - year += 1900 elif key == 'Y': year = int(val) elif key == 'm': @@ -148,7 +144,7 @@ def reGroupDictStrptime(found_dict, msec=False): elif key == 'S': second = int(val) elif key == 'f': - if msec: + if msec: # pragma: no cover - currently unused s = val # Pad to always return microseconds. s += "0" * (6 - len(s)) @@ -158,21 +154,14 @@ def reGroupDictStrptime(found_dict, msec=False): elif key == 'a': weekday = locale_time.a_weekday.index(val.lower()) elif key == 'w': - weekday = int(val) - if weekday == 0: - weekday = 6 - else: - weekday -= 1 + weekday = int(val) - 1 + if weekday < 0: weekday = 6 elif key == 'j': julian = int(val) elif key in ('U', 'W'): week_of_year = int(val) - if key == 'U': - # U starts week on Sunday. - week_of_year_start = 6 - else: - # W starts week on Monday. - week_of_year_start = 0 + # U starts week on Sunday, W - on Monday + week_of_year_start = 6 if key == 'U' else 0 elif key == 'z': z = val if z in ("Z", "UTC", "GMT"): @@ -242,6 +231,6 @@ def reGroupDictStrptime(found_dict, msec=False): tm = calendar.timegm(date_result.utctimetuple()) else: tm = time.mktime(date_result.timetuple()) - if msec: + if msec: # pragma: no cover - currently unused tm += fraction/1000000.0 return tm diff --git a/fail2ban/tests/datedetectortestcase.py b/fail2ban/tests/datedetectortestcase.py index 5b32a7e9..39ab7173 100644 --- a/fail2ban/tests/datedetectortestcase.py +++ b/fail2ban/tests/datedetectortestcase.py @@ -298,6 +298,16 @@ iso8601 = DatePatternRegex("%Y-%m-%d[T ]%H:%M:%S(?:\.%f)?%z") class CustomDateFormatsTest(unittest.TestCase): + def setUp(self): + """Call before every test case.""" + unittest.TestCase.setUp(self) + setUpMyTime() + + def tearDown(self): + """Call after every test case.""" + unittest.TestCase.tearDown(self) + tearDownMyTime() + def testIso8601(self): date = datetime.datetime.utcfromtimestamp( iso8601.getDate("2007-01-25T12:00:00Z")[0]) @@ -411,6 +421,37 @@ class CustomDateFormatsTest(unittest.TestCase): else: self.assertEqual(date, None) + def testVariousFormatSpecs(self): + for (matched, dp, line) in ( + # cover %B (full-month-name) and %I (as 12 == 0): + (1106438399.0, "^%B %Exd %I:%ExM:%ExS**", 'January 23 12:59:59'), + # cover %U (week of year starts on sunday) and %A (weekday): + (985208399.0, "^%y %U %A %ExH:%ExM:%ExS**", '01 11 Wednesday 21:59:59'), + # cover %W (week of year starts on monday) and %A (weekday): + (984603599.0, "^%y %W %A %ExH:%ExM:%ExS**", '01 11 Wednesday 21:59:59'), + # cover %W (week of year starts on monday) and %w (weekday, 0 - sunday): + (984949199.0, "^%y %W %w %ExH:%ExM:%ExS**", '01 11 0 21:59:59'), + # cover %W (week of year starts on monday) and %w (weekday, 6 - saturday): + (984862799.0, "^%y %W %w %ExH:%ExM:%ExS**", '01 11 6 21:59:59'), + # cover time only, current date, in test cases now == 14 Aug 2005 12:00 -> back to yesterday (13 Aug): + (1123963199.0, "^%ExH:%ExM:%ExS**", '21:59:59'), + # cover time only, current date, in test cases now == 14 Aug 2005 12:00 -> today (14 Aug): + (1123970401.0, "^%ExH:%ExM:%ExS**", '00:00:01'), + # cover date with current year, in test cases now == Aug 2005 -> back to last year (Sep 2004): + (1094068799.0, "^%m/%d %ExH:%ExM:%ExS**", '09/01 21:59:59'), + ): + logSys.debug('== test: %r', (matched, dp, line)) + dd = DateDetector() + dd.appendTemplate(dp) + date = dd.getTime(line) + if matched: + self.assertTrue(date) + if isinstance(matched, basestring): # pragma: no cover + self.assertEqual(matched, date[1].group(1)) + else: + self.assertEqual(matched, date[0]) + else: # pragma: no cover + self.assertEqual(date, None) # def testDefaultTempate(self): # self.__datedetector.setDefaultRegex("^\S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}")