diff --git a/fail2ban/server/datetemplate.py b/fail2ban/server/datetemplate.py index 8210dad4..0a5ec55a 100644 --- a/fail2ban/server/datetemplate.py +++ b/fail2ban/server/datetemplate.py @@ -64,7 +64,7 @@ class DateTemplate(object): def getRegex(self): return self._regex - def setRegex(self, regex, wordBegin=True): + def setRegex(self, regex, wordBegin=True, wordEnd=True): """Sets regex to use for searching for date in log line. Parameters @@ -82,8 +82,10 @@ class DateTemplate(object): If regular expression fails to compile """ regex = regex.strip() - if (wordBegin and not re.search(r'^\^', regex)): - regex = r'\b' + regex + if wordBegin and not re.search(r'^\^', regex): + regex = r'(?=^|\b|\W)' + regex + if wordEnd and not re.search(r'\$$', regex): + regex += r'(?=\b|\W|$)' self._regex = regex self._cRegex = re.compile(regex, re.UNICODE | re.IGNORECASE) diff --git a/fail2ban/tests/fail2banregextestcase.py b/fail2ban/tests/fail2banregextestcase.py index 1119efdb..fb1bc6e3 100644 --- a/fail2ban/tests/fail2banregextestcase.py +++ b/fail2ban/tests/fail2banregextestcase.py @@ -187,4 +187,32 @@ class Fail2banRegexTest(LogCaptureTestCase): self.assertLogged('https://') - + def testAmbiguousDatePattern(self): + for (matched, args) in ( + # positive case: + (1, ('Test failure Jan 23 21:59:59 for 192.0.2.1', r'for $')), + # ambiguous "unbound" patterns (missed): + (0, ('Test failure TestJan 23 21:59:59.011 2015 for 192.0.2.1', r'for $')), + (0, ('Test failure Jan 23 21:59:59123456789 for 192.0.2.1', r'for $')), + # ambiguous "no optional year" patterns (matched): + (1, ('Aug 8 11:25:50 14430f2329b8 Authentication failed from 192.0.2.1', r'from $')), + (1, ('[Aug 8 11:25:50] 14430f2329b8 Authentication failed from 192.0.2.1', r'from $')), + # direct specified patterns: + (1, ('-d', r'%H:%M:%S %d.%m.%Y$', '192.0.2.1 at 20:00:00 01.02.2003', '^')), + (1, ('-d', r'\[%H:%M:%S %d.%m.%Y\]', '192.0.2.1[20:00:00 01.02.2003]', '^$')), + (1, ('-d', r'\[%H:%M:%S %d.%m.%Y\]$', '192.0.2.1[20:00:00 01.02.2003]', '^$')), + (1, ('-d', r'^\[%H:%M:%S %d.%m.%Y\]', '[20:00:00 01.02.2003]192.0.2.1', '^$')), + (1, ('-d', r'^\[%d/%b/%Y %H:%M:%S\]', '[17/Jun/2011 17:00:45] Attempt, IP address 192.0.2.1', r'^ Attempt, IP address $')), + ): + logSys.debug('== test: %r', args) + (opts, args, fail2banRegex) = _Fail2banRegex(*args) + self.assertTrue(fail2banRegex.start(opts, args)) + matchedLog = 'Lines: 1 lines, 0 ignored, 1 matched, 0 missed' + missedLog = 'Lines: 1 lines, 0 ignored, 0 matched, 1 missed' + if matched: + self.assertLogged(matchedLog) + self.assertNotLogged(missedLog) + else: + self.assertNotLogged(matchedLog) + self.assertLogged(missedLog) + self.pruneLog()