diff options
59 files changed, 112 insertions, 0 deletions
diff --git a/config/action.d/badips.py b/config/action.d/badips.py index c2a239f5..a1df00a3 100644 --- a/config/action.d/badips.py +++ b/config/action.d/badips.py @@ -35,6 +35,7 @@ else: from fail2ban.server.actions import ActionBase from fail2ban.version import version as f2bVersion + class BadIPsAction(ActionBase): """Fail2Ban action which reports bans to badips.com, and also blacklist bad IPs listed on badips.com by using another action's diff --git a/config/action.d/smtp.py b/config/action.d/smtp.py index 86857616..2429cf48 100644 --- a/config/action.d/smtp.py +++ b/config/action.d/smtp.py @@ -68,6 +68,7 @@ Matches for %(ip)s for jail %(jailname)s: %(ipjailmatches)s """ + class SMTPAction(ActionBase): """Fail2Ban action which sends emails to inform on jail starting, stopping and bans. diff --git a/fail2ban/__init__.py b/fail2ban/__init__.py index b7906099..cd92dbab 100644 --- a/fail2ban/__init__.py +++ b/fail2ban/__init__.py @@ -37,6 +37,7 @@ Below derived from: logging.NOTICE = logging.INFO + 5 logging.addLevelName(logging.NOTICE, 'NOTICE') + # define a new logger function for notice # this is exactly like existing info, critical, debug...etc def _Logger_notice(self, msg, *args, **kwargs): @@ -53,6 +54,7 @@ def _Logger_notice(self, msg, *args, **kwargs): logging.Logger.notice = _Logger_notice + # define a new root level notice function # this is exactly like existing info, critical, debug...etc def _root_notice(msg, *args, **kwargs): diff --git a/fail2ban/client/actionreader.py b/fail2ban/client/actionreader.py index 8022ecc1..c80b230e 100644 --- a/fail2ban/client/actionreader.py +++ b/fail2ban/client/actionreader.py @@ -32,6 +32,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class ActionReader(DefinitionInitConfigReader): _configOpts = [ diff --git a/fail2ban/client/beautifier.py b/fail2ban/client/beautifier.py index 742cbba6..812fbe65 100644 --- a/fail2ban/client/beautifier.py +++ b/fail2ban/client/beautifier.py @@ -27,6 +27,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + ## # Beautify the output of the client. # diff --git a/fail2ban/client/configparserinc.py b/fail2ban/client/configparserinc.py index 5a3b60eb..7bbc7886 100644 --- a/fail2ban/client/configparserinc.py +++ b/fail2ban/client/configparserinc.py @@ -67,6 +67,7 @@ logLevel = 7 __all__ = ['SafeConfigParserWithIncludes'] + class SafeConfigParserWithIncludes(SafeConfigParser): """ Class adds functionality to SafeConfigParser to handle included diff --git a/fail2ban/client/configreader.py b/fail2ban/client/configreader.py index c0e13460..6a2fa897 100644 --- a/fail2ban/client/configreader.py +++ b/fail2ban/client/configreader.py @@ -34,6 +34,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class ConfigReader(): """Generic config reader class. @@ -136,6 +137,7 @@ class ConfigReader(): return self._cfg.getOptions(*args, **kwargs) return {} + class ConfigReaderUnshared(SafeConfigParserWithIncludes): """Unshared config reader (previously ConfigReader). @@ -237,6 +239,7 @@ class ConfigReaderUnshared(SafeConfigParserWithIncludes): values[option[1]] = option[2] return values + class DefinitionInitConfigReader(ConfigReader): """Config reader for files with options grouped in [Definition] and [Init] sections. diff --git a/fail2ban/client/configurator.py b/fail2ban/client/configurator.py index 8667501c..3b9845b6 100644 --- a/fail2ban/client/configurator.py +++ b/fail2ban/client/configurator.py @@ -31,6 +31,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class Configurator: def __init__(self, force_enable=False, share_config=None): diff --git a/fail2ban/client/csocket.py b/fail2ban/client/csocket.py index 761a17ff..9ac0eff1 100644 --- a/fail2ban/client/csocket.py +++ b/fail2ban/client/csocket.py @@ -36,6 +36,7 @@ else: # python 2.x, string type is equivalent to bytes. EMPTY_BYTES = "" + class CSocket: if sys.version_info >= (3,): diff --git a/fail2ban/client/fail2banreader.py b/fail2ban/client/fail2banreader.py index c2f71d06..9b12bba7 100644 --- a/fail2ban/client/fail2banreader.py +++ b/fail2ban/client/fail2banreader.py @@ -30,6 +30,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class Fail2banReader(ConfigReader): def __init__(self, **kwargs): diff --git a/fail2ban/client/filterreader.py b/fail2ban/client/filterreader.py index 8aae0c85..318c8c9a 100644 --- a/fail2ban/client/filterreader.py +++ b/fail2ban/client/filterreader.py @@ -34,6 +34,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class FilterReader(DefinitionInitConfigReader): _configOpts = [ diff --git a/fail2ban/client/jailreader.py b/fail2ban/client/jailreader.py index f1b1783e..6d0fddfa 100644 --- a/fail2ban/client/jailreader.py +++ b/fail2ban/client/jailreader.py @@ -37,6 +37,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class JailReader(ConfigReader): optionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$") diff --git a/fail2ban/client/jailsreader.py b/fail2ban/client/jailsreader.py index be321f7d..09725ec9 100644 --- a/fail2ban/client/jailsreader.py +++ b/fail2ban/client/jailsreader.py @@ -31,6 +31,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class JailsReader(ConfigReader): def __init__(self, force_enable=False, **kwargs): diff --git a/fail2ban/exceptions.py b/fail2ban/exceptions.py index a7fe5ccc..03936b8e 100644 --- a/fail2ban/exceptions.py +++ b/fail2ban/exceptions.py @@ -23,12 +23,14 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko" __license__ = "GPL" + # # Jails # class DuplicateJailException(Exception): pass + class UnknownJailException(KeyError): pass diff --git a/fail2ban/helpers.py b/fail2ban/helpers.py index cecd3f31..f5c3163a 100644 --- a/fail2ban/helpers.py +++ b/fail2ban/helpers.py @@ -26,11 +26,13 @@ import traceback import re import logging + def formatExceptionInfo(): """ Consistently format exception information """ cla, exc = sys.exc_info()[:2] return (cla.__name__, str(exc)) + # # Following "traceback" functions are adopted from PyMVPA distributed # under MIT/Expat and copyright by PyMVPA developers (i.e. me and @@ -49,6 +51,7 @@ def mbasename(s): base = os.path.basename(os.path.dirname(s)) + '.' + base return base + class TraceBack(object): """Customized traceback to be included in debug messages """ @@ -94,6 +97,7 @@ class TraceBack(object): return sftb + class FormatterWithTraceBack(logging.Formatter): """Custom formatter which expands %(tb) and %(tbc) with tracebacks @@ -108,6 +112,7 @@ class FormatterWithTraceBack(logging.Formatter): record.tbc = record.tb = self._tb() return logging.Formatter.format(self, record) + def getLogger(name): """Get logging.Logger instance with Fail2Ban logger name convention """ @@ -115,6 +120,7 @@ def getLogger(name): name = "fail2ban.%s" % name.rpartition(".")[-1] return logging.getLogger(name) + def excepthook(exctype, value, traceback): """Except hook used to log unhandled exceptions to Fail2Ban log """ diff --git a/fail2ban/protocol.py b/fail2ban/protocol.py index 9218b736..9b690067 100644 --- a/fail2ban/protocol.py +++ b/fail2ban/protocol.py @@ -119,6 +119,7 @@ protocol = [ ["get <JAIL> action <ACT> <PROPERTY>", "gets the value of <PROPERTY> for the action <ACT> for <JAIL>"], ] + ## # Prints the protocol in a "man" format. This is used for the # "-h" output of fail2ban-client. @@ -143,6 +144,7 @@ def printFormatted(): line = ' ' * (INDENT + MARGIN) + n.strip() print line + ## # Prints the protocol in a "mediawiki" format. @@ -159,6 +161,7 @@ def printWiki(): print "| <span style=\"white-space:nowrap;\"><tt>" + m[0] + "</tt></span> || || " + m[1] print "|}" + def __printWikiHeader(section, desc): print print "=== " + section + " ===" diff --git a/fail2ban/server/action.py b/fail2ban/server/action.py index d94f7812..60cb00e4 100644 --- a/fail2ban/server/action.py +++ b/fail2ban/server/action.py @@ -55,6 +55,7 @@ _RETCODE_HINTS = { signame = dict((num, name) for name, num in signal.__dict__.iteritems() if name.startswith("SIG")) + class CallingMap(MutableMapping): """A Mapping type which returns the result of callable values. @@ -100,6 +101,7 @@ class CallingMap(MutableMapping): def copy(self): return self.__class__(self.data.copy()) + class ActionBase(object): """An abstract base class for actions in Fail2Ban. @@ -182,6 +184,7 @@ class ActionBase(object): """ pass + class CommandAction(ActionBase): """A action which executes OS shell commands. diff --git a/fail2ban/server/actions.py b/fail2ban/server/actions.py index 95161290..62fac7c1 100644 --- a/fail2ban/server/actions.py +++ b/fail2ban/server/actions.py @@ -47,6 +47,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class Actions(JailThread, Mapping): """Handles jail actions. diff --git a/fail2ban/server/asyncserver.py b/fail2ban/server/asyncserver.py index 8ca86cfd..4a8bc987 100644 --- a/fail2ban/server/asyncserver.py +++ b/fail2ban/server/asyncserver.py @@ -45,6 +45,7 @@ else: # python 2.x, string type is equivalent to bytes. EMPTY_BYTES = "" + ## # Request handler class. # @@ -92,6 +93,7 @@ class RequestHandler(asynchat.async_chat): logSys.error(traceback.format_exc().splitlines()) self.close() + ## # Asynchronous server class. # @@ -187,6 +189,7 @@ class AsyncServer(asyncore.dispatcher): flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC) + ## # AsyncServerException is used to wrap communication exceptions. diff --git a/fail2ban/server/banmanager.py b/fail2ban/server/banmanager.py index 46e717e0..662666b0 100644 --- a/fail2ban/server/banmanager.py +++ b/fail2ban/server/banmanager.py @@ -33,6 +33,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + ## # Banning Manager. # diff --git a/fail2ban/server/database.py b/fail2ban/server/database.py index e5d60661..bf91188a 100644 --- a/fail2ban/server/database.py +++ b/fail2ban/server/database.py @@ -87,6 +87,7 @@ else: sqlite3.register_adapter(dict, _json_dumps_safe) sqlite3.register_converter("JSON", _json_loads_safe) + def commitandrollback(f): @wraps(f) def wrapper(self, *args, **kwargs): @@ -95,6 +96,7 @@ def commitandrollback(f): return f(self, self._db.cursor(), *args, **kwargs) return wrapper + class Fail2BanDb(object): """Fail2Ban database for storing persistent data. diff --git a/fail2ban/server/datedetector.py b/fail2ban/server/datedetector.py index fe5282fd..95d368b5 100644 --- a/fail2ban/server/datedetector.py +++ b/fail2ban/server/datedetector.py @@ -29,6 +29,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class DateDetector(object): """Manages one or more date templates to find a date within a log line. diff --git a/fail2ban/server/datetemplate.py b/fail2ban/server/datetemplate.py index a5179ed1..bcd17ec1 100644 --- a/fail2ban/server/datetemplate.py +++ b/fail2ban/server/datetemplate.py @@ -154,6 +154,7 @@ class DateEpoch(DateTemplate): return (float(dateMatch.group()), dateMatch) return None + class DatePatternRegex(DateTemplate): """Date template, with regex/pattern @@ -236,6 +237,7 @@ class DatePatternRegex(DateTemplate): if value is not None) return reGroupDictStrptime(groupdict), dateMatch + class DateTai64n(DateTemplate): """A date template which matches TAI64N formate timestamps. diff --git a/fail2ban/server/faildata.py b/fail2ban/server/faildata.py index 91aaa1ee..2dd8d4d8 100644 --- a/fail2ban/server/faildata.py +++ b/fail2ban/server/faildata.py @@ -29,6 +29,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class FailData: def __init__(self): diff --git a/fail2ban/server/failmanager.py b/fail2ban/server/failmanager.py index 58dcd143..37a5fe55 100644 --- a/fail2ban/server/failmanager.py +++ b/fail2ban/server/failmanager.py @@ -34,6 +34,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class FailManager: def __init__(self): @@ -154,5 +155,6 @@ class FailManager: finally: self.__lock.release() + class FailManagerEmpty(Exception): pass diff --git a/fail2ban/server/failregex.py b/fail2ban/server/failregex.py index cbe8ebe3..75e64c46 100644 --- a/fail2ban/server/failregex.py +++ b/fail2ban/server/failregex.py @@ -25,6 +25,7 @@ import re import sre_constants import sys + ## # Regular expression class. # @@ -184,6 +185,7 @@ class Regex: else: return ["".join(line) for line in self._matchedTupleLines] + ## # Exception dedicated to the class Regex. diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index 7b62fa2f..18afb135 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -48,6 +48,7 @@ logSys = getLogger(__name__) # that matches a given regular expression. This class is instantiated by # a Jail object. + class Filter(JailThread): ## @@ -717,6 +718,7 @@ except ImportError: # pragma: no cover import md5 md5sum = md5.new + class FileContainer: def __init__(self, filename, encoding, tail = False): @@ -843,6 +845,7 @@ class JournalFilter(Filter): # pragma: systemd no cover import socket import struct + class DNSUtils: IP_CRE = re.compile("^(?:\d{1,3}\.){3}\d{1,3}$") diff --git a/fail2ban/server/filtergamin.py b/fail2ban/server/filtergamin.py index 66cab6de..1f51744b 100644 --- a/fail2ban/server/filtergamin.py +++ b/fail2ban/server/filtergamin.py @@ -36,6 +36,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + ## # Log reader class. # diff --git a/fail2ban/server/filterpoll.py b/fail2ban/server/filterpoll.py index 2f3f3203..25c3e119 100644 --- a/fail2ban/server/filterpoll.py +++ b/fail2ban/server/filterpoll.py @@ -35,6 +35,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + ## # Log reader class. # diff --git a/fail2ban/server/filterpyinotify.py b/fail2ban/server/filterpyinotify.py index fd1dff9f..100ad233 100644 --- a/fail2ban/server/filterpyinotify.py +++ b/fail2ban/server/filterpyinotify.py @@ -51,6 +51,7 @@ except Exception, e: # Gets the instance of the logger. logSys = getLogger(__name__) + ## # Log reader class. # diff --git a/fail2ban/server/filtersystemd.py b/fail2ban/server/filtersystemd.py index d5c81b0e..d0ebec95 100644 --- a/fail2ban/server/filtersystemd.py +++ b/fail2ban/server/filtersystemd.py @@ -38,6 +38,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + ## # Journal reader class. # diff --git a/fail2ban/server/jail.py b/fail2ban/server/jail.py index 0c570ebb..a866cb51 100644 --- a/fail2ban/server/jail.py +++ b/fail2ban/server/jail.py @@ -32,6 +32,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class Jail: """Fail2Ban jail, which manages a filter and associated actions. diff --git a/fail2ban/server/jailthread.py b/fail2ban/server/jailthread.py index c44c16c1..3897801a 100644 --- a/fail2ban/server/jailthread.py +++ b/fail2ban/server/jailthread.py @@ -30,6 +30,7 @@ from abc import abstractmethod from ..helpers import excepthook + class JailThread(Thread): """Abstract class for threading elements in Fail2Ban. diff --git a/fail2ban/server/mytime.py b/fail2ban/server/mytime.py index 16998e24..166f4796 100644 --- a/fail2ban/server/mytime.py +++ b/fail2ban/server/mytime.py @@ -24,6 +24,7 @@ __license__ = "GPL" import datetime import time + ## # MyTime class. # diff --git a/fail2ban/server/server.py b/fail2ban/server/server.py index 2a24c380..58857986 100644 --- a/fail2ban/server/server.py +++ b/fail2ban/server/server.py @@ -48,6 +48,7 @@ except ImportError: # Dont print error here, as database may not even be used Fail2BanDb = None + class Server: def __init__(self, daemon = False): diff --git a/fail2ban/server/strptime.py b/fail2ban/server/strptime.py index cf02dad5..2e3c051c 100644 --- a/fail2ban/server/strptime.py +++ b/fail2ban/server/strptime.py @@ -28,6 +28,7 @@ locale_time = LocaleTime() timeRE = TimeRE() timeRE['z'] = r"(?P<z>Z|[+-]\d{2}(?::?[0-5]\d)?)" + def reGroupDictStrptime(found_dict): """Return time from dictionary of strptime fields diff --git a/fail2ban/server/ticket.py b/fail2ban/server/ticket.py index 51abdc83..70be06fe 100644 --- a/fail2ban/server/ticket.py +++ b/fail2ban/server/ticket.py @@ -29,6 +29,7 @@ from ..helpers import getLogger # Gets the instance of the logger. logSys = getLogger(__name__) + class Ticket: def __init__(self, ip, time, matches=None): diff --git a/fail2ban/server/transmitter.py b/fail2ban/server/transmitter.py index 565443d2..537cd34d 100644 --- a/fail2ban/server/transmitter.py +++ b/fail2ban/server/transmitter.py @@ -33,6 +33,7 @@ from .. import version # Gets the instance of the logger. logSys = getLogger(__name__) + class Transmitter: ## diff --git a/fail2ban/tests/action_d/test_smtp.py b/fail2ban/tests/action_d/test_smtp.py index 440db55c..35ac2393 100644 --- a/fail2ban/tests/action_d/test_smtp.py +++ b/fail2ban/tests/action_d/test_smtp.py @@ -32,6 +32,7 @@ from ..dummyjail import DummyJail from ..utils import CONFIG_DIR + class TestSMTPServer(smtpd.SMTPServer): def process_message(self, peer, mailfrom, rcpttos, data): @@ -40,6 +41,7 @@ class TestSMTPServer(smtpd.SMTPServer): self.rcpttos = rcpttos self.data = data + class SMTPActionTest(unittest.TestCase): def setUp(self): diff --git a/fail2ban/tests/actionstestcase.py b/fail2ban/tests/actionstestcase.py index 5d73d911..bb295967 100644 --- a/fail2ban/tests/actionstestcase.py +++ b/fail2ban/tests/actionstestcase.py @@ -35,6 +35,7 @@ from .utils import LogCaptureTestCase TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files") + class ExecuteActions(LogCaptureTestCase): def setUp(self): diff --git a/fail2ban/tests/actiontestcase.py b/fail2ban/tests/actiontestcase.py index d2dad6cd..5850309e 100644 --- a/fail2ban/tests/actiontestcase.py +++ b/fail2ban/tests/actiontestcase.py @@ -30,6 +30,7 @@ from ..server.action import CommandAction, CallingMap from .utils import LogCaptureTestCase + class CommandActionTest(LogCaptureTestCase): def setUp(self): diff --git a/fail2ban/tests/banmanagertestcase.py b/fail2ban/tests/banmanagertestcase.py index c4dd42cf..09d2411e 100644 --- a/fail2ban/tests/banmanagertestcase.py +++ b/fail2ban/tests/banmanagertestcase.py @@ -29,6 +29,7 @@ import unittest from ..server.banmanager import BanManager from ..server.ticket import BanTicket + class AddFailure(unittest.TestCase): def setUp(self): """Call before every test case.""" diff --git a/fail2ban/tests/clientreadertestcase.py b/fail2ban/tests/clientreadertestcase.py index 9d9d567f..9275ae14 100644 --- a/fail2ban/tests/clientreadertestcase.py +++ b/fail2ban/tests/clientreadertestcase.py @@ -45,6 +45,7 @@ STOCK = os.path.exists(os.path.join('config','fail2ban.conf')) IMPERFECT_CONFIG = os.path.join(os.path.dirname(__file__), 'config') + class ConfigReaderTest(unittest.TestCase): def setUp(self): @@ -156,6 +157,7 @@ c = d ;in line comment self.assertEqual(self.c.get('DEFAULT', 'b'), 'a') self.assertEqual(self.c.get('DEFAULT', 'c'), 'd') + class JailReaderTest(LogCaptureTestCase): def __init__(self, *args, **kwargs): @@ -355,6 +357,7 @@ class FilterReaderTest(unittest.TestCase): except Exception, e: # pragma: no cover - failed if reachable self.fail('unexpected options after readexplicit: %s' % (e)) + class JailsReaderTestCache(LogCaptureTestCase): def _readWholeConf(self, basedir, force_enable=False, share_config=None): diff --git a/fail2ban/tests/databasetestcase.py b/fail2ban/tests/databasetestcase.py index b6646e41..8834e9fd 100644 --- a/fail2ban/tests/databasetestcase.py +++ b/fail2ban/tests/databasetestcase.py @@ -42,6 +42,7 @@ from .utils import LogCaptureTestCase TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files") + class DatabaseTest(LogCaptureTestCase): def setUp(self): diff --git a/fail2ban/tests/datedetectortestcase.py b/fail2ban/tests/datedetectortestcase.py index c82f92ba..0d758640 100644 --- a/fail2ban/tests/datedetectortestcase.py +++ b/fail2ban/tests/datedetectortestcase.py @@ -32,6 +32,7 @@ from ..server.datedetector import DateDetector from ..server.datetemplate import DateTemplate from .utils import setUpMyTime, tearDownMyTime + class DateDetectorTest(unittest.TestCase): def setUp(self): diff --git a/fail2ban/tests/dummyjail.py b/fail2ban/tests/dummyjail.py index 77ab785e..9b784f77 100644 --- a/fail2ban/tests/dummyjail.py +++ b/fail2ban/tests/dummyjail.py @@ -26,6 +26,7 @@ from threading import Lock from ..server.actions import Actions + class DummyJail(object): """A simple 'jail' to suck in all the tickets generated by Filter's """ diff --git a/fail2ban/tests/failmanagertestcase.py b/fail2ban/tests/failmanagertestcase.py index 1f99d161..5d8ce0dd 100644 --- a/fail2ban/tests/failmanagertestcase.py +++ b/fail2ban/tests/failmanagertestcase.py @@ -29,6 +29,7 @@ import unittest from ..server.failmanager import FailManager, FailManagerEmpty from ..server.ticket import FailTicket + class AddFailure(unittest.TestCase): def setUp(self): diff --git a/fail2ban/tests/files/action.d/action.py b/fail2ban/tests/files/action.d/action.py index 2dd64c3f..16a0a208 100644 --- a/fail2ban/tests/files/action.d/action.py +++ b/fail2ban/tests/files/action.d/action.py @@ -1,6 +1,7 @@ from fail2ban.server.action import ActionBase + class TestAction(ActionBase): def __init__(self, jail, name, opt1, opt2=None): diff --git a/fail2ban/tests/files/action.d/action_checkainfo.py b/fail2ban/tests/files/action.d/action_checkainfo.py index eec9cc85..63dd4f5b 100644 --- a/fail2ban/tests/files/action.d/action_checkainfo.py +++ b/fail2ban/tests/files/action.d/action_checkainfo.py @@ -1,6 +1,7 @@ from fail2ban.server.action import ActionBase + class TestAction(ActionBase): def ban(self, aInfo): diff --git a/fail2ban/tests/files/action.d/action_errors.py b/fail2ban/tests/files/action.d/action_errors.py index 767848c1..a193be16 100644 --- a/fail2ban/tests/files/action.d/action_errors.py +++ b/fail2ban/tests/files/action.d/action_errors.py @@ -1,6 +1,7 @@ from fail2ban.server.action import ActionBase + class TestAction(ActionBase): def __init__(self, jail, name): diff --git a/fail2ban/tests/files/action.d/action_modifyainfo.py b/fail2ban/tests/files/action.d/action_modifyainfo.py index 9fbe1e0b..b003edef 100644 --- a/fail2ban/tests/files/action.d/action_modifyainfo.py +++ b/fail2ban/tests/files/action.d/action_modifyainfo.py @@ -1,6 +1,7 @@ from fail2ban.server.action import ActionBase + class TestAction(ActionBase): def ban(self, aInfo): diff --git a/fail2ban/tests/files/action.d/action_noAction.py b/fail2ban/tests/files/action.d/action_noAction.py index 1aa25e67..0888bf60 100644 --- a/fail2ban/tests/files/action.d/action_noAction.py +++ b/fail2ban/tests/files/action.d/action_noAction.py @@ -1,5 +1,6 @@ from fail2ban.server.action import ActionBase + class TestAction(ActionBase): pass diff --git a/fail2ban/tests/files/config/apache-auth/digest.py b/fail2ban/tests/files/config/apache-auth/digest.py index 020a1272..875ebffe 100755 --- a/fail2ban/tests/files/config/apache-auth/digest.py +++ b/fail2ban/tests/files/config/apache-auth/digest.py @@ -10,6 +10,7 @@ except ImportError: # pragma: no cover import md5 md5sum = md5.new + def auth(v): ha1 = md5sum(username + ':' + realm + ':' + password).hexdigest() @@ -44,6 +45,7 @@ def auth(v): s = requests.Session() return s.send(p) + def preauth(): r = requests.get(host + url) print(r) diff --git a/fail2ban/tests/filtertestcase.py b/fail2ban/tests/filtertestcase.py index de63c317..891b55a6 100644 --- a/fail2ban/tests/filtertestcase.py +++ b/fail2ban/tests/filtertestcase.py @@ -46,6 +46,7 @@ from .dummyjail import DummyJail TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files") + # yoh: per Steven Hiscocks's insight while troubleshooting # https://github.com/fail2ban/fail2ban/issues/103#issuecomment-15542836 # adding a sufficiently large buffer might help to guarantee that @@ -63,6 +64,7 @@ def open(*args): else: return fopen(*args) + def _killfile(f, name): try: f.close() @@ -98,6 +100,7 @@ def _assert_equal_entries(utest, found, output, count=None): srepr = repr utest.assertEqual(srepr(found[3]), srepr(output[3])) + def _ticket_tuple(ticket): """Create a tuple for easy comparison from fail ticket """ @@ -107,6 +110,7 @@ def _ticket_tuple(ticket): matches = ticket.getMatches() return (ip, attempts, date, matches) + def _assert_correct_last_attempt(utest, filter_, output, count=None): """Additional helper to wrap most common test case @@ -120,6 +124,7 @@ def _assert_correct_last_attempt(utest, filter_, output, count=None): _assert_equal_entries(utest, found, output, count) + def _copy_lines_between_files(in_, fout, n=None, skip=0, mode='a', terminal_line=""): """Copy lines from one file to another (which might be already open) @@ -156,6 +161,7 @@ def _copy_lines_between_files(in_, fout, n=None, skip=0, mode='a', terminal_line time.sleep(0.1) return fout + def _copy_lines_to_journal(in_, fields={},n=None, skip=0, terminal_line=""): # pragma: systemd no cover """Copy lines from one file to systemd journal @@ -184,6 +190,7 @@ def _copy_lines_to_journal(in_, fields={},n=None, skip=0, terminal_line=""): # p # Opened earlier, therefore must close it fin.close() + # # Actual tests # @@ -209,6 +216,7 @@ class BasicFilter(unittest.TestCase): ("^%Y-%m-%d-%H%M%S.%f %z", "^Year-Month-Day-24hourMinuteSecond.Microseconds Zone offset")) + class IgnoreIP(LogCaptureTestCase): def setUp(self): @@ -276,6 +284,7 @@ class IgnoreIP(LogCaptureTestCase): self.filter.logIgnoreIp("example.com", False, ignore_source="NOT_LOGGED") self.assertFalse(self._is_logged("[%s] Ignore %s by %s" % (self.jail.name, "example.com", "NOT_LOGGED"))) + class IgnoreIPDNS(IgnoreIP): def testIgnoreIPDNSOK(self): @@ -289,6 +298,7 @@ class IgnoreIPDNS(IgnoreIP): self.assertFalse(self.filter.inIgnoreIPList("128.178.50.11")) self.assertFalse(self.filter.inIgnoreIPList("128.178.50.13")) + class LogFile(LogCaptureTestCase): MISSING = 'testcases/missingLogFile' @@ -303,6 +313,7 @@ class LogFile(LogCaptureTestCase): self.filter = FilterPoll(None) self.assertRaises(IOError, self.filter.addLogPath, LogFile.MISSING) + class LogFileFilterPoll(unittest.TestCase): FILENAME = os.path.join(TEST_FILES_DIR, "testcase01.log") @@ -675,6 +686,7 @@ def get_monitor_failures_testcase(Filter_): % (Filter_.__name__, testclass_name) # 'tempfile') return MonitorFailures + def get_monitor_failures_journal_testcase(Filter_): # pragma: systemd no cover """Generator of TestCase's for journal based filters/backends """ @@ -798,6 +810,7 @@ def get_monitor_failures_journal_testcase(Filter_): # pragma: systemd no cover return MonitorJournalFailures + class GetFailures(unittest.TestCase): FILENAME_01 = os.path.join(TEST_FILES_DIR, "testcase01.log") @@ -987,6 +1000,7 @@ class GetFailures(unittest.TestCase): break self.assertEqual(sorted(foundList), sorted(output)) + class DNSUtilsTests(unittest.TestCase): def testUseDns(self): @@ -1034,6 +1048,7 @@ class DNSUtilsTests(unittest.TestCase): res = DNSUtils.bin2addr(167772160L) self.assertEqual(res, '10.0.0.0') + class JailTests(unittest.TestCase): def testSetBackend_gh83(self): diff --git a/fail2ban/tests/misctestcase.py b/fail2ban/tests/misctestcase.py index 343a0fc1..75f492ec 100644 --- a/fail2ban/tests/misctestcase.py +++ b/fail2ban/tests/misctestcase.py @@ -55,6 +55,7 @@ class HelpersTest(unittest.TestCase): # might be fragile due to ' vs " self.assertEqual(args, "('Very bad', None)") + class SetupTest(unittest.TestCase): def setUp(self): @@ -116,6 +117,7 @@ class SetupTest(unittest.TestCase): os.system("%s %s clean --all >/dev/null 2>&1" % (sys.executable, self.setup)) + class TestsUtilsTest(unittest.TestCase): def testmbasename(self): @@ -176,6 +178,7 @@ class TestsUtilsTest(unittest.TestCase): iso8601 = DatePatternRegex("%Y-%m-%d[T ]%H:%M:%S(?:\.%f)?%z") + class CustomDateFormatsTest(unittest.TestCase): def testIso8601(self): diff --git a/fail2ban/tests/samplestestcase.py b/fail2ban/tests/samplestestcase.py index 4c9cb5da..9e6c0ee7 100644 --- a/fail2ban/tests/samplestestcase.py +++ b/fail2ban/tests/samplestestcase.py @@ -37,6 +37,7 @@ from .utils import setUpMyTime, tearDownMyTime, CONFIG_DIR TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files") + class FilterSamplesRegex(unittest.TestCase): def setUp(self): @@ -58,6 +59,7 @@ class FilterSamplesRegex(unittest.TestCase): >= 10, "Expected more FilterSampleRegexs tests") + def testSampleRegexsFactory(name): def testFilter(self): diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py index f9b92305..57453269 100644 --- a/fail2ban/tests/servertestcase.py +++ b/fail2ban/tests/servertestcase.py @@ -47,6 +47,7 @@ except ImportError: # pragma: no cover TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files") + class TestServer(Server): def setLogLevel(self, *args, **kwargs): pass @@ -54,6 +55,7 @@ class TestServer(Server): def setLogTarget(self, *args, **kwargs): pass + class TransmitterBase(unittest.TestCase): def setUp(self): @@ -146,6 +148,7 @@ class TransmitterBase(unittest.TestCase): self.transm.proceed(["get", jail, cmd]), (0, outValues[n+1:])) + class Transmitter(TransmitterBase): def setUp(self): @@ -760,6 +763,7 @@ class Transmitter(TransmitterBase): ["set", jailName, "deljournalmatch", value]) self.assertTrue(isinstance(result[1], ValueError)) + class TransmitterLogging(TransmitterBase): def setUp(self): @@ -884,6 +888,7 @@ class JailTests(unittest.TestCase): jail = Jail(longname) self.assertEqual(jail.name, longname) + class RegexTests(unittest.TestCase): def testInit(self): @@ -908,10 +913,12 @@ class RegexTests(unittest.TestCase): self.assertTrue(fr.hasMatched()) self.assertRaises(RegexException, fr.getHost) + class _BadThread(JailThread): def run(self): raise RuntimeError('run bad thread exception') + class LoggingTests(LogCaptureTestCase): def testGetF2BLogger(self): diff --git a/fail2ban/tests/sockettestcase.py b/fail2ban/tests/sockettestcase.py index b710fe37..01e72847 100644 --- a/fail2ban/tests/sockettestcase.py +++ b/fail2ban/tests/sockettestcase.py @@ -33,6 +33,7 @@ import unittest from ..server.asyncserver import AsyncServer, AsyncServerException from ..client.csocket import CSocket + class Socket(unittest.TestCase): def setUp(self): diff --git a/fail2ban/tests/utils.py b/fail2ban/tests/utils.py index e1da03ad..bf992024 100644 --- a/fail2ban/tests/utils.py +++ b/fail2ban/tests/utils.py @@ -44,12 +44,15 @@ if not CONFIG_DIR: else: CONFIG_DIR = '/etc/fail2ban' + def mtimesleep(): # no sleep now should be necessary since polling tracks now not only # mtime but also ino and size pass old_TZ = os.environ.get('TZ', None) + + def setUpMyTime(): # Set the time to a fixed, known value # Sun Aug 14 12:00:00 CEST 2005 @@ -58,6 +61,7 @@ def setUpMyTime(): time.tzset() MyTime.setTime(1124013600) + def tearDownMyTime(): os.environ.pop('TZ') if old_TZ: @@ -65,6 +69,7 @@ def tearDownMyTime(): time.tzset() MyTime.myTime = None + def gatherTests(regexps=None, no_network=False): # Import all the test cases here instead of a module level to # avoid circular imports @@ -197,6 +202,7 @@ def gatherTests(regexps=None, no_network=False): return tests + class LogCaptureTestCase(unittest.TestCase): def setUp(self): |