actions.py

Go to the documentation of this file.
00001 # This file is part of Fail2Ban.
00002 #
00003 # Fail2Ban is free software; you can redistribute it and/or modify
00004 # it under the terms of the GNU General Public License as published by
00005 # the Free Software Foundation; either version 2 of the License, or
00006 # (at your option) any later version.
00007 #
00008 # Fail2Ban is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 # GNU General Public License for more details.
00012 #
00013 # You should have received a copy of the GNU General Public License
00014 # along with Fail2Ban; if not, write to the Free Software
00015 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 
00017 # Author: Cyril Jaquier
00018 # 
00019 # $Revision: 567 $
00020 
00021 __author__ = "Cyril Jaquier"
00022 __version__ = "$Revision: 567 $"
00023 __date__ = "$Date: 2007-03-26 23:17:31 +0200 (Mon, 26 Mar 2007) $"
00024 __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
00025 __license__ = "GPL"
00026 
00027 from banmanager import BanManager
00028 from jailthread import JailThread
00029 from action import Action
00030 from mytime import MyTime
00031 import time, logging
00032 
00033 # Gets the instance of the logger.
00034 logSys = logging.getLogger("fail2ban.actions")
00035 
00036 ##
00037 # Execute commands.
00038 #
00039 # This class reads the failures from the Jail queue and decide if an
00040 # action has to be taken. A BanManager take care of the banned IP
00041 # addresses.
00042 
00043 class Actions(JailThread):
00044     
00045     ##
00046     # Constructor.
00047     #
00048     # Initialize the filter object with default values.
00049     # @param jail the jail object
00050     
00051     def __init__(self, jail):
00052         JailThread.__init__(self)
00053         ## The jail which contains this action.
00054         self.jail = jail
00055         self.__actions = list()
00056         ## The ban manager.
00057         self.__banManager = BanManager()
00058     
00059     ##
00060     # Adds an action.
00061     #
00062     # @param name The action name
00063     
00064     def addAction(self, name):
00065         action = Action(name)
00066         self.__actions.append(action)
00067     
00068     ##
00069     # Removes an action.
00070     #
00071     # @param name The action name
00072     
00073     def delAction(self, name):
00074         for action in self.__actions:
00075             if action.getName() == name:
00076                 self.__actions.remove(action)
00077                 break
00078     
00079     ##
00080     # Returns an action.
00081     #
00082     # Raises a KeyError exception if the action does not exist.
00083     #
00084     # @param name the action name
00085     # @return the action
00086     
00087     def getAction(self, name):
00088         for action in self.__actions:
00089             if action.getName() == name:
00090                 return action
00091         raise KeyError
00092     
00093     ##
00094     # Returns the last defined action.
00095     #
00096     # @return The last defined action.
00097     
00098     def getLastAction(self):
00099         action = self.__actions.pop()
00100         self.__actions.append(action)
00101         return action
00102     
00103     ##
00104     # Set the ban time.
00105     #
00106     # @param value the time
00107     
00108     def setBanTime(self, value):
00109         self.__banManager.setBanTime(value)
00110         logSys.info("Set banTime = %s" % value)
00111     
00112     ##
00113     # Get the ban time.
00114     #
00115     # @return the time
00116     
00117     def getBanTime(self):
00118         return self.__banManager.getBanTime()
00119     
00120     ##
00121     # Main loop.
00122     #
00123     # This function is the main loop of the thread. It checks the Jail
00124     # queue and executes commands when an IP address is banned.
00125     # @return True when the thread exits nicely
00126     
00127     def run(self):
00128         self.setActive(True)
00129         for action in self.__actions:
00130             action.execActionStart()
00131         while self._isActive():
00132             if not self.getIdle():
00133                 #logSys.debug(self.jail.getName() + ": action")
00134                 ret = self.__checkBan()
00135                 if not ret:
00136                     self.__checkUnBan()
00137                     time.sleep(self.getSleepTime())
00138             else:
00139                 time.sleep(self.getSleepTime())
00140         self.__flushBan()
00141         for action in self.__actions:
00142             action.execActionStop()
00143         logSys.debug(self.jail.getName() + ": action terminated")
00144         return True
00145 
00146     ##
00147     # Check for IP address to ban.
00148     #
00149     # Look in the Jail queue for FailTicket. If a ticket is available,
00150     # it executes the "ban" command and add a ticket to the BanManager.
00151     # @return True if an IP address get banned
00152     
00153     def __checkBan(self):
00154         ticket = self.jail.getFailTicket()
00155         if ticket != False:
00156             aInfo = dict()
00157             bTicket = BanManager.createBanTicket(ticket)
00158             aInfo["ip"] = bTicket.getIP()
00159             aInfo["failures"] = bTicket.getAttempt()
00160             aInfo["time"] = bTicket.getTime()
00161             if self.__banManager.addBanTicket(bTicket):
00162                 logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
00163                 for action in self.__actions:
00164                     action.execActionBan(aInfo)
00165                 return True
00166             else:
00167                 logSys.warn("[%s] %s already banned" % (self.jail.getName(), 
00168                                                         aInfo["ip"]))
00169         return False
00170     
00171     ##
00172     # Check for IP address to unban.
00173     #
00174     # Unban IP address which are outdated.
00175     
00176     def __checkUnBan(self):
00177         for ticket in self.__banManager.unBanList(MyTime.time()):
00178             self.__unBan(ticket)
00179     
00180     ##
00181     # Flush the ban list.
00182     #
00183     # Unban all IP address which are still in the banning list.
00184     
00185     def __flushBan(self):
00186         logSys.debug("Flush ban list")
00187         for ticket in self.__banManager.flushBanList():
00188             self.__unBan(ticket)
00189     
00190     ##
00191     # Unbans host corresponding to the ticket.
00192     #
00193     # Executes the actions in order to unban the host given in the
00194     # ticket.
00195     
00196     def __unBan(self, ticket):
00197         aInfo = dict()
00198         aInfo["ip"] = ticket.getIP()
00199         aInfo["failures"] = ticket.getAttempt()
00200         aInfo["time"] = ticket.getTime()
00201         logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
00202         for action in self.__actions:
00203             action.execActionUnban(aInfo)
00204             
00205     
00206     ##
00207     # Get the status of the filter.
00208     #
00209     # Get some informations about the filter state such as the total
00210     # number of failures.
00211     # @return a list with tuple
00212     
00213     def status(self):
00214         ret = [("Currently banned", self.__banManager.size()), 
00215                ("Total banned", self.__banManager.getBanTotal()),
00216                ("IP list", self.__banManager.getBanList())]
00217         return ret
Generated on Sun May 19 03:01:59 2013 for Fail2Ban by  doxygen 1.6.3