Merge pull request #769 from kwirk/unban-database

BF: Remove manually unbanned IPs from persistent database
pull/774/head
Yaroslav Halchenko 2014-07-27 21:54:44 -04:00
commit 81c98f77ca
4 changed files with 26 additions and 1 deletions

View File

@ -39,6 +39,8 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger
* Per-distribution paths to the exim's main log * Per-distribution paths to the exim's main log
* Ignored IPs are no longer banned when being restored from persistent * Ignored IPs are no longer banned when being restored from persistent
database database
* Manually unbanned IPs are now removed from persistent database, such they
wont be banned again when Fail2Ban is restarted
- New features: - New features:
- Added monit filter thanks Jason H Martin. - Added monit filter thanks Jason H Martin.

View File

@ -197,6 +197,8 @@ class Actions(JailThread, Mapping):
if ticket is not None: if ticket is not None:
# Unban the IP. # Unban the IP.
self.__unBan(ticket) self.__unBan(ticket)
if self._jail.database is not None:
self._jail.database.delBan(self._jail, ticket)
else: else:
raise ValueError("IP %s is not banned" % ip) raise ValueError("IP %s is not banned" % ip)

View File

@ -368,10 +368,25 @@ class Fail2BanDb(object):
#TODO: Implement data parts once arbitrary match keys completed #TODO: Implement data parts once arbitrary match keys completed
cur.execute( cur.execute(
"INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)", "INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)",
(jail.name, ticket.getIP(), round(ticket.getTime()), (jail.name, ticket.getIP(), int(round(ticket.getTime())),
{"matches": ticket.getMatches(), {"matches": ticket.getMatches(),
"failures": ticket.getAttempt()})) "failures": ticket.getAttempt()}))
@commitandrollback
def delBan(self, cur, jail, ticket):
"""Delete a ban from the database.
Parameters
----------
jail : Jail
Jail in which the ban has occurred.
ticket : BanTicket
Ticket of the ban to be removed.
"""
cur.execute(
"DELETE FROM bans WHERE jail = ? AND ip = ? AND timeofban = ?",
(jail.name, ticket.getIP(), int(round(ticket.getTime()))))
@commitandrollback @commitandrollback
def _getBans(self, cur, jail=None, bantime=None, ip=None): def _getBans(self, cur, jail=None, bantime=None, ip=None):
query = "SELECT ip, timeofban, data FROM bans WHERE 1" query = "SELECT ip, timeofban, data FROM bans WHERE 1"

View File

@ -173,6 +173,12 @@ class DatabaseTest(unittest.TestCase):
self.assertTrue( self.assertTrue(
isinstance(self.db.getBans(jail=self.jail)[0], FailTicket)) isinstance(self.db.getBans(jail=self.jail)[0], FailTicket))
def testDelBan(self):
self.testAddBan()
ticket = self.db.getBans(jail=self.jail)[0]
self.db.delBan(self.jail, ticket)
self.assertEqual(len(self.db.getBans(jail=self.jail)), 0)
def testGetBansWithTime(self): def testGetBansWithTime(self):
if Fail2BanDb is None: # pragma: no cover if Fail2BanDb is None: # pragma: no cover
return return