From 34935acd13672481f136bde9e6ee4eb9244d8b0e Mon Sep 17 00:00:00 2001 From: lostcontrol Date: Sun, 17 Sep 2006 21:59:29 +0000 Subject: [PATCH] - Replaced jails = dict() with a Jails class for better concurrency control - Set umask to 0077 at startup for security reason git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@357 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- MANIFEST | 1 + server/jails.py | 107 ++++++++++++++++++++++++++++++++ server/server.py | 155 +++++++++++++++++++---------------------------- 3 files changed, 170 insertions(+), 93 deletions(-) create mode 100644 server/jails.py diff --git a/MANIFEST b/MANIFEST index 9e1f6e0b..de220d23 100644 --- a/MANIFEST +++ b/MANIFEST @@ -33,6 +33,7 @@ server/transmitter.py server/action.py server/ticket.py server/jail.py +server/jails.py server/__init__.py server/dateepoch.py server/banmanager.py diff --git a/server/jails.py b/server/jails.py new file mode 100644 index 00000000..30d61b48 --- /dev/null +++ b/server/jails.py @@ -0,0 +1,107 @@ +# This file is part of Fail2Ban. +# +# Fail2Ban is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Fail2Ban is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Fail2Ban; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Author: Cyril Jaquier +# +# $Revision: 354 $ + +__author__ = "Cyril Jaquier" +__version__ = "$Revision: 354 $" +__date__ = "$Date: 2006-09-13 23:31:22 +0200 (Wed, 13 Sep 2006) $" +__copyright__ = "Copyright (c) 2004 Cyril Jaquier" +__license__ = "GPL" + + +from jail import Jail +from threading import Lock + +class Jails: + + def __init__(self): + self.lock = Lock() + self.jails = dict() + + def add(self, name): + self.lock.acquire() + if self.jails.has_key(name): + self.lock.release() + raise DuplicateJailException(name) + else: + self.jails[name] = Jail(name) + self.lock.release() + + def remove(self, name): + self.lock.acquire() + if self.jails.has_key(name): + del self.jails[name] + self.lock.release() + else: + self.lock.release() + raise UnknownJailException(name) + + 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() + + 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() + + 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() + + def getAll(self): + try: + self.lock.acquire() + return self.jails.copy() + finally: + self.lock.release() + + def size(self): + try: + self.lock.acquire() + return len(self.jails) + finally: + self.lock.release() + + +class DuplicateJailException(Exception): + pass + +class UnknownJailException(Exception): + pass diff --git a/server/server.py b/server/server.py index 0b39a417..dac4f5e2 100644 --- a/server/server.py +++ b/server/server.py @@ -24,7 +24,7 @@ __date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -from jail import Jail +from jails import Jails from transmitter import Transmitter import locale, logging, logging.handlers, sys, os, signal @@ -34,7 +34,7 @@ logSys = logging.getLogger("fail2ban.server") class Server: def __init__(self, daemon = False): - self.jails = dict() + self.jails = Jails() self.daemon = daemon self.transm = Transmitter(self) self.logLevel = 3 @@ -45,6 +45,8 @@ class Server: def start(self, force): logSys.info("Starting Fail2ban") + # First set the mask to only allow access to owner + os.umask(0077) if self.daemon: ret = self.createDaemon() if ret: @@ -62,185 +64,158 @@ class Server: self.transm.stop() def addJail(self, name): - if self.jails.has_key(name): - raise ServerDuplicateJail(name) - else: - self.jails[name] = Jail(name) + self.jails.add(name) def delJail(self, name): - if self.jails.has_key(name): - del self.jails[name] - else: - raise ServerUnknownJail(name) + self.jails.remove(name) def startJail(self, name): - if self.jails.has_key(name): - self.jails[name].start() - else: - raise ServerUnknownJail(name) + if not self.isActive(name): + self.jails.get(name).start() def stopJail(self, name): - if self.jails.has_key(name): - if self.isActive(name): - self.jails[name].stop() - self.delJail(name) - else: - raise ServerUnknownJail(name) + if self.isActive(name): + self.jails.get(name).stop() + self.delJail(name) def stopAllJail(self): - for jail in self.jails.copy(): + for jail in self.jails.getAll(): self.stopJail(jail) - def getAction(self, name): - if self.jails.has_key(name): - return self.jails[name].getAction() - else: - raise ServerUnknownJail(name) - - def getFilter(self, name): - if self.jails.has_key(name): - return self.jails[name].getFilter() - else: - raise ServerUnknownJail(name) - def isActive(self, name): - if self.jails.has_key(name): - return self.jails[name].isActive() - else: - raise ServerUnknownJail(name) + return self.jails.get(name).isActive() def setIdleJail(self, name, value): - if self.jails.has_key(name): - self.jails[name].setIdle(value) - return True - else: - raise ServerUnknownJail(name) + self.jails.get(name).setIdle(value) + return True def getIdleJail(self, name): - if self.jails.has_key(name): - return self.jails[name].getIdle() - else: - raise ServerUnknownJail(name) + return self.jails.get(name).getIdle() # Filter + def addIgnoreIP(self, name, ip): + self.jails.getFilter(name).addIgnoreIP(ip) + + def delIgnoreIP(self, name, ip): + self.jails.getFilter(name).delIgnoreIP(ip) + + def getIgnoreIP(self, name): + return self.jails.getFilter(name).getIgnoreIP() + def addLogPath(self, name, file): - if self.jails.has_key(name): - self.jails[name].getFilter().addLogPath(file) + self.jails.getFilter(name).addLogPath(file) def delLogPath(self, name, file): - if self.jails.has_key(name): - self.jails[name].getFilter().delLogPath(file) + self.jails.getFilter(name).delLogPath(file) def getLogPath(self, name): - return self.getFilter(name).getLogPath() + return self.jails.getFilter(name).getLogPath() def setTimeRegex(self, name, value): - self.getFilter(name).setTimeRegex(value) + self.jails.getFilter(name).setTimeRegex(value) def getTimeRegex(self, name): - return self.getFilter(name).getTimeRegex() + return self.jails.getFilter(name).getTimeRegex() def setTimePattern(self, name, value): - self.getFilter(name).setTimePattern(value) + self.jails.getFilter(name).setTimePattern(value) def getTimePattern(self, name): - return self.getFilter(name).getTimePattern() + return self.jails.getFilter(name).getTimePattern() def setFindTime(self, name, value): - self.getFilter(name).setFindTime(value) + self.jails.getFilter(name).setFindTime(value) def getFindTime(self): - return self.getFilter(name).getFindTime() + return self.jails.getFilter(name).getFindTime() def setFailRegex(self, name, value): - self.getFilter(name).setFailRegex(value) + self.jails.getFilter(name).setFailRegex(value) def getFailRegex(self, name): - return self.getFilter(name).getFailRegex() + return self.jails.getFilter(name).getFailRegex() def setMaxRetry(self, name, value): - self.getFilter(name).setMaxRetry(value) + self.jails.getFilter(name).setMaxRetry(value) def getMaxRetry(self, name): - return self.getFilter(name).getMaxRetry() + return self.jails.getFilter(name).getMaxRetry() def setMaxTime(self, name, value): - self.getFilter(name).setMaxTime(value) + self.jails.getFilter(name).setMaxTime(value) def getMaxTime(self, name): - return self.getFilter(name).getMaxTime() + return self.jails.getFilter(name).getMaxTime() # Action def addAction(self, name, value): - self.getAction(name).addAction(value) + self.jails.getAction(name).addAction(value) def getLastAction(self, name): - return self.getAction(name).getLastAction() + return self.jails.getAction(name).getLastAction() def delAction(self, name, value): - self.getAction(name).delAction(value) + self.jails.getAction(name).delAction(value) def setCInfo(self, name, action, key, value): - self.getAction(name).getAction(action).setCInfo(key, value) + self.jails.getAction(name).getAction(action).setCInfo(key, value) def getCInfo(self, name, action, key): - return self.getAction(name).getAction(action).getCInfo(key) + return self.jails.getAction(name).getAction(action).getCInfo(key) def delCInfo(self, name, action, key): - self.getAction(name).getAction(action).delCInfo(key) + self.jails.getAction(name).getAction(action).delCInfo(key) def setBanTime(self, name, value): - self.getAction(name).setBanTime(value) + self.jails.getAction(name).setBanTime(value) def getBanTime(self, name): - return self.getAction(name).getBanTime() + return self.jails.getAction(name).getBanTime() def setActionStart(self, name, action, value): - self.getAction(name).getAction(action).setActionStart(value) + self.jails.getAction(name).getAction(action).setActionStart(value) def getActionStart(self, name, action): - return self.getAction(name).getAction(action).getActionStart() + return self.jails.getAction(name).getAction(action).getActionStart() def setActionStop(self, name, action, value): - self.getAction(name).getAction(action).setActionStop(value) + self.jails.getAction(name).getAction(action).setActionStop(value) def getActionStop(self, name, action): - return self.getAction(name).getAction(action).getActionStop() + return self.jails.getAction(name).getAction(action).getActionStop() def setActionCheck(self, name, action, value): - self.getAction(name).getAction(action).setActionCheck(value) + self.jails.getAction(name).getAction(action).setActionCheck(value) def getActionCheck(self, name, action): - return self.getAction(name).getAction(action).getActionCheck() + return self.jails.getAction(name).getAction(action).getActionCheck() def setActionBan(self, name, action, value): - self.getAction(name).getAction(action).setActionBan(value) + self.jails.getAction(name).getAction(action).setActionBan(value) def getActionBan(self, name, action): - return self.getAction(name).getAction(action).getActionBan() + return self.jails.getAction(name).getAction(action).getActionBan() def setActionUnban(self, name, action, value): - self.getAction(name).getAction(action).setActionUnban(value) + self.jails.getAction(name).getAction(action).setActionUnban(value) def getActionUnban(self, name, action): - return self.getAction(name).getAction(action).getActionUnban() + return self.jails.getAction(name).getAction(action).getActionUnban() # Status def status(self): jailList = '' - for jail in self.jails: + for jail in self.jails.getAll(): jailList += jail + ', ' length = len(jailList) if not length == 0: jailList = jailList[:length-2] - ret = [("Number of jail", len(self.jails)), + ret = [("Number of jail", self.jails.size()), ("Jail list", jailList)] return ret def statusJail(self, name): - if self.jails.has_key(name): - return self.jails[name].getStatus() - raise ServerUnknownJail(name) + return self.jails.get(name).getStatus() # Logging @@ -378,11 +353,5 @@ class Server: return True -class ServerDuplicateJail(Exception): - pass - -class ServerUnknownJail(Exception): - pass - class ServerInitializationError(Exception): - pass \ No newline at end of file + pass