Merge pull request #1512 from 'remotes/gh-upstream/0.9' into 0.10

pull/1516/head
sebres 2016-08-15 20:08:42 +02:00
commit 5509ba37a2
3 changed files with 60 additions and 5 deletions

View File

@ -80,6 +80,7 @@ releases.
uses "fail2ban-python" now); uses "fail2ban-python" now);
* Fixed test case "testSetupInstallRoot" for not default python version (also * Fixed test case "testSetupInstallRoot" for not default python version (also
using direct call, out of virtualenv); using direct call, out of virtualenv);
* Fixed ambiguous wrong recognized date pattern resp. its optional parts (see gh-1512);
* `filter.d/ignorecommands/apache-fakegooglebot` * `filter.d/ignorecommands/apache-fakegooglebot`
- Fixed error within apache-fakegooglebot, that will be called - Fixed error within apache-fakegooglebot, that will be called
with wrong python version (gh-1506) with wrong python version (gh-1506)
@ -91,6 +92,8 @@ releases.
### New Features ### New Features
### Enhancements ### Enhancements
* DateTemplate regexp extended with the word-end boundary, additionally to
word-start boundary
* Introduces new command "fail2ban-python", as automatically created symlink to * Introduces new command "fail2ban-python", as automatically created symlink to
python executable, where fail2ban currently installed (resp. its modules are located): python executable, where fail2ban currently installed (resp. its modules are located):
- allows to use the same version, fail2ban currently running, e.g. in - allows to use the same version, fail2ban currently running, e.g. in

View File

@ -65,7 +65,7 @@ class DateTemplate(object):
def getRegex(self): def getRegex(self):
return self._regex 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. """Sets regex to use for searching for date in log line.
Parameters Parameters
@ -73,8 +73,12 @@ class DateTemplate(object):
regex : str regex : str
The regex the template will use for searching for a date. The regex the template will use for searching for a date.
wordBegin : bool wordBegin : bool
Defines whether the regex should be modified to search at Defines whether the regex should be modified to search at beginning of a
beginning of a word, by adding "\\b" to start of regex. word, by adding special boundary r'(?=^|\b|\W)' to start of regex.
Default True.
wordEnd : bool
Defines whether the regex should be modified to search at end of a word,
by adding special boundary r'(?=\b|\W|$)' to end of regex.
Default True. Default True.
Raises Raises
@ -83,8 +87,10 @@ class DateTemplate(object):
If regular expression fails to compile If regular expression fails to compile
""" """
regex = regex.strip() regex = regex.strip()
if (wordBegin and not re.search(r'^\^', regex)): if wordBegin and not re.search(r'^\^', regex):
regex = r'\b' + regex regex = r'(?=^|\b|\W)' + regex
if wordEnd and not re.search(r'\$$', regex):
regex += r'(?=\b|\W|$)'
self._regex = regex self._regex = regex
regex = property(getRegex, setRegex, doc= regex = property(getRegex, setRegex, doc=

View File

@ -37,6 +37,7 @@ from utils import LogCaptureTestCase, logSys as DefLogSys
from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack, getLogger from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack, getLogger
from ..helpers import splitwords from ..helpers import splitwords
from ..server.datedetector import DateDetector
from ..server.datetemplate import DatePatternRegex from ..server.datetemplate import DatePatternRegex
from ..server.mytime import MyTime from ..server.mytime import MyTime
@ -343,6 +344,51 @@ class CustomDateFormatsTest(unittest.TestCase):
date, date,
datetime.datetime(2007, 1, 25, 16, 0)) datetime.datetime(2007, 1, 25, 16, 0))
def testAmbiguousDatePattern(self):
defDD = DateDetector()
defDD.addDefaultTemplate()
logSys = DefLogSys
for (matched, dp, line) in (
# positive case:
('Jan 23 21:59:59', None, 'Test failure Jan 23 21:59:59 for 192.0.2.1'),
# ambiguous "unbound" patterns (missed):
(False, None, 'Test failure TestJan 23 21:59:59.011 2015 for 192.0.2.1'),
(False, None, 'Test failure Jan 23 21:59:59123456789 for 192.0.2.1'),
# ambiguous "no optional year" patterns (matched):
('Aug 8 11:25:50', None, 'Aug 8 11:25:50 14430f2329b8 Authentication failed from 192.0.2.1'),
('Aug 8 11:25:50', None, '[Aug 8 11:25:50] 14430f2329b8 Authentication failed from 192.0.2.1'),
('Aug 8 11:25:50 2014', None, 'Aug 8 11:25:50 2014 14430f2329b8 Authentication failed from 192.0.2.1'),
# direct specified patterns:
('20:00:00 01.02.2003', r'%H:%M:%S %d.%m.%Y$', '192.0.2.1 at 20:00:00 01.02.2003'),
('[20:00:00 01.02.2003]', r'\[%H:%M:%S %d.%m.%Y\]', '192.0.2.1[20:00:00 01.02.2003]'),
('[20:00:00 01.02.2003]', r'\[%H:%M:%S %d.%m.%Y\]', '[20:00:00 01.02.2003]192.0.2.1'),
('[20:00:00 01.02.2003]', r'\[%H:%M:%S %d.%m.%Y\]$', '192.0.2.1[20:00:00 01.02.2003]'),
('[20:00:00 01.02.2003]', r'^\[%H:%M:%S %d.%m.%Y\]', '[20:00:00 01.02.2003]192.0.2.1'),
('[17/Jun/2011 17:00:45]', r'^\[%d/%b/%Y %H:%M:%S\]', '[17/Jun/2011 17:00:45] Attempt, IP address 192.0.2.1'),
('[17/Jun/2011 17:00:45]', r'\[%d/%b/%Y %H:%M:%S\]', 'Attempt [17/Jun/2011 17:00:45] IP address 192.0.2.1'),
('[17/Jun/2011 17:00:45]', r'\[%d/%b/%Y %H:%M:%S\]', 'Attempt IP address 192.0.2.1, date: [17/Jun/2011 17:00:45]'),
# direct specified patterns (begin/end, missed):
(False, r'%H:%M:%S %d.%m.%Y', '192.0.2.1x20:00:00 01.02.2003'),
(False, r'%H:%M:%S %d.%m.%Y', '20:00:00 01.02.2003x192.0.2.1'),
# direct specified patterns (begin/end, matched):
('20:00:00 01.02.2003', r'%H:%M:%S %d.%m.%Y', '192.0.2.1 20:00:00 01.02.2003'),
('20:00:00 01.02.2003', r'%H:%M:%S %d.%m.%Y', '20:00:00 01.02.2003 192.0.2.1'),
):
logSys.debug('== test: %r', (matched, dp, line))
if dp is None:
dd = defDD
else:
dp = DatePatternRegex(dp)
dd = DateDetector()
dd.appendTemplate(dp)
date = dd.getTime(line)
if matched:
self.assertTrue(date)
self.assertEqual(matched, date[1].group())
else:
self.assertEqual(date, None)
class MyTimeTest(unittest.TestCase): class MyTimeTest(unittest.TestCase):
def testStr2Seconds(self): def testStr2Seconds(self):