mirror of https://github.com/fail2ban/fail2ban
RF: Change Jails and Actions to Mapping types
parent
a070284a18
commit
6e63f0ea5a
|
@ -103,7 +103,7 @@ class SMTPAction(ActionBase):
|
||||||
self.message_values = CallingMap(
|
self.message_values = CallingMap(
|
||||||
jailname = self._jail.getName(), # Doesn't change
|
jailname = self._jail.getName(), # Doesn't change
|
||||||
hostname = socket.gethostname,
|
hostname = socket.gethostname,
|
||||||
bantime = self._jail.getAction().getBanTime,
|
bantime = self._jail.actions.getBanTime,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _sendMessage(self, subject, text):
|
def _sendMessage(self, subject, text):
|
||||||
|
|
|
@ -29,7 +29,7 @@ __license__ = "GPL"
|
||||||
class DuplicateJailException(Exception):
|
class DuplicateJailException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class UnknownJailException(Exception):
|
class UnknownJailException(KeyError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,6 @@ protocol = [
|
||||||
["get <JAIL> usedns", "gets the usedns setting for <JAIL>"],
|
["get <JAIL> usedns", "gets the usedns setting for <JAIL>"],
|
||||||
["get <JAIL> maxretry", "gets the number of failures allowed for <JAIL>"],
|
["get <JAIL> maxretry", "gets the number of failures allowed for <JAIL>"],
|
||||||
["get <JAIL> maxlines", "gets the number of lines to buffer for <JAIL>"],
|
["get <JAIL> maxlines", "gets the number of lines to buffer for <JAIL>"],
|
||||||
["get <JAIL> addaction", "gets the last action which has been added for <JAIL>"],
|
|
||||||
["get <JAIL> actions", "gets a list of actions for <JAIL>"],
|
["get <JAIL> actions", "gets a list of actions for <JAIL>"],
|
||||||
["", "COMMAND ACTION INFORMATION",""],
|
["", "COMMAND ACTION INFORMATION",""],
|
||||||
["get <JAIL> action <ACT> actionstart", "gets the start command for the action <ACT> for <JAIL>"],
|
["get <JAIL> action <ACT> actionstart", "gets the start command for the action <ACT> for <JAIL>"],
|
||||||
|
|
|
@ -79,12 +79,11 @@ class ActionBase(object):
|
||||||
place to create a python based action for fail2ban. This class can
|
place to create a python based action for fail2ban. This class can
|
||||||
be inherited from to ease implementation, but is not required as
|
be inherited from to ease implementation, but is not required as
|
||||||
long as the following required methods/properties are implemented:
|
long as the following required methods/properties are implemented:
|
||||||
- __init__(jail, actionname)
|
- __init__(jail, name)
|
||||||
- start()
|
- start()
|
||||||
- stop()
|
- stop()
|
||||||
- ban(aInfo)
|
- ban(aInfo)
|
||||||
- unban(aInfo)
|
- unban(aInfo)
|
||||||
- actionname
|
|
||||||
"""
|
"""
|
||||||
__metaclass__ = ABCMeta
|
__metaclass__ = ABCMeta
|
||||||
|
|
||||||
|
@ -101,23 +100,17 @@ class ActionBase(object):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __init__(self, jail, actionname):
|
def __init__(self, jail, name):
|
||||||
"""Should initialise the action class with `jail` being the Jail
|
"""Should initialise the action class with `jail` being the Jail
|
||||||
object the action belongs to, `actionname` being the name assigned
|
object the action belongs to, `name` being the name assigned
|
||||||
to the action, and `kwargs` being all other args that have been
|
to the action, and `kwargs` being all other args that have been
|
||||||
specified with jail.conf or on the fail2ban-client.
|
specified with jail.conf or on the fail2ban-client.
|
||||||
"""
|
"""
|
||||||
self._jail = jail
|
self._jail = jail
|
||||||
self._actionname = actionname
|
self._name = name
|
||||||
self._logSys = logging.getLogger(
|
self._logSys = logging.getLogger(
|
||||||
'%s.%s' % (__name__, self.__class__.__name__))
|
'%s.%s' % (__name__, self.__class__.__name__))
|
||||||
|
|
||||||
@property
|
|
||||||
def actionname(self):
|
|
||||||
"""The name of the action, which should not change in the
|
|
||||||
lifetime of the action."""
|
|
||||||
return self._actionname
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Executed when the jail/action starts."""
|
"""Executed when the jail/action starts."""
|
||||||
pass
|
pass
|
||||||
|
@ -144,8 +137,8 @@ class CommandAction(ActionBase):
|
||||||
Fail2Ban uses.
|
Fail2Ban uses.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, jail, actionname):
|
def __init__(self, jail, name):
|
||||||
super(CommandAction, self).__init__(jail, actionname)
|
super(CommandAction, self).__init__(jail, name)
|
||||||
self.timeout = 60
|
self.timeout = 60
|
||||||
## Command executed in order to initialize the system.
|
## Command executed in order to initialize the system.
|
||||||
self.actionstart = ''
|
self.actionstart = ''
|
||||||
|
@ -172,7 +165,7 @@ class CommandAction(ActionBase):
|
||||||
def timeout(self, timeout):
|
def timeout(self, timeout):
|
||||||
self._timeout = int(timeout)
|
self._timeout = int(timeout)
|
||||||
self._logSys.debug("Set action %s timeout = %i" %
|
self._logSys.debug("Set action %s timeout = %i" %
|
||||||
(self.actionname, self.timeout))
|
(self._name, self.timeout))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _properties(self):
|
def _properties(self):
|
||||||
|
|
|
@ -27,6 +27,7 @@ __license__ = "GPL"
|
||||||
import time, logging
|
import time, logging
|
||||||
import os
|
import os
|
||||||
import imp
|
import imp
|
||||||
|
from collections import Mapping
|
||||||
|
|
||||||
from .banmanager import BanManager
|
from .banmanager import BanManager
|
||||||
from .jailthread import JailThread
|
from .jailthread import JailThread
|
||||||
|
@ -36,40 +37,61 @@ from .mytime import MyTime
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = logging.getLogger(__name__)
|
||||||
|
|
||||||
##
|
class Actions(JailThread, Mapping):
|
||||||
# Execute commands.
|
"""Handles jail actions.
|
||||||
#
|
|
||||||
# This class reads the failures from the Jail queue and decide if an
|
This class handles the actions of the jail. Creation, deletion or to
|
||||||
# action has to be taken. A BanManager take care of the banned IP
|
actions must be done through this class. This class is based on the
|
||||||
# addresses.
|
Mapping type, and the `add` method must be used to add new actions.
|
||||||
|
This class also starts and stops the actions, and fetches bans from
|
||||||
|
the jail executing these bans via the actions.
|
||||||
|
"""
|
||||||
|
|
||||||
class Actions(JailThread):
|
|
||||||
|
|
||||||
##
|
|
||||||
# Constructor.
|
|
||||||
#
|
|
||||||
# Initialize the filter object with default values.
|
|
||||||
# @param jail the jail object
|
|
||||||
|
|
||||||
def __init__(self, jail):
|
def __init__(self, jail):
|
||||||
|
"""Initialise an empty Actions instance.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
jail: Jail
|
||||||
|
The jail of which the actions belongs to.
|
||||||
|
"""
|
||||||
JailThread.__init__(self)
|
JailThread.__init__(self)
|
||||||
## The jail which contains this action.
|
## The jail which contains this action.
|
||||||
self.jail = jail
|
self._jail = jail
|
||||||
self.__actions = list()
|
self._actions = dict()
|
||||||
## The ban manager.
|
## The ban manager.
|
||||||
self.__banManager = BanManager()
|
self.__banManager = BanManager()
|
||||||
|
|
||||||
##
|
def add(self, name, pythonModule=None, initOpts=None):
|
||||||
# Adds an action.
|
"""Adds a new action.
|
||||||
#
|
|
||||||
# @param name The action name
|
Add a new action if not already present, defaulting to standard
|
||||||
|
`CommandAction`, or specified Python module.
|
||||||
def addAction(self, name, pythonModule=None, initOpts=None):
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
name : str
|
||||||
|
The name of the action.
|
||||||
|
pythonModule : str
|
||||||
|
Path to Python file which must contain `Action` class.
|
||||||
|
initOpts : dict
|
||||||
|
Options for Python Action, used as keyword arguments for
|
||||||
|
initialisation.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
ValueError
|
||||||
|
If action name already exists.
|
||||||
|
RuntimeError
|
||||||
|
If external Python module does not have `Action` class
|
||||||
|
or does not implement necessary methods as per `ActionBase`
|
||||||
|
abstract class.
|
||||||
|
"""
|
||||||
# Check is action name already exists
|
# Check is action name already exists
|
||||||
if name in [action.actionname for action in self.__actions]:
|
if name in self._actions:
|
||||||
raise ValueError("Action %s already exists" % name)
|
raise ValueError("Action %s already exists" % name)
|
||||||
if pythonModule is None:
|
if pythonModule is None:
|
||||||
action = CommandAction(self.jail, name)
|
action = CommandAction(self._jail, name)
|
||||||
else:
|
else:
|
||||||
pythonModuleName = os.path.basename(pythonModule.strip(".py"))
|
pythonModuleName = os.path.basename(pythonModule.strip(".py"))
|
||||||
customActionModule = imp.load_source(
|
customActionModule = imp.load_source(
|
||||||
|
@ -79,53 +101,35 @@ class Actions(JailThread):
|
||||||
"%s module does not have 'Action' class" % pythonModule)
|
"%s module does not have 'Action' class" % pythonModule)
|
||||||
elif not issubclass(customActionModule.Action, ActionBase):
|
elif not issubclass(customActionModule.Action, ActionBase):
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"%s module %s does not implment required methods" % (
|
"%s module %s does not implement required methods" % (
|
||||||
pythonModule, customActionModule.Action.__name__))
|
pythonModule, customActionModule.Action.__name__))
|
||||||
action = customActionModule.Action(self.jail, name, **initOpts)
|
action = customActionModule.Action(self._jail, name, **initOpts)
|
||||||
self.__actions.append(action)
|
self._actions[name] = action
|
||||||
|
|
||||||
##
|
def __getitem__(self, name):
|
||||||
# Removes an action.
|
try:
|
||||||
#
|
return self._actions[name]
|
||||||
# @param name The action name
|
except KeyError:
|
||||||
|
raise KeyError("Invalid Action name: %s" % name)
|
||||||
def delAction(self, name):
|
|
||||||
for action in self.__actions:
|
def __delitem__(self, name):
|
||||||
if action.actionname == name:
|
try:
|
||||||
self.__actions.remove(action)
|
del self._actions[name]
|
||||||
return
|
except KeyError:
|
||||||
raise KeyError("Invalid Action name: %s" % name)
|
raise KeyError("Invalid Action name: %s" % name)
|
||||||
|
|
||||||
##
|
def __iter__(self):
|
||||||
# Returns an action.
|
return iter(self._actions)
|
||||||
#
|
|
||||||
# Raises a KeyError exception if the action does not exist.
|
def __len__(self):
|
||||||
#
|
return len(self._actions)
|
||||||
# @param name the action name
|
|
||||||
# @return the action
|
def __eq__(self, other): # Required for Threading
|
||||||
|
return False
|
||||||
def getAction(self, name):
|
|
||||||
for action in self.__actions:
|
def __hash__(self): # Required for Threading
|
||||||
if action.actionname == name:
|
return id(self)
|
||||||
return action
|
|
||||||
raise KeyError("Invalid Action name")
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the last defined action.
|
|
||||||
#
|
|
||||||
# @return The last defined action.
|
|
||||||
|
|
||||||
def getLastAction(self):
|
|
||||||
return self.__actions[-1]
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the list of actions
|
|
||||||
#
|
|
||||||
# @return list of actions
|
|
||||||
|
|
||||||
def getActions(self):
|
|
||||||
return self.__actions
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Set the ban time.
|
# Set the ban time.
|
||||||
#
|
#
|
||||||
|
@ -142,38 +146,52 @@ class Actions(JailThread):
|
||||||
|
|
||||||
def getBanTime(self):
|
def getBanTime(self):
|
||||||
return self.__banManager.getBanTime()
|
return self.__banManager.getBanTime()
|
||||||
|
|
||||||
##
|
|
||||||
# Remove a banned IP now, rather than waiting for it to expire, even if set to never expire.
|
|
||||||
#
|
|
||||||
# @return the IP string or 'None' if not unbanned.
|
|
||||||
def removeBannedIP(self, ip):
|
def removeBannedIP(self, ip):
|
||||||
|
"""Removes banned IP calling actions' unban method
|
||||||
|
|
||||||
|
Remove a banned IP now, rather than waiting for it to expire,
|
||||||
|
even if set to never expire.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
ip : str
|
||||||
|
The IP address to unban
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
ValueError
|
||||||
|
If `ip` is not banned
|
||||||
|
"""
|
||||||
# Find the ticket with the IP.
|
# Find the ticket with the IP.
|
||||||
ticket = self.__banManager.getTicketByIP(ip)
|
ticket = self.__banManager.getTicketByIP(ip)
|
||||||
if ticket is not None:
|
if ticket is not None:
|
||||||
# Unban the IP.
|
# Unban the IP.
|
||||||
self.__unBan(ticket)
|
self.__unBan(ticket)
|
||||||
return ip
|
else:
|
||||||
raise ValueError("IP %s is not banned" % ip)
|
raise ValueError("IP %s is not banned" % ip)
|
||||||
|
|
||||||
##
|
|
||||||
# Main loop.
|
|
||||||
#
|
|
||||||
# This function is the main loop of the thread. It checks the Jail
|
|
||||||
# queue and executes commands when an IP address is banned.
|
|
||||||
# @return True when the thread exits nicely
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
"""Main loop for Threading.
|
||||||
|
|
||||||
|
This function is the main loop of the thread. It checks the jail
|
||||||
|
queue and executes commands when an IP address is banned.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
bool
|
||||||
|
True when the thread exits nicely.
|
||||||
|
"""
|
||||||
self.setActive(True)
|
self.setActive(True)
|
||||||
for action in self.__actions:
|
for name, action in self._actions.iteritems():
|
||||||
try:
|
try:
|
||||||
action.start()
|
action.start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logSys.error("Failed to start jail '%s' action '%s': %s",
|
logSys.error("Failed to start jail '%s' action '%s': %s",
|
||||||
self.jail.getName(), action.actionname, e)
|
self._jail.getName(), name, e)
|
||||||
while self._isActive():
|
while self._isActive():
|
||||||
if not self.getIdle():
|
if not self.getIdle():
|
||||||
#logSys.debug(self.jail.getName() + ": action")
|
#logSys.debug(self._jail.getName() + ": action")
|
||||||
ret = self.__checkBan()
|
ret = self.__checkBan()
|
||||||
if not ret:
|
if not ret:
|
||||||
self.__checkUnBan()
|
self.__checkUnBan()
|
||||||
|
@ -181,24 +199,27 @@ class Actions(JailThread):
|
||||||
else:
|
else:
|
||||||
time.sleep(self.getSleepTime())
|
time.sleep(self.getSleepTime())
|
||||||
self.__flushBan()
|
self.__flushBan()
|
||||||
for action in self.__actions:
|
for name, action in self._actions.iteritems():
|
||||||
try:
|
try:
|
||||||
action.stop()
|
action.stop()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logSys.error("Failed to stop jail '%s' action '%s': %s",
|
logSys.error("Failed to stop jail '%s' action '%s': %s",
|
||||||
self.jail.getName(), action.actionname, e)
|
self._jail.getName(), name, e)
|
||||||
logSys.debug(self.jail.getName() + ": action terminated")
|
logSys.debug(self._jail.getName() + ": action terminated")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
##
|
|
||||||
# Check for IP address to ban.
|
|
||||||
#
|
|
||||||
# Look in the Jail queue for FailTicket. If a ticket is available,
|
|
||||||
# it executes the "ban" command and add a ticket to the BanManager.
|
|
||||||
# @return True if an IP address get banned
|
|
||||||
|
|
||||||
def __checkBan(self):
|
def __checkBan(self):
|
||||||
ticket = self.jail.getFailTicket()
|
"""Check for IP address to ban.
|
||||||
|
|
||||||
|
Look in the jail queue for FailTicket. If a ticket is available,
|
||||||
|
it executes the "ban" command and adds a ticket to the BanManager.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
bool
|
||||||
|
True if an IP address get banned.
|
||||||
|
"""
|
||||||
|
ticket = self._jail.getFailTicket()
|
||||||
if ticket != False:
|
if ticket != False:
|
||||||
aInfo = CallingMap()
|
aInfo = CallingMap()
|
||||||
bTicket = BanManager.createBanTicket(ticket)
|
bTicket = BanManager.createBanTicket(ticket)
|
||||||
|
@ -206,83 +227,88 @@ class Actions(JailThread):
|
||||||
aInfo["failures"] = bTicket.getAttempt()
|
aInfo["failures"] = bTicket.getAttempt()
|
||||||
aInfo["time"] = bTicket.getTime()
|
aInfo["time"] = bTicket.getTime()
|
||||||
aInfo["matches"] = "\n".join(bTicket.getMatches())
|
aInfo["matches"] = "\n".join(bTicket.getMatches())
|
||||||
if self.jail.getDatabase() is not None:
|
if self._jail.getDatabase() is not None:
|
||||||
aInfo["ipmatches"] = lambda: "\n".join(
|
aInfo["ipmatches"] = lambda: "\n".join(
|
||||||
self.jail.getDatabase().getBansMerged(
|
self._jail.getDatabase().getBansMerged(
|
||||||
ip=bTicket.getIP()).getMatches())
|
ip=bTicket.getIP()).getMatches())
|
||||||
aInfo["ipjailmatches"] = lambda: "\n".join(
|
aInfo["ipjailmatches"] = lambda: "\n".join(
|
||||||
self.jail.getDatabase().getBansMerged(
|
self._jail.getDatabase().getBansMerged(
|
||||||
ip=bTicket.getIP(), jail=self.jail).getMatches())
|
ip=bTicket.getIP(), jail=self._jail).getMatches())
|
||||||
aInfo["ipfailures"] = lambda: "\n".join(
|
aInfo["ipfailures"] = lambda: "\n".join(
|
||||||
self.jail.getDatabase().getBansMerged(
|
self._jail.getDatabase().getBansMerged(
|
||||||
ip=bTicket.getIP()).getAttempt())
|
ip=bTicket.getIP()).getAttempt())
|
||||||
aInfo["ipjailfailures"] = lambda: "\n".join(
|
aInfo["ipjailfailures"] = lambda: "\n".join(
|
||||||
self.jail.getDatabase().getBansMerged(
|
self._jail.getDatabase().getBansMerged(
|
||||||
ip=bTicket.getIP(), jail=self.jail).getAttempt())
|
ip=bTicket.getIP(), jail=self._jail).getAttempt())
|
||||||
if self.__banManager.addBanTicket(bTicket):
|
if self.__banManager.addBanTicket(bTicket):
|
||||||
logSys.warning("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
|
logSys.warning("[%s] Ban %s" % (self._jail.getName(), aInfo["ip"]))
|
||||||
for action in self.__actions:
|
for name, action in self._actions.iteritems():
|
||||||
try:
|
try:
|
||||||
action.ban(aInfo)
|
action.ban(aInfo)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logSys.error(
|
logSys.error(
|
||||||
"Failed to execute ban jail '%s' action '%s': %s",
|
"Failed to execute ban jail '%s' action '%s': %s",
|
||||||
self.jail.getName(), action.actionname, e)
|
self._jail.getName(), name, e)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logSys.info("[%s] %s already banned" % (self.jail.getName(),
|
logSys.info("[%s] %s already banned" % (self._jail.getName(),
|
||||||
aInfo["ip"]))
|
aInfo["ip"]))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
##
|
|
||||||
# Check for IP address to unban.
|
|
||||||
#
|
|
||||||
# Unban IP address which are outdated.
|
|
||||||
|
|
||||||
def __checkUnBan(self):
|
def __checkUnBan(self):
|
||||||
|
"""Check for IP address to unban.
|
||||||
|
|
||||||
|
Unban IP addresses which are outdated.
|
||||||
|
"""
|
||||||
for ticket in self.__banManager.unBanList(MyTime.time()):
|
for ticket in self.__banManager.unBanList(MyTime.time()):
|
||||||
self.__unBan(ticket)
|
self.__unBan(ticket)
|
||||||
|
|
||||||
##
|
|
||||||
# Flush the ban list.
|
|
||||||
#
|
|
||||||
# Unban all IP address which are still in the banning list.
|
|
||||||
|
|
||||||
def __flushBan(self):
|
def __flushBan(self):
|
||||||
|
"""Flush the ban list.
|
||||||
|
|
||||||
|
Unban all IP address which are still in the banning list.
|
||||||
|
"""
|
||||||
logSys.debug("Flush ban list")
|
logSys.debug("Flush ban list")
|
||||||
for ticket in self.__banManager.flushBanList():
|
for ticket in self.__banManager.flushBanList():
|
||||||
self.__unBan(ticket)
|
self.__unBan(ticket)
|
||||||
|
|
||||||
##
|
|
||||||
# Unbans host corresponding to the ticket.
|
|
||||||
#
|
|
||||||
# Executes the actions in order to unban the host given in the
|
|
||||||
# ticket.
|
|
||||||
|
|
||||||
def __unBan(self, ticket):
|
def __unBan(self, ticket):
|
||||||
|
"""Unbans host corresponding to the ticket.
|
||||||
|
|
||||||
|
Executes the actions in order to unban the host given in the
|
||||||
|
ticket.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
ticket : FailTicket
|
||||||
|
Ticket of failures of which to unban
|
||||||
|
"""
|
||||||
aInfo = dict()
|
aInfo = dict()
|
||||||
aInfo["ip"] = ticket.getIP()
|
aInfo["ip"] = ticket.getIP()
|
||||||
aInfo["failures"] = ticket.getAttempt()
|
aInfo["failures"] = ticket.getAttempt()
|
||||||
aInfo["time"] = ticket.getTime()
|
aInfo["time"] = ticket.getTime()
|
||||||
aInfo["matches"] = "".join(ticket.getMatches())
|
aInfo["matches"] = "".join(ticket.getMatches())
|
||||||
logSys.warning("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
|
logSys.warning("[%s] Unban %s" % (self._jail.getName(), aInfo["ip"]))
|
||||||
for action in self.__actions:
|
for name, action in self._actions.iteritems():
|
||||||
try:
|
try:
|
||||||
action.unban(aInfo)
|
action.unban(aInfo)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logSys.error(
|
logSys.error(
|
||||||
"Failed to execute unban jail '%s' action '%s': %s",
|
"Failed to execute unban jail '%s' action '%s': %s",
|
||||||
self.jail.getName(), action.actionname, e)
|
self._jail.getName(), name, e)
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Get the status of the filter.
|
|
||||||
#
|
|
||||||
# Get some informations about the filter state such as the total
|
|
||||||
# number of failures.
|
|
||||||
# @return a list with tuple
|
|
||||||
|
|
||||||
def status(self):
|
def status(self):
|
||||||
|
"""Get the status of the filter.
|
||||||
|
|
||||||
|
Get some informations about the filter state such as the total
|
||||||
|
number of failures.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
list
|
||||||
|
List of tuple pairs, each containing a description and value
|
||||||
|
for general status information.
|
||||||
|
"""
|
||||||
ret = [("Currently banned", self.__banManager.size()),
|
ret = [("Currently banned", self.__banManager.size()),
|
||||||
("Total banned", self.__banManager.getBanTotal()),
|
("Total banned", self.__banManager.getBanTotal()),
|
||||||
("IP list", self.__banManager.getBanList())]
|
("IP list", self.__banManager.getBanList())]
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Jail:
|
||||||
"%r was requested" % (b, backend))
|
"%r was requested" % (b, backend))
|
||||||
else:
|
else:
|
||||||
logSys.info("Initiated %r backend" % b)
|
logSys.info("Initiated %r backend" % b)
|
||||||
self.__action = Actions(self)
|
self.__actions = Actions(self)
|
||||||
return # we are done
|
return # we are done
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
logSys.debug(
|
logSys.debug(
|
||||||
|
@ -124,11 +124,17 @@ class Jail:
|
||||||
def getDatabase(self):
|
def getDatabase(self):
|
||||||
return self.__db
|
return self.__db
|
||||||
|
|
||||||
def getFilter(self):
|
@property
|
||||||
|
def filter(self):
|
||||||
|
"""The filter which the jail is using to monitor log files.
|
||||||
|
"""
|
||||||
return self.__filter
|
return self.__filter
|
||||||
|
|
||||||
def getAction(self):
|
@property
|
||||||
return self.__action
|
def actions(self):
|
||||||
|
"""Actions object used to manage actions for jail.
|
||||||
|
"""
|
||||||
|
return self.__actions
|
||||||
|
|
||||||
def putFailTicket(self, ticket):
|
def putFailTicket(self, ticket):
|
||||||
self.__queue.put(ticket)
|
self.__queue.put(ticket)
|
||||||
|
@ -143,36 +149,36 @@ class Jail:
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.__filter.start()
|
self.__filter.start()
|
||||||
self.__action.start()
|
self.__actions.start()
|
||||||
# Restore any previous valid bans from the database
|
# Restore any previous valid bans from the database
|
||||||
if self.__db is not None:
|
if self.__db is not None:
|
||||||
for ticket in self.__db.getBans(
|
for ticket in self.__db.getBans(
|
||||||
jail=self, bantime=self.__action.getBanTime()):
|
jail=self, bantime=self.__actions.getBanTime()):
|
||||||
self.__queue.put(ticket)
|
self.__queue.put(ticket)
|
||||||
logSys.info("Jail '%s' started" % self.__name)
|
logSys.info("Jail '%s' started" % self.__name)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.__filter.stop()
|
self.__filter.stop()
|
||||||
self.__action.stop()
|
self.__actions.stop()
|
||||||
self.__filter.join()
|
self.__filter.join()
|
||||||
self.__action.join()
|
self.__actions.join()
|
||||||
logSys.info("Jail '%s' stopped" % self.__name)
|
logSys.info("Jail '%s' stopped" % self.__name)
|
||||||
|
|
||||||
def isAlive(self):
|
def isAlive(self):
|
||||||
isAlive0 = self.__filter.isAlive()
|
isAlive0 = self.__filter.isAlive()
|
||||||
isAlive1 = self.__action.isAlive()
|
isAlive1 = self.__actions.isAlive()
|
||||||
return isAlive0 or isAlive1
|
return isAlive0 or isAlive1
|
||||||
|
|
||||||
def setIdle(self, value):
|
def setIdle(self, value):
|
||||||
self.__filter.setIdle(value)
|
self.__filter.setIdle(value)
|
||||||
self.__action.setIdle(value)
|
self.__actions.setIdle(value)
|
||||||
|
|
||||||
def getIdle(self):
|
def getIdle(self):
|
||||||
return self.__filter.getIdle() or self.__action.getIdle()
|
return self.__filter.getIdle() or self.__actions.getIdle()
|
||||||
|
|
||||||
def getStatus(self):
|
def getStatus(self):
|
||||||
fStatus = self.__filter.status()
|
fStatus = self.__filter.status()
|
||||||
aStatus = self.__action.status()
|
aStatus = self.__actions.status()
|
||||||
ret = [("filter", fStatus),
|
ret = [("filter", fStatus),
|
||||||
("action", aStatus)]
|
("action", aStatus)]
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -22,136 +22,83 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2013- Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
from collections import Mapping
|
||||||
|
|
||||||
from ..exceptions import DuplicateJailException, UnknownJailException
|
from ..exceptions import DuplicateJailException, UnknownJailException
|
||||||
from .jail import Jail
|
from .jail import Jail
|
||||||
|
|
||||||
##
|
|
||||||
# Handles the jails.
|
|
||||||
#
|
|
||||||
# This class handles the jails. Creation, deletion or access to a jail must be
|
|
||||||
# done through this class. This class is thread-safe which is not the case of
|
|
||||||
# the jail itself, including filter and actions.
|
|
||||||
|
|
||||||
class Jails:
|
class Jails(Mapping):
|
||||||
|
"""Handles the jails.
|
||||||
##
|
|
||||||
# Constructor.
|
This class handles the jails. Creation, deletion or access to a jail
|
||||||
|
must be done through this class. This class is thread-safe which is
|
||||||
|
not the case of the jail itself, including filter and actions. This
|
||||||
|
class is based on Mapping type, and the `add` method must be used to
|
||||||
|
add additional jails.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
"""Initialise an empty Jails instance.
|
||||||
|
"""
|
||||||
self.__lock = Lock()
|
self.__lock = Lock()
|
||||||
self.__jails = dict()
|
self._jails = dict()
|
||||||
|
|
||||||
##
|
|
||||||
# Adds a jail.
|
|
||||||
#
|
|
||||||
# Adds a new jail which should use the given backend. Raises a
|
|
||||||
# <code>DuplicateJailException</code> if the jail is already defined.
|
|
||||||
# @param name The name of the jail
|
|
||||||
# @param backend The backend to use
|
|
||||||
|
|
||||||
def add(self, name, backend, db=None):
|
def add(self, name, backend, db=None):
|
||||||
|
"""Adds a jail.
|
||||||
|
|
||||||
|
Adds a new jail if not already present which should use the
|
||||||
|
given backend.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
name : str
|
||||||
|
The name of the jail.
|
||||||
|
backend : str
|
||||||
|
The backend to use.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
DuplicateJailException
|
||||||
|
If jail name is already present.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
if self.__jails.has_key(name):
|
if name in self._jails:
|
||||||
raise DuplicateJailException(name)
|
raise DuplicateJailException(name)
|
||||||
else:
|
else:
|
||||||
self.__jails[name] = Jail(name, backend, db)
|
self._jails[name] = Jail(name, backend, db)
|
||||||
finally:
|
|
||||||
self.__lock.release()
|
|
||||||
|
|
||||||
##
|
|
||||||
# Removes a jail.
|
|
||||||
#
|
|
||||||
# Removes the jail <code>name</code>. Raise an <code>UnknownJailException</code>
|
|
||||||
# if the jail does not exist.
|
|
||||||
# @param name The name of the jail
|
|
||||||
|
|
||||||
def remove(self, name):
|
|
||||||
try:
|
|
||||||
self.__lock.acquire()
|
|
||||||
if self.__jails.has_key(name):
|
|
||||||
del self.__jails[name]
|
|
||||||
else:
|
|
||||||
raise UnknownJailException(name)
|
|
||||||
finally:
|
|
||||||
self.__lock.release()
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns a jail.
|
|
||||||
#
|
|
||||||
# Returns the jail <code>name</code>. Raise an <code>UnknownJailException</code>
|
|
||||||
# if the jail does not exist.
|
|
||||||
# @param name The name of the jail
|
|
||||||
|
|
||||||
def get(self, name):
|
|
||||||
try:
|
|
||||||
self.__lock.acquire()
|
|
||||||
if self.__jails.has_key(name):
|
|
||||||
jail = self.__jails[name]
|
|
||||||
return jail
|
|
||||||
else:
|
|
||||||
raise UnknownJailException(name)
|
|
||||||
finally:
|
|
||||||
self.__lock.release()
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns an action class instance.
|
|
||||||
#
|
|
||||||
# Returns the action object of the jail <code>name</code>. Raise an
|
|
||||||
# <code>UnknownJailException</code> if the jail does not exist.
|
|
||||||
# @param name The name of the jail
|
|
||||||
|
|
||||||
def getAction(self, name):
|
|
||||||
try:
|
|
||||||
self.__lock.acquire()
|
|
||||||
if self.__jails.has_key(name):
|
|
||||||
action = self.__jails[name].getAction()
|
|
||||||
return action
|
|
||||||
else:
|
|
||||||
raise UnknownJailException(name)
|
|
||||||
finally:
|
|
||||||
self.__lock.release()
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns a filter class instance.
|
|
||||||
#
|
|
||||||
# Returns the filter object of the jail <code>name</code>. Raise an
|
|
||||||
# <code>UnknownJailException</code> if the jail does not exist.
|
|
||||||
# @param name The name of the jail
|
|
||||||
|
|
||||||
def getFilter(self, name):
|
|
||||||
try:
|
|
||||||
self.__lock.acquire()
|
|
||||||
if self.__jails.has_key(name):
|
|
||||||
action = self.__jails[name].getFilter()
|
|
||||||
return action
|
|
||||||
else:
|
|
||||||
raise UnknownJailException(name)
|
|
||||||
finally:
|
|
||||||
self.__lock.release()
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the jails.
|
|
||||||
#
|
|
||||||
# Returns a copy of the jails list.
|
|
||||||
|
|
||||||
def getAll(self):
|
|
||||||
try:
|
|
||||||
self.__lock.acquire()
|
|
||||||
return self.__jails.copy()
|
|
||||||
finally:
|
|
||||||
self.__lock.release()
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the size of the jails.
|
|
||||||
#
|
|
||||||
# Returns the number of jails.
|
|
||||||
|
|
||||||
def size(self):
|
|
||||||
try:
|
|
||||||
self.__lock.acquire()
|
|
||||||
return len(self.__jails)
|
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
|
def __getitem__(self, name):
|
||||||
|
try:
|
||||||
|
self.__lock.acquire()
|
||||||
|
return self._jails[name]
|
||||||
|
except KeyError:
|
||||||
|
raise UnknownJailException(name)
|
||||||
|
finally:
|
||||||
|
self.__lock.release()
|
||||||
|
|
||||||
|
def __delitem__(self, name):
|
||||||
|
try:
|
||||||
|
self.__lock.acquire()
|
||||||
|
del self._jails[name]
|
||||||
|
except KeyError:
|
||||||
|
raise UnknownJailException(name)
|
||||||
|
finally:
|
||||||
|
self.__lock.release()
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
try:
|
||||||
|
self.__lock.acquire()
|
||||||
|
return len(self._jails)
|
||||||
|
finally:
|
||||||
|
self.__lock.release()
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
try:
|
||||||
|
self.__lock.acquire()
|
||||||
|
return iter(self._jails)
|
||||||
|
finally:
|
||||||
|
self.__lock.release()
|
||||||
|
|
|
@ -122,10 +122,10 @@ class Server:
|
||||||
def addJail(self, name, backend):
|
def addJail(self, name, backend):
|
||||||
self.__jails.add(name, backend, self.__db)
|
self.__jails.add(name, backend, self.__db)
|
||||||
if self.__db is not None:
|
if self.__db is not None:
|
||||||
self.__db.addJail(self.__jails.get(name))
|
self.__db.addJail(self.__jails[name])
|
||||||
|
|
||||||
def delJail(self, name):
|
def delJail(self, name):
|
||||||
self.__jails.remove(name)
|
del self.__jails[name]
|
||||||
if self.__db is not None:
|
if self.__db is not None:
|
||||||
self.__db.delJailName(name)
|
self.__db.delJailName(name)
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ class Server:
|
||||||
try:
|
try:
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
if not self.isAlive(name):
|
if not self.isAlive(name):
|
||||||
self.__jails.get(name).start()
|
self.__jails[name].start()
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ class Server:
|
||||||
try:
|
try:
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
if self.isAlive(name):
|
if self.isAlive(name):
|
||||||
self.__jails.get(name).stop()
|
self.__jails[name].stop()
|
||||||
self.delJail(name)
|
self.delJail(name)
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
@ -151,43 +151,43 @@ class Server:
|
||||||
logSys.info("Stopping all jails")
|
logSys.info("Stopping all jails")
|
||||||
try:
|
try:
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
for jail in self.__jails.getAll():
|
for jail in self.__jails.keys():
|
||||||
self.stopJail(jail)
|
self.stopJail(jail)
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
def isAlive(self, name):
|
def isAlive(self, name):
|
||||||
return self.__jails.get(name).isAlive()
|
return self.__jails[name].isAlive()
|
||||||
|
|
||||||
def setIdleJail(self, name, value):
|
def setIdleJail(self, name, value):
|
||||||
self.__jails.get(name).setIdle(value)
|
self.__jails[name].setIdle(value)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getIdleJail(self, name):
|
def getIdleJail(self, name):
|
||||||
return self.__jails.get(name).getIdle()
|
return self.__jails[name].getIdle()
|
||||||
|
|
||||||
# Filter
|
# Filter
|
||||||
def addIgnoreIP(self, name, ip):
|
def addIgnoreIP(self, name, ip):
|
||||||
self.__jails.getFilter(name).addIgnoreIP(ip)
|
self.__jails[name].filter.addIgnoreIP(ip)
|
||||||
|
|
||||||
def delIgnoreIP(self, name, ip):
|
def delIgnoreIP(self, name, ip):
|
||||||
self.__jails.getFilter(name).delIgnoreIP(ip)
|
self.__jails[name].filter.delIgnoreIP(ip)
|
||||||
|
|
||||||
def getIgnoreIP(self, name):
|
def getIgnoreIP(self, name):
|
||||||
return self.__jails.getFilter(name).getIgnoreIP()
|
return self.__jails[name].filter.getIgnoreIP()
|
||||||
|
|
||||||
def addLogPath(self, name, fileName, tail=False):
|
def addLogPath(self, name, fileName, tail=False):
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, FileFilter):
|
if isinstance(filter_, FileFilter):
|
||||||
filter_.addLogPath(fileName, tail)
|
filter_.addLogPath(fileName, tail)
|
||||||
|
|
||||||
def delLogPath(self, name, fileName):
|
def delLogPath(self, name, fileName):
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, FileFilter):
|
if isinstance(filter_, FileFilter):
|
||||||
filter_.delLogPath(fileName)
|
filter_.delLogPath(fileName)
|
||||||
|
|
||||||
def getLogPath(self, name):
|
def getLogPath(self, name):
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, FileFilter):
|
if isinstance(filter_, FileFilter):
|
||||||
return [m.getFileName()
|
return [m.getFileName()
|
||||||
for m in filter_.getLogPath()]
|
for m in filter_.getLogPath()]
|
||||||
|
@ -196,17 +196,17 @@ class Server:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def addJournalMatch(self, name, match): # pragma: systemd no cover
|
def addJournalMatch(self, name, match): # pragma: systemd no cover
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, JournalFilter):
|
if isinstance(filter_, JournalFilter):
|
||||||
filter_.addJournalMatch(match)
|
filter_.addJournalMatch(match)
|
||||||
|
|
||||||
def delJournalMatch(self, name, match): # pragma: systemd no cover
|
def delJournalMatch(self, name, match): # pragma: systemd no cover
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, JournalFilter):
|
if isinstance(filter_, JournalFilter):
|
||||||
filter_.delJournalMatch(match)
|
filter_.delJournalMatch(match)
|
||||||
|
|
||||||
def getJournalMatch(self, name): # pragma: systemd no cover
|
def getJournalMatch(self, name): # pragma: systemd no cover
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, JournalFilter):
|
if isinstance(filter_, JournalFilter):
|
||||||
return filter_.getJournalMatch()
|
return filter_.getJournalMatch()
|
||||||
else:
|
else:
|
||||||
|
@ -214,112 +214,109 @@ class Server:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def setLogEncoding(self, name, encoding):
|
def setLogEncoding(self, name, encoding):
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, FileFilter):
|
if isinstance(filter_, FileFilter):
|
||||||
filter_.setLogEncoding(encoding)
|
filter_.setLogEncoding(encoding)
|
||||||
|
|
||||||
def getLogEncoding(self, name):
|
def getLogEncoding(self, name):
|
||||||
filter_ = self.__jails.getFilter(name)
|
filter_ = self.__jails[name].filter
|
||||||
if isinstance(filter_, FileFilter):
|
if isinstance(filter_, FileFilter):
|
||||||
return filter_.getLogEncoding()
|
return filter_.getLogEncoding()
|
||||||
|
|
||||||
def setFindTime(self, name, value):
|
def setFindTime(self, name, value):
|
||||||
self.__jails.getFilter(name).setFindTime(value)
|
self.__jails[name].filter.setFindTime(value)
|
||||||
|
|
||||||
def getFindTime(self, name):
|
def getFindTime(self, name):
|
||||||
return self.__jails.getFilter(name).getFindTime()
|
return self.__jails[name].filter.getFindTime()
|
||||||
|
|
||||||
def setDatePattern(self, name, pattern):
|
def setDatePattern(self, name, pattern):
|
||||||
self.__jails.getFilter(name).setDatePattern(pattern)
|
self.__jails[name].filter.setDatePattern(pattern)
|
||||||
|
|
||||||
def getDatePattern(self, name):
|
def getDatePattern(self, name):
|
||||||
return self.__jails.getFilter(name).getDatePattern()
|
return self.__jails[name].filter.getDatePattern()
|
||||||
|
|
||||||
def setIgnoreCommand(self, name, value):
|
def setIgnoreCommand(self, name, value):
|
||||||
self.__jails.getFilter(name).setIgnoreCommand(value)
|
self.__jails[name].filter.setIgnoreCommand(value)
|
||||||
|
|
||||||
def getIgnoreCommand(self, name):
|
def getIgnoreCommand(self, name):
|
||||||
return self.__jails.getFilter(name).getIgnoreCommand()
|
return self.__jails[name].filter.getIgnoreCommand()
|
||||||
|
|
||||||
def addFailRegex(self, name, value):
|
def addFailRegex(self, name, value):
|
||||||
self.__jails.getFilter(name).addFailRegex(value)
|
self.__jails[name].filter.addFailRegex(value)
|
||||||
|
|
||||||
def delFailRegex(self, name, index):
|
def delFailRegex(self, name, index):
|
||||||
self.__jails.getFilter(name).delFailRegex(index)
|
self.__jails[name].filter.delFailRegex(index)
|
||||||
|
|
||||||
def getFailRegex(self, name):
|
def getFailRegex(self, name):
|
||||||
return self.__jails.getFilter(name).getFailRegex()
|
return self.__jails[name].filter.getFailRegex()
|
||||||
|
|
||||||
def addIgnoreRegex(self, name, value):
|
def addIgnoreRegex(self, name, value):
|
||||||
self.__jails.getFilter(name).addIgnoreRegex(value)
|
self.__jails[name].filter.addIgnoreRegex(value)
|
||||||
|
|
||||||
def delIgnoreRegex(self, name, index):
|
def delIgnoreRegex(self, name, index):
|
||||||
self.__jails.getFilter(name).delIgnoreRegex(index)
|
self.__jails[name].filter.delIgnoreRegex(index)
|
||||||
|
|
||||||
def getIgnoreRegex(self, name):
|
def getIgnoreRegex(self, name):
|
||||||
return self.__jails.getFilter(name).getIgnoreRegex()
|
return self.__jails[name].filter.getIgnoreRegex()
|
||||||
|
|
||||||
def setUseDns(self, name, value):
|
def setUseDns(self, name, value):
|
||||||
self.__jails.getFilter(name).setUseDns(value)
|
self.__jails[name].filter.setUseDns(value)
|
||||||
|
|
||||||
def getUseDns(self, name):
|
def getUseDns(self, name):
|
||||||
return self.__jails.getFilter(name).getUseDns()
|
return self.__jails[name].filter.getUseDns()
|
||||||
|
|
||||||
def setMaxRetry(self, name, value):
|
def setMaxRetry(self, name, value):
|
||||||
self.__jails.getFilter(name).setMaxRetry(value)
|
self.__jails[name].filter.setMaxRetry(value)
|
||||||
|
|
||||||
def getMaxRetry(self, name):
|
def getMaxRetry(self, name):
|
||||||
return self.__jails.getFilter(name).getMaxRetry()
|
return self.__jails[name].filter.getMaxRetry()
|
||||||
|
|
||||||
def setMaxLines(self, name, value):
|
def setMaxLines(self, name, value):
|
||||||
self.__jails.getFilter(name).setMaxLines(value)
|
self.__jails[name].filter.setMaxLines(value)
|
||||||
|
|
||||||
def getMaxLines(self, name):
|
def getMaxLines(self, name):
|
||||||
return self.__jails.getFilter(name).getMaxLines()
|
return self.__jails[name].filter.getMaxLines()
|
||||||
|
|
||||||
# Action
|
# Action
|
||||||
def addAction(self, name, value, *args):
|
def addAction(self, name, value, *args):
|
||||||
self.__jails.getAction(name).addAction(value, *args)
|
self.__jails[name].actions.add(value, *args)
|
||||||
|
|
||||||
def getLastAction(self, name):
|
|
||||||
return self.__jails.getAction(name).getLastAction()
|
|
||||||
|
|
||||||
def getActions(self, name):
|
def getActions(self, name):
|
||||||
return self.__jails.getAction(name).getActions()
|
return self.__jails[name].actions
|
||||||
|
|
||||||
def delAction(self, name, value):
|
def delAction(self, name, value):
|
||||||
self.__jails.getAction(name).delAction(value)
|
del self.__jails[name].actions[value]
|
||||||
|
|
||||||
def getAction(self, name, value):
|
def getAction(self, name, value):
|
||||||
return self.__jails.getAction(name).getAction(value)
|
return self.__jails[name].actions[value]
|
||||||
|
|
||||||
def setBanTime(self, name, value):
|
def setBanTime(self, name, value):
|
||||||
self.__jails.getAction(name).setBanTime(value)
|
self.__jails[name].actions.setBanTime(value)
|
||||||
|
|
||||||
def setBanIP(self, name, value):
|
def setBanIP(self, name, value):
|
||||||
return self.__jails.getFilter(name).addBannedIP(value)
|
return self.__jails[name].filter.addBannedIP(value)
|
||||||
|
|
||||||
def setUnbanIP(self, name, value):
|
def setUnbanIP(self, name, value):
|
||||||
return self.__jails.getAction(name).removeBannedIP(value)
|
self.__jails[name].actions.removeBannedIP(value)
|
||||||
|
|
||||||
def getBanTime(self, name):
|
def getBanTime(self, name):
|
||||||
return self.__jails.getAction(name).getBanTime()
|
return self.__jails[name].actions.getBanTime()
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
def status(self):
|
def status(self):
|
||||||
try:
|
try:
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
jails = list(self.__jails.getAll())
|
jails = list(self.__jails)
|
||||||
jails.sort()
|
jails.sort()
|
||||||
jailList = ", ".join(jails)
|
jailList = ", ".join(jails)
|
||||||
ret = [("Number of jail", self.__jails.size()),
|
ret = [("Number of jail", len(self.__jails)),
|
||||||
("Jail list", jailList)]
|
("Jail list", jailList)]
|
||||||
return ret
|
return ret
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
def statusJail(self, name):
|
def statusJail(self, name):
|
||||||
return self.__jails.get(name).getStatus()
|
return self.__jails[name].getStatus()
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
|
|
||||||
|
@ -447,7 +444,7 @@ class Server:
|
||||||
return "flushed"
|
return "flushed"
|
||||||
|
|
||||||
def setDatabase(self, filename):
|
def setDatabase(self, filename):
|
||||||
if self.__jails.size() == 0:
|
if len(self.__jails) == 0:
|
||||||
if filename.lower() == "none":
|
if filename.lower() == "none":
|
||||||
self.__db = None
|
self.__db = None
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -227,13 +227,14 @@ class Transmitter:
|
||||||
return self.__server.setBanIP(name,value)
|
return self.__server.setBanIP(name,value)
|
||||||
elif command[1] == "unbanip":
|
elif command[1] == "unbanip":
|
||||||
value = command[2]
|
value = command[2]
|
||||||
return self.__server.setUnbanIP(name,value)
|
self.__server.setUnbanIP(name, value)
|
||||||
|
return value
|
||||||
elif command[1] == "addaction":
|
elif command[1] == "addaction":
|
||||||
args = [command[2]]
|
args = [command[2]]
|
||||||
if len(command) > 3:
|
if len(command) > 3:
|
||||||
args.extend([command[3], json.loads(command[4])])
|
args.extend([command[3], json.loads(command[4])])
|
||||||
self.__server.addAction(name, *args)
|
self.__server.addAction(name, *args)
|
||||||
return self.__server.getLastAction(name).actionname
|
return args[0]
|
||||||
elif command[1] == "delaction":
|
elif command[1] == "delaction":
|
||||||
value = command[2]
|
value = command[2]
|
||||||
self.__server.delAction(name, value)
|
self.__server.delAction(name, value)
|
||||||
|
@ -300,10 +301,7 @@ class Transmitter:
|
||||||
elif command[1] == "bantime":
|
elif command[1] == "bantime":
|
||||||
return self.__server.getBanTime(name)
|
return self.__server.getBanTime(name)
|
||||||
elif command[1] == "actions":
|
elif command[1] == "actions":
|
||||||
return [action.actionname
|
return self.__server.getActions(name).keys()
|
||||||
for action in self.__server.getActions(name)]
|
|
||||||
elif command[1] == "addaction":
|
|
||||||
return self.__server.getLastAction(name).actionname
|
|
||||||
elif command[1] == "action":
|
elif command[1] == "action":
|
||||||
actionname = command[2]
|
actionname = command[2]
|
||||||
actionvalue = command[3]
|
actionvalue = command[3]
|
||||||
|
|
|
@ -47,8 +47,8 @@ class ExecuteActions(LogCaptureTestCase):
|
||||||
os.remove(self.__tmpfilename)
|
os.remove(self.__tmpfilename)
|
||||||
|
|
||||||
def defaultActions(self):
|
def defaultActions(self):
|
||||||
self.__actions.addAction('ip')
|
self.__actions.add('ip')
|
||||||
self.__ip = self.__actions.getAction('ip')
|
self.__ip = self.__actions['ip']
|
||||||
self.__ip.actionstart = 'echo ip start 64 >> "%s"' % self.__tmpfilename
|
self.__ip.actionstart = 'echo ip start 64 >> "%s"' % self.__tmpfilename
|
||||||
self.__ip.actionban = 'echo ip ban <ip> >> "%s"' % self.__tmpfilename
|
self.__ip.actionban = 'echo ip ban <ip> >> "%s"' % self.__tmpfilename
|
||||||
self.__ip.actionunban = 'echo ip unban <ip> >> "%s"' % self.__tmpfilename
|
self.__ip.actionunban = 'echo ip unban <ip> >> "%s"' % self.__tmpfilename
|
||||||
|
@ -56,15 +56,15 @@ class ExecuteActions(LogCaptureTestCase):
|
||||||
self.__ip.actionstop = 'echo ip stop >> "%s"' % self.__tmpfilename
|
self.__ip.actionstop = 'echo ip stop >> "%s"' % self.__tmpfilename
|
||||||
|
|
||||||
def testActionsManipulation(self):
|
def testActionsManipulation(self):
|
||||||
self.__actions.addAction('test')
|
self.__actions.add('test')
|
||||||
self.assertTrue(self.__actions.getAction('test'))
|
self.assertTrue(self.__actions['test'])
|
||||||
self.assertTrue(self.__actions.getLastAction())
|
self.assertTrue('test' in self.__actions)
|
||||||
self.assertRaises(KeyError,self.__actions.getAction,*['nonexistant action'])
|
self.assertFalse('nonexistant action' in self.__actions)
|
||||||
self.__actions.addAction('test1')
|
self.__actions.add('test1')
|
||||||
self.__actions.delAction('test')
|
del self.__actions['test']
|
||||||
self.__actions.delAction('test1')
|
del self.__actions['test1']
|
||||||
self.assertRaises(KeyError, self.__actions.getAction, *['test'])
|
self.assertFalse('test' in self.__actions)
|
||||||
self.assertRaises(IndexError,self.__actions.getLastAction)
|
self.assertEqual(len(self.__actions), 0)
|
||||||
|
|
||||||
self.__actions.setBanTime(127)
|
self.__actions.setBanTime(127)
|
||||||
self.assertEqual(self.__actions.getBanTime(),127)
|
self.assertEqual(self.__actions.getBanTime(),127)
|
||||||
|
@ -85,7 +85,7 @@ class ExecuteActions(LogCaptureTestCase):
|
||||||
|
|
||||||
|
|
||||||
def testAddActionPython(self):
|
def testAddActionPython(self):
|
||||||
self.__actions.addAction(
|
self.__actions.add(
|
||||||
"Action", os.path.join(TEST_FILES_DIR, "action.d/action.py"),
|
"Action", os.path.join(TEST_FILES_DIR, "action.d/action.py"),
|
||||||
{'opt1': 'value'})
|
{'opt1': 'value'})
|
||||||
|
|
||||||
|
@ -100,18 +100,18 @@ class ExecuteActions(LogCaptureTestCase):
|
||||||
self.assertTrue(self._is_logged("TestAction action stop"))
|
self.assertTrue(self._is_logged("TestAction action stop"))
|
||||||
|
|
||||||
self.assertRaises(IOError,
|
self.assertRaises(IOError,
|
||||||
self.__actions.addAction, "Action3", "/does/not/exist.py", {})
|
self.__actions.add, "Action3", "/does/not/exist.py", {})
|
||||||
|
|
||||||
# With optional argument
|
# With optional argument
|
||||||
self.__actions.addAction(
|
self.__actions.add(
|
||||||
"Action4", os.path.join(TEST_FILES_DIR, "action.d/action.py"),
|
"Action4", os.path.join(TEST_FILES_DIR, "action.d/action.py"),
|
||||||
{'opt1': 'value', 'opt2': 'value2'})
|
{'opt1': 'value', 'opt2': 'value2'})
|
||||||
# With too many arguments
|
# With too many arguments
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
TypeError, self.__actions.addAction, "Action5",
|
TypeError, self.__actions.add, "Action5",
|
||||||
os.path.join(TEST_FILES_DIR, "action.d/action.py"),
|
os.path.join(TEST_FILES_DIR, "action.d/action.py"),
|
||||||
{'opt1': 'value', 'opt2': 'value2', 'opt3': 'value3'})
|
{'opt1': 'value', 'opt2': 'value2', 'opt3': 'value3'})
|
||||||
# Missing required argument
|
# Missing required argument
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
TypeError, self.__actions.addAction, "Action5",
|
TypeError, self.__actions.add, "Action5",
|
||||||
os.path.join(TEST_FILES_DIR, "action.d/action.py"), {})
|
os.path.join(TEST_FILES_DIR, "action.d/action.py"), {})
|
||||||
|
|
|
@ -3,8 +3,8 @@ from fail2ban.server.action import ActionBase
|
||||||
|
|
||||||
class TestAction(ActionBase):
|
class TestAction(ActionBase):
|
||||||
|
|
||||||
def __init__(self, jail, actionname, opt1, opt2=None):
|
def __init__(self, jail, name, opt1, opt2=None):
|
||||||
super(TestAction, self).__init__(jail, actionname)
|
super(TestAction, self).__init__(jail, name)
|
||||||
self._logSys.debug("%s initialised" % self.__class__.__name__)
|
self._logSys.debug("%s initialised" % self.__class__.__name__)
|
||||||
self.opt1 = opt1
|
self.opt1 = opt1
|
||||||
self.opt2 = opt2
|
self.opt2 = opt2
|
||||||
|
|
|
@ -518,9 +518,6 @@ class Transmitter(TransmitterBase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.transm.proceed(["set", self.jailName, "addaction", action]),
|
self.transm.proceed(["set", self.jailName, "addaction", action]),
|
||||||
(0, action))
|
(0, action))
|
||||||
self.assertEqual(
|
|
||||||
self.transm.proceed(["get", self.jailName, "addaction"]),
|
|
||||||
(0, action))
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.transm.proceed(
|
self.transm.proceed(
|
||||||
["get", self.jailName, "actions"])[1][0],
|
["get", self.jailName, "actions"])[1][0],
|
||||||
|
@ -546,10 +543,6 @@ class Transmitter(TransmitterBase):
|
||||||
self.transm.proceed(
|
self.transm.proceed(
|
||||||
["get", self.jailName, "action", action, "InvalidKey"])[0],
|
["get", self.jailName, "action", action, "InvalidKey"])[0],
|
||||||
1)
|
1)
|
||||||
self.assertEqual(
|
|
||||||
self.transm.proceed(
|
|
||||||
["get", self.jailName, "action", action, "actionname"]),
|
|
||||||
(0, action))
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.transm.proceed(
|
self.transm.proceed(
|
||||||
["set", self.jailName, "action", action, "timeout", "10"]),
|
["set", self.jailName, "action", action, "timeout", "10"]),
|
||||||
|
@ -575,7 +568,7 @@ class Transmitter(TransmitterBase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
sorted(self.transm.proceed(["get", self.jailName,
|
sorted(self.transm.proceed(["get", self.jailName,
|
||||||
"actionproperties", action])[1]),
|
"actionproperties", action])[1]),
|
||||||
['actionname', 'opt1', 'opt2'])
|
['opt1', 'opt2'])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.transm.proceed(["get", self.jailName, "action", action,
|
self.transm.proceed(["get", self.jailName, "action", action,
|
||||||
"opt1"]),
|
"opt1"]),
|
||||||
|
|
Loading…
Reference in New Issue