"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "fail2ban/server/jail.py" between
fail2ban-0.10.5.tar.gz and fail2ban-0.11.1.tar.gz

About:

jail.py  (fail2ban-0.10.5):jail.py  (fail2ban-0.11.1)
skipping to change at line 27 skipping to change at line 27
# along with Fail2Ban; if not, write to the Free Software # along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA . # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA .
# Author: Cyril Jaquier # Author: Cyril Jaquier
__author__ = "Cyril Jaquier, Lee Clemens, Yaroslav Halchenko" __author__ = "Cyril Jaquier, Lee Clemens, Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Lee Clemens, 2012 Y aroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Lee Clemens, 2012 Y aroslav Halchenko"
__license__ = "GPL" __license__ = "GPL"
import logging import logging
import math
import random
import Queue import Queue
from .actions import Actions from .actions import Actions
from ..helpers import getLogger, extractOptions, MyTime from ..helpers import getLogger, _as_bool, extractOptions, MyTime
from .mytime import MyTime
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = getLogger(__name__) logSys = getLogger(__name__)
class Jail(object): class Jail(object):
"""Fail2Ban jail, which manages a filter and associated actions. """Fail2Ban jail, which manages a filter and associated actions.
The class handles the initialisation of a filter, and actions. It's The class handles the initialisation of a filter, and actions. It's
role is then to act as an interface between the filter and actions, role is then to act as an interface between the filter and actions,
passing bans detected by the filter, for the actions to then act upon. passing bans detected by the filter, for the actions to then act upon.
skipping to change at line 77 skipping to change at line 80
def __init__(self, name, backend = "auto", db=None): def __init__(self, name, backend = "auto", db=None):
self.__db = db self.__db = db
# 26 based on iptable chain name limit of 30 less len('f2b-') # 26 based on iptable chain name limit of 30 less len('f2b-')
if len(name) >= 26: if len(name) >= 26:
logSys.warning("Jail name %r might be too long and some c ommands " logSys.warning("Jail name %r might be too long and some c ommands "
"might not function corre ctly. Please shorten" "might not function corre ctly. Please shorten"
% name) % name)
self.__name = name self.__name = name
self.__queue = Queue.Queue() self.__queue = Queue.Queue()
self.__filter = None self.__filter = None
# Extra parameters for increase ban time
self._banExtra = {};
logSys.info("Creating new jail '%s'" % self.name) logSys.info("Creating new jail '%s'" % self.name)
if backend is not None: if backend is not None:
self._setBackend(backend) self._setBackend(backend)
self.backend = backend self.backend = backend
def __repr__(self): def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.name) return "%s(%r)" % (self.__class__.__name__, self.name)
def _setBackend(self, backend): def _setBackend(self, backend):
backend, beArgs = extractOptions(backend) backend, beArgs = extractOptions(backend)
skipping to change at line 195 skipping to change at line 200
("Filter", self.filter.status(flavor=flavor)), ("Filter", self.filter.status(flavor=flavor)),
("Actions", self.actions.status(flavor=flavor)), ("Actions", self.actions.status(flavor=flavor)),
] ]
def putFailTicket(self, ticket): def putFailTicket(self, ticket):
"""Add a fail ticket to the jail. """Add a fail ticket to the jail.
Used by filter to add a failure for banning. Used by filter to add a failure for banning.
""" """
self.__queue.put(ticket) self.__queue.put(ticket)
if not ticket.restored and self.database is not None: # add ban to database moved to observer (should previously check
self.database.addBan(self, ticket) not already banned
# and increase ticket time if "bantime.increment" set)
def getFailTicket(self): def getFailTicket(self):
"""Get a fail ticket from the jail. """Get a fail ticket from the jail.
Used by actions to get a failure for banning. Used by actions to get a failure for banning.
""" """
try: try:
ticket = self.__queue.get(False) ticket = self.__queue.get(False)
return ticket return ticket
except Queue.Empty: except Queue.Empty:
return False return False
def restoreCurrentBans(self): def setBanTimeExtra(self, opt, value):
# merge previous extra with new option:
be = self._banExtra;
if value == '':
value = None
if value is not None:
be[opt] = value;
elif opt in be:
del be[opt]
logSys.info('Set banTime.%s = %s', opt, value)
if opt == 'increment':
be[opt] = _as_bool(value)
if be.get(opt) and self.database is None:
logSys.warning("ban time increment is not availab
le as long jail database is not set")
if opt in ['maxtime', 'rndtime']:
if not value is None:
be[opt] = MyTime.str2seconds(value)
# prepare formula lambda:
if opt in ['formula', 'factor', 'maxtime', 'rndtime', 'multiplier
s'] or be.get('evformula', None) is None:
# split multifiers to an array begins with 0 (or empty if
not set):
if opt == 'multipliers':
be['evmultipliers'] = [int(i) for i in (value.spl
it(' ') if value is not None and value != '' else [])]
# if we have multifiers - use it in lambda, otherwise com
pile and use formula within lambda
multipliers = be.get('evmultipliers', [])
banFactor = eval(be.get('factor', "1"))
if len(multipliers):
evformula = lambda ban, banFactor=banFactor: (
ban.Time * banFactor * multipliers[ban.Co
unt if ban.Count < len(multipliers) else -1]
)
else:
formula = be.get('formula', 'ban.Time * (1<<(ban.
Count if ban.Count<20 else 20)) * banFactor')
formula = compile(formula, '~inline-conf-expr~',
'eval')
evformula = lambda ban, banFactor=banFactor, form
ula=formula: max(ban.Time, eval(formula))
# extend lambda with max time :
if not be.get('maxtime', None) is None:
maxtime = be['maxtime']
evformula = lambda ban, evformula=evformula: min(
evformula(ban), maxtime)
# mix lambda with random time (to prevent bot-nets to cal
culate exact time IP can be unbanned):
if not be.get('rndtime', None) is None:
rndtime = be['rndtime']
evformula = lambda ban, evformula=evformula: (evf
ormula(ban) + random.random() * rndtime)
# set to extra dict:
be['evformula'] = evformula
#logSys.info('banTimeExtra : %s' % json.dumps(be))
def getBanTimeExtra(self, opt=None):
if opt is not None:
return self._banExtra.get(opt, None)
return self._banExtra
def getMaxBanTime(self):
"""Returns max possible ban-time of jail.
"""
return self._banExtra.get("maxtime", -1) \
if self._banExtra.get('increment') else self.actions.getB
anTime()
def restoreCurrentBans(self, correctBanTime=True):
"""Restore any previous valid bans from the database. """Restore any previous valid bans from the database.
""" """
try: try:
if self.database is not None: if self.database is not None:
forbantime = self.actions.getBanTime() if self._banExtra.get('increment'):
for ticket in self.database.getCurrentBans(jail=s forbantime = None;
elf, if correctBanTime:
forbantime=forbantime, maxmatches correctBanTime = self.getMaxBanTi
=self.filter.failManager.maxMatches): me()
#logSys.debug('restored ticket: %s', tick else:
et) # use ban time as search time if we have
if not self.filter.inIgnoreIPList(ticket. not enabled a increasing:
getIP(), log_ignore=True): forbantime = self.actions.getBanTime()
for ticket in self.database.getCurrentBans(jail=s
elf, forbantime=forbantime,
correctBanTime=correctBanTime, maxmatches
=self.filter.failManager.maxMatches
):
try:
#logSys.debug('restored ticket: %
s', ticket)
if self.filter.inIgnoreIPList(tic
ket.getIP(), log_ignore=True): continue
# mark ticked was restored from d atabase - does not put it again into db: # mark ticked was restored from d atabase - does not put it again into db:
ticket.restored = True ticket.restored = True
# correct start time / ban time ( by the same end of ban): # correct start time / ban time ( by the same end of ban):
btm = ticket.getBanTime(forbantim e) btm = ticket.getBanTime(forbantim e)
diftm = MyTime.time() - ticket.ge tTime() diftm = MyTime.time() - ticket.ge tTime()
if btm != -1 and diftm > 0: if btm != -1 and diftm > 0:
btm -= diftm btm -= diftm
# ignore obsolete tickets: # ignore obsolete tickets:
if btm != -1 and btm <= 0: if btm != -1 and btm <= 0:
continue continue
ticket.setTime(MyTime.time())
ticket.setBanTime(btm)
self.putFailTicket(ticket) self.putFailTicket(ticket)
except Exception as e: # pragma: no cover
logSys.error('Restore ticket fail
ed: %s', e,
exc_info=logSys.getEffect
iveLevel()<=logging.DEBUG)
except Exception as e: # pragma: no cover except Exception as e: # pragma: no cover
logSys.error('%s', e, exc_info=logSys.getEffectiveLevel() logSys.error('Restore bans failed: %s', e,
<=logging.DEBUG) exc_info=logSys.getEffectiveLevel()<=logging.DEBU
G)
def start(self): def start(self):
"""Start the jail, by starting filter and actions threads. """Start the jail, by starting filter and actions threads.
Once stated, also queries the persistent database to reinstate Once stated, also queries the persistent database to reinstate
any valid bans. any valid bans.
""" """
logSys.debug("Starting jail %r", self.name) logSys.debug("Starting jail %r", self.name)
self.filter.start() self.filter.start()
self.actions.start() self.actions.start()
 End of changes. 9 change blocks. 
17 lines changed or deleted 106 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)