fix restoring of tickets from database if `maxmatches` of jail smaller as `dbmaxmatches` (so read fewer matches in memory):

pull/2402/head
sebres 2019-04-18 21:17:38 +02:00
parent 25f1aa334e
commit 852cb0362c
3 changed files with 21 additions and 3 deletions

View File

@ -712,7 +712,7 @@ class Fail2BanDb(object):
cur = self._db.cursor()
return cur.execute(query, queryArgs)
def getCurrentBans(self, jail = None, ip = None, forbantime=None, fromtime=None):
def getCurrentBans(self, jail = None, ip = None, forbantime=None, fromtime=None, maxmatches=None):
tickets = []
ticket = None
@ -724,6 +724,15 @@ class Fail2BanDb(object):
for banip, timeofban, data in results:
# logSys.debug('restore ticket %r, %r, %r', banip, timeofban, data)
ticket = FailTicket(banip, timeofban, data=data)
# filter matches if expected (current count > as maxmatches specified):
if maxmatches is None:
maxmatches = self.maxMatches
if maxmatches:
matches = ticket.getMatches()
if matches and len(matches) > maxmatches:
ticket.setMatches(matches[-maxmatches:])
else:
ticket.setMatches(None)
# logSys.debug('restored ticket: %r', ticket)
if ip is not None: return ticket
tickets.append(ticket)

View File

@ -213,7 +213,8 @@ class Jail(object):
try:
if self.database is not None:
forbantime = self.actions.getBanTime()
for ticket in self.database.getCurrentBans(jail=self, forbantime=forbantime):
for ticket in self.database.getCurrentBans(jail=self,
forbantime=forbantime, maxmatches=self.filter.failManager.maxMatches):
#logSys.debug('restored ticket: %s', ticket)
if not self.filter.inIgnoreIPList(ticket.getIP(), log_ignore=True):
# mark ticked was restored from database - does not put it again into db:

View File

@ -371,7 +371,15 @@ class DatabaseTest(LogCaptureTestCase):
self.assertEqual(ticket.getAttempt(), len(failures))
self.assertEqual(len(ticket.getMatches()), maxMatches)
self.assertEqual(ticket.getMatches(), matches2find[-maxMatches:])
# should retrieve 0 matches by last ban:
# maxmatches of jail < dbmaxmatches (so read 1 match and 0 matches):
ticket = self.db.getCurrentBans(self.jail, "127.0.0.1", fromtime=MyTime.time()-100,
maxmatches=1)
self.assertEqual(len(ticket.getMatches()), 1)
self.assertEqual(ticket.getMatches(), failures[3]['matches'])
ticket = self.db.getCurrentBans(self.jail, "127.0.0.1", fromtime=MyTime.time()-100,
maxmatches=0)
self.assertEqual(len(ticket.getMatches()), 0)
# dbmaxmatches = 0, should retrieve 0 matches by last ban:
self.db.maxMatches = 0;
self.db.addBan(self.jail, ticket)
ticket = self.db.getCurrentBans(self.jail, "127.0.0.1", fromtime=MyTime.time()-100)