From 189e70d99cc38f09183c26b86cfd880039763314 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 18 Nov 2016 14:42:29 +0100 Subject: [PATCH] processLine etc. rewritten: - normalize calling parameters (persistent parameters moved from function arguments to filter member variables) - save last line as lambda instead of return it as string (lazy convert of process line tuple to string on demand, needed in fail2ban-regex only) --- fail2ban/client/fail2banregex.py | 6 +++++- fail2ban/server/filter.py | 28 +++++++++++++++++----------- fail2ban/tests/samplestestcase.py | 6 ++++-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/fail2ban/client/fail2banregex.py b/fail2ban/client/fail2banregex.py index 4096ac4e..a5aad76f 100644 --- a/fail2ban/client/fail2banregex.py +++ b/fail2ban/client/fail2banregex.py @@ -247,6 +247,9 @@ class Fail2banRegex(object): self.raw = True if opts.raw else False if opts.usedns: self._filter.setUseDns(opts.usedns) + self._filter.returnRawHost = self.raw + self._filter.checkFindTime = False + self._filter.checkAllRegex = True def decode_line(self, line): return FileContainer.decode_line('', self.encoding, line) @@ -350,7 +353,8 @@ class Fail2banRegex(object): orgLineBuffer = self._filter._Filter__lineBuffer fullBuffer = len(orgLineBuffer) >= self._filter.getMaxLines() try: - line, ret = self._filter.processLine(line, date, checkAllRegex=True, returnRawHost=self.raw) + ret = self._filter.processLine(line, date) + line = self._filter.processedLine() for match in ret: # Append True/False flag depending if line was matched by # more than one regex diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index 9b1aefd6..2487b8f5 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -90,6 +90,12 @@ class Filter(JailThread): ## Error counter (protected, so can be used in filter implementations) ## if it reached 100 (at once), run-cycle will go idle self._errors = 0 + ## return raw host (host is not dns): + self.returnRawHost = False + ## check each regex (used for test purposes): + self.checkAllRegex = False + ## if true ignores obsolete failures (failure time < now - findTime): + self.checkFindTime = True ## Ticks counter self.ticks = 0 @@ -455,8 +461,7 @@ class Filter(JailThread): return False - def processLine(self, line, date=None, returnRawHost=False, - checkAllRegex=False, checkFindTime=False): + def processLine(self, line, date=None): """Split the time portion from log msg and return findFailures on them """ if date: @@ -476,14 +481,15 @@ class Filter(JailThread): else: tupleLine = (l, "", "", None) - return "".join(tupleLine[::2]), self.findFailure( - tupleLine, date, returnRawHost, checkAllRegex, checkFindTime) + # save last line (lazy convert of process line tuple to string on demand): + self.processedLine = lambda: "".join(tupleLine[::2]) + return self.findFailure(tupleLine, date) def processLineAndAdd(self, line, date=None): """Processes the line for failures and populates failManager """ try: - for element in self.processLine(line, date, checkFindTime=True)[1]: + for element in self.processLine(line, date): ip = element[1] unixTime = element[2] lines = element[3] @@ -539,10 +545,10 @@ class Filter(JailThread): # to find the logging time. # @return a dict with IP and timestamp. - def findFailure(self, tupleLine, date=None, returnRawHost=False, - checkAllRegex=False, checkFindTime=False): + def findFailure(self, tupleLine, date=None): failList = list() + returnRawHost = self.returnRawHost cidr = IPAddr.CIDR_UNSPEC if self.__useDns == "raw": returnRawHost = True @@ -577,7 +583,7 @@ class Filter(JailThread): timeText = self.__lastTimeText or "".join(tupleLine[::2]) date = self.__lastDate - if checkFindTime and date is not None and date < MyTime.time() - self.getFindTime(): + if self.checkFindTime and date is not None and date < MyTime.time() - self.getFindTime(): logSys.log(5, "Ignore line since time %s < %s - %s", date, MyTime.time(), self.getFindTime()) return failList @@ -598,7 +604,7 @@ class Filter(JailThread): # The ignoreregex matched. Remove ignored match. self.__lineBuffer = failRegex.getUnmatchedTupleLines() logSys.log(7, "Matched ignoreregex and was ignored") - if not checkAllRegex: + if not self.checkAllRegex: break else: continue @@ -641,7 +647,7 @@ class Filter(JailThread): ip = IPAddr(fid, IPAddr.CIDR_RAW) failList.append([failRegexIndex, ip, date, failRegex.getMatchedLines(), fail]) - if not checkAllRegex: + if not self.checkAllRegex: break else: ips = DNSUtils.textToIp(host, self.__useDns) @@ -649,7 +655,7 @@ class Filter(JailThread): for ip in ips: failList.append([failRegexIndex, ip, date, failRegex.getMatchedLines(), fail]) - if not checkAllRegex: + if not self.checkAllRegex: break except RegexException as e: # pragma: no cover - unsure if reachable logSys.error(e) diff --git a/fail2ban/tests/samplestestcase.py b/fail2ban/tests/samplestestcase.py index 31b1812e..55dffdb0 100644 --- a/fail2ban/tests/samplestestcase.py +++ b/fail2ban/tests/samplestestcase.py @@ -44,6 +44,9 @@ class FilterSamplesRegex(unittest.TestCase): def setUp(self): """Call before every test case.""" self.filter = Filter(None) + self.filter.returnRawHost = True + self.filter.checkAllRegex = True + self.filter.checkFindTime = False self.filter.active = True setUpMyTime() @@ -111,8 +114,7 @@ def testSampleRegexsFactory(name, basedir): else: faildata = {} - ret = self.filter.processLine( - line, returnRawHost=True, checkAllRegex=True)[1] + ret = self.filter.processLine(line) if not ret: # Check line is flagged as none match self.assertFalse(faildata.get('match', True),