- Added support for several "failregex" and "ignoreregex". This should simplify the configuration files.

- Configuration files are backward-compatible but need to be updated in order to take advantage of this feature.

git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@503 a942ae1a-1317-0410-a47c-b1dcaea8d605
0.x
Cyril Jaquier 2006-12-23 16:31:00 +00:00
parent 34a48157dc
commit 0f31cc0feb
15 changed files with 349 additions and 118 deletions

View File

@ -15,7 +15,8 @@ ver. 0.7.6 (200?/??/??) - ???
- Fixed removal of host in hosts.deny. Thanks to René Berber
- Added new date format (2006-12-21 06:43:20) and Exim4
filter. Thanks to mEDI
- Improved regular expression checking a bit
- Several "failregex" and "ignoreregex" are now accepted.
Creation of rules should be easier now.
ver. 0.7.5 (2006/12/07) - beta
----------

View File

@ -39,6 +39,8 @@ server/dateepoch.py
server/banmanager.py
server/datetemplate.py
server/mytime.py
server/regex.py
server/failregex.py
testcases/banmanagertestcase.py
testcases/failmanagertestcase.py
testcases/clientreadertestcase.py

View File

@ -109,7 +109,18 @@ class Beautifier:
msg = "These IP addresses/networks are ignored:\n"
for ip in response[:-1]:
msg = msg + "|- " + ip + "\n"
msg = msg + "`- " + response[len(response)-1]
msg = msg + "`- " + response[len(response)-1]
elif inC[2] in ("failregex", "addfailregex", "delfailregex",
"ignoreregex", "addignoreregex", "delignoreregex"):
if len(response) == 0:
msg = "No regular expression is defined"
else:
msg = "The following regular expression are defined:\n"
c = 0
for ip in response[:-1]:
msg = msg + "|- [" + str(c) + "]: " + ip + "\n"
c += 1
msg = msg + "`- [" + str(c) + "]: " + response[len(response)-1]
except Exception:
logSys.warn("Beautifier error. Please report the error")
logSys.error("Beautify " + `response` + " with " + `self.__inputCmd` +

View File

@ -67,8 +67,10 @@ class FilterReader(ConfigReader):
elif opt == "timepattern":
stream.append(["set", self.__name, "timepattern", self.__opts[opt]])
elif opt == "failregex":
stream.append(["set", self.__name, "failregex", self.__opts[opt]])
for regex in self.__opts[opt].split('\n'):
stream.append(["set", self.__name, "addfailregex", regex])
elif opt == "ignoreregex":
stream.append(["set", self.__name, "ignoreregex", self.__opts[opt]])
for regex in self.__opts[opt].split('\n'):
stream.append(["set", self.__name, "addignoreregex", regex])
return stream

View File

@ -54,8 +54,10 @@ protocol = [
["set <JAIL> dellogpath <FILE>", "removes <FILE> to the monitoring list of <JAIL>"],
["set <JAIL> timeregex <REGEX>", "sets the regular expression <REGEX> to match the date format for <JAIL>. This will disable the autodetection feature."],
["set <JAIL> timepattern <PATTERN>", "sets the pattern <PATTERN> to match the date format for <JAIL>. This will disable the autodetection feature."],
["set <JAIL> failregex <REGEX>", "sets the regular expression <REGEX> which must match failures for <JAIL>"],
["set <JAIL> ignoreregex <REGEX>", "sets the regular expression <REGEX> which should match pattern to exclude for <JAIL>"],
["set <JAIL> addfailregex <REGEX>", "adds the regular expression <REGEX> which must match failures for <JAIL>"],
["set <JAIL> delfailregex <INDEX>", "removes the regular expression at <INDEX> for failregex"],
["set <JAIL> addignoreregex <REGEX>", "adds the regular expression <REGEX> which should match pattern to exclude for <JAIL>"],
["set <JAIL> delignoreregex <INDEX>", "removes the regular expression at <INDEX> for ignoreregex"],
["set <JAIL> findtime <TIME>", "sets the number of seconds <TIME> for which the filter will look back for <JAIL>"],
["set <JAIL> bantime <TIME>", "sets the number of seconds <TIME> a host will be banned for <JAIL>"],
["set <JAIL> maxretry <RETRY>", "sets the number of failures <RETRY> before banning the host for <JAIL>"],
@ -73,8 +75,8 @@ protocol = [
["get <JAIL> ignoreip", "gets the list of ignored IP addresses for <JAIL>"],
["get <JAIL> timeregex", "gets the regular expression used for the time detection for <JAIL>"],
["get <JAIL> timepattern", "gets the pattern used for the time detection for <JAIL>"],
["get <JAIL> failregex", "gets the regular expression which matches the failures for <JAIL>"],
["get <JAIL> ignoreregex", "gets the regular expression which matches patterns to ignore for <JAIL>"],
["get <JAIL> failregex", "gets the list of regular expressions which matches the failures for <JAIL>"],
["get <JAIL> ignoreregex", "gets the list of regular expressions which matches patterns to ignore for <JAIL>"],
["get <JAIL> findtime", "gets the time for which the filter will look back for failures for <JAIL>"],
["get <JAIL> bantime", "gets the time a host is banned for <JAIL>"],
["get <JAIL> maxretry", "gets the number of failures allowed for <JAIL>"],

View File

@ -33,6 +33,7 @@ sys.path.insert(1, "/usr/lib/fail2ban")
from common.version import version
from server.filter import Filter
from server.regex import RegexException
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.regex")
@ -83,17 +84,17 @@ class Fail2banRegex:
self.dispVersion()
sys.exit(0)
def setRegex(self, value):
print
self.__filter.setFailRegex(value)
def testRegex(self, line):
def testRegex(self, line, regex):
print
try:
logging.getLogger("fail2ban").setLevel(logging.DEBUG)
self.__filter.addFailRegex(regex)
ret = self.__filter.findFailure(line)
print
logging.getLogger("fail2ban").setLevel(logging.CRITICAL)
except RegexException, e:
print e
return False
except IndexError:
print "Sorry, but no <host> found in regex"
return False
@ -156,8 +157,7 @@ if __name__ == "__main__":
regex.dispUsage()
sys.exit(-1)
else:
regex.setRegex(sys.argv[2])
ret = regex.testRegex(sys.argv[1])
ret = regex.testRegex(sys.argv[1], sys.argv[2])
if ret:
sys.exit(0)
else:

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-CLIENT "1" "December 2006" "fail2ban-client v0.7.4-SVN" "User Commands"
.TH FAIL2BAN-CLIENT "1" "December 2006" "fail2ban-client v0.7.5-SVN" "User Commands"
.SH NAME
fail2ban-client \- configure and control the server
.SH SYNOPSIS
.B fail2ban-client
[\fIOPTIONS\fR]... \fI<COMMAND>\fR
.SH DESCRIPTION
Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
Fail2Ban v0.7.5\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.SH OPTIONS
.TP
@ -37,6 +37,8 @@ display this help message
\fB\-V\fR, \fB\-\-version\fR
print the version
.SH COMMAND
.IP
Basic
.TP
\fBstart\fR
starts the server and the jails
@ -54,6 +56,8 @@ server
.TP
\fBping\fR
tests if the server is alive
.IP
Logging
.TP
\fBset loglevel <LEVEL>\fR
sets logging level to <LEVEL>. 0
@ -69,10 +73,24 @@ file
.TP
\fBget logtarget\fR
gets logging target
.IP
Jail control
.TP
\fBadd <JAIL> <BACKEND>\fR
creates <JAIL> using <BACKEND>
.TP
\fBstart <JAIL>\fR
starts the jail <JAIL>
.TP
\fBstop <JAIL>\fR
stops the jail <JAIL>. The jail is
removed
.TP
\fBstatus <JAIL>\fR
gets the current status of <JAIL>
.IP
Jail configuration
.TP
\fBset <JAIL> idle on|off\fR
sets the idle state of <JAIL>
.TP
@ -104,16 +122,24 @@ match the date format for <JAIL>.
This will disable the
autodetection feature.
.TP
\fBset <JAIL> failregex <REGEX>\fR
sets the regular expression
\fBset <JAIL> addfailregex <REGEX>\fR
adds the regular expression
<REGEX> which must match failures
for <JAIL>
.TP
\fBset <JAIL> ignoreregex <REGEX>\fR
sets the regular expression
\fBset <JAIL> delfailregex <INDEX>\fR
removes the regular expression at
<INDEX> for failregex
.TP
\fBset <JAIL> addignoreregex <REGEX>\fR
adds the regular expression
<REGEX> which should match pattern
to exclude for <JAIL>
.TP
\fBset <JAIL> delignoreregex <INDEX>\fR
removes the regular expression at
<INDEX> for ignoreregex
.TP
\fBset <JAIL> findtime <TIME>\fR
sets the number of seconds <TIME>
for which the filter will look
@ -163,6 +189,8 @@ action <ACT> for <JAIL>
\fBset <JAIL> actionunban <ACT> <CMD>\fR
sets the unban command <CMD> of
the action <ACT> for <JAIL>
.IP
Jail information
.TP
\fBget <JAIL> logpath\fR
gets the list of the monitored
@ -181,13 +209,14 @@ gets the pattern used for the time
detection for <JAIL>
.TP
\fBget <JAIL> failregex\fR
gets the regular expression which
matches the failures for <JAIL>
gets the list of regular
expressions which matches the
failures for <JAIL>
.TP
\fBget <JAIL> ignoreregex\fR
gets the regular expression which
matches patterns to ignore for
<JAIL>
gets the list of regular
expressions which matches patterns
to ignore for <JAIL>
.TP
\fBget <JAIL> findtime\fR
gets the time for which the filter
@ -225,16 +254,6 @@ action <ACT> for <JAIL>
\fBget <JAIL> actionunban <ACT>\fR
gets the unban command for the
action <ACT> for <JAIL>
.TP
\fBstart <JAIL>\fR
starts the jail <JAIL>
.TP
\fBstop <JAIL>\fR
stops the jail <JAIL>. The jail is
removed
.TP
\fBstatus <JAIL>\fR
gets the current status of <JAIL>
.SH FILES
\fI/etc/fail2ban/*\fR
.SH AUTHOR

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-REGEX "1" "December 2006" "fail2ban-regex v0.7.4-SVN" "User Commands"
.TH FAIL2BAN-REGEX "1" "December 2006" "fail2ban-regex v0.7.5-SVN" "User Commands"
.SH NAME
fail2ban-regex \- test Fail2ban "failregex" option
.SH SYNOPSIS
.B fail2ban-regex
\fI<logline> <failregex>\fR
.SH DESCRIPTION
Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
Fail2Ban v0.7.5\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
This tools can test and benchmark your regular expressions for the "failregex"

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-SERVER "1" "December 2006" "fail2ban-server v0.7.4-SVN" "User Commands"
.TH FAIL2BAN-SERVER "1" "December 2006" "fail2ban-server v0.7.5-SVN" "User Commands"
.SH NAME
fail2ban-server \- start the server
.SH SYNOPSIS
.B fail2ban-server
[\fIOPTIONS\fR]
.SH DESCRIPTION
Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
Fail2Ban v0.7.5\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
Only use this command for debugging purpose. Start the server with

62
server/failregex.py Normal file
View File

@ -0,0 +1,62 @@
# 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$
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
from regex import Regex, RegexException
##
# Regular expression class.
#
# This class represents a regular expression with its compiled version.
class FailRegex(Regex):
##
# Constructor.
#
# Creates a new object. This method can throw RegexException in order to
# avoid construction of invalid object.
# @param value the regular expression
def __init__(self, value):
# Replace "<HOST>" with default regular expression for host.
regex = value.replace("<HOST>", "(?:::f{4,6}:)?(?P<host>\S+)")
# Initializes the parent.
Regex.__init__(self, regex)
# Check for group "host"
if "host" not in self._regexObj.groupindex:
raise RegexException("No 'host' group in '%s'" % self._regex)
##
# Returns the matched host.
#
# This corresponds to the pattern matched by the named group "host".
# @return the matched host
def getHost(self):
host = self._matchCache.group("host")
if host == None:
raise RegexException("Unexpected error. Please check your regex")
return host

View File

@ -29,8 +29,10 @@ from failticket import FailTicket
from jailthread import JailThread
from datedetector import DateDetector
from mytime import MyTime
from regex import Regex, RegexException
from failregex import FailRegex
import logging, re, sre_constants
import logging, re
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.filter")
@ -61,12 +63,10 @@ class Filter(JailThread):
self.__crtFilename = None
## The log file path.
self.__logPath = []
## The regular expression matching the failure.
self.__failRegex = ''
self.__failRegexObj = None
## The regular expression with expression to ignore.
self.__ignoreRegex = ''
self.__ignoreRegexObj = None
## The regular expression list matching the failures.
self.__failRegex = list()
## The regular expression list with expressions to ignore.
self.__ignoreRegex = list()
## The amount of time to look back.
self.__findTime = 6000
## The ignore IP list.
@ -158,26 +158,26 @@ class Filter(JailThread):
return self.dateDetector.getDefaultPattern()
##
# Set the regular expression which matches the failure.
# Add a regular expression which matches the failure.
#
# The regular expression can also match any other pattern than failures
# and thus can be used for many purporse.
# @param value the regular expression
def setFailRegex(self, value):
def addFailRegex(self, value):
try:
if value.lstrip() == '':
self.__failRegex = value
self.__failRegexObj = None
else:
# Replace "<HOST>" with default regular expression for host.
regex = value.replace("<HOST>", "(?:::f{4,6}:)?(?P<host>\S+)")
self.__failRegex = regex
self.__failRegexObj = re.compile(regex)
logSys.info("Set failregex = %s" % self.__failRegex)
except sre_constants.error:
logSys.error("Unable to compile regular expression " +
self.__failRegex)
regex = FailRegex(value)
self.__failRegex.append(regex)
except RegexException, e:
logSys.error(e)
def delFailRegex(self, index):
try:
del self.__failRegex[index]
except IndexError:
logSys.error("Cannot remove regular expression. Index %d is not "
"valid" % index)
##
# Get the regular expression which matches the failure.
@ -185,25 +185,31 @@ class Filter(JailThread):
# @return the regular expression
def getFailRegex(self):
return self.__failRegex
failRegex = list()
for regex in self.__failRegex:
failRegex.append(regex.getRegex())
return failRegex
##
# Set the regular expression which matches the failure.
# Add the regular expression which matches the failure.
#
# The regular expression can also match any other pattern than failures
# and thus can be used for many purporse.
# @param value the regular expression
def setIgnoreRegex(self, value):
def addIgnoreRegex(self, value):
try:
if value.lstrip() == '':
self.__ignoreRegexObj = None
else:
self.__ignoreRegexObj = re.compile(value)
self.__ignoreRegex = value
logSys.info("Set ignoreregex = %s" % value)
except sre_constants.error:
logSys.error("Unable to compile regular expression " + value)
regex = Regex(value)
self.__ignoreRegex.append(regex)
except RegexException, e:
logSys.error(e)
def delIgnoreRegex(self, index):
try:
del self.__ignoreRegex[index]
except IndexError:
logSys.error("Cannot remove regular expression. Index %d is not "
"valid" % index)
##
# Get the regular expression which matches the failure.
@ -211,7 +217,10 @@ class Filter(JailThread):
# @return the regular expression
def getIgnoreRegex(self):
return self.__ignoreRegex
ignoreRegex = list()
for regex in self.__ignoreRegex:
ignoreRegex.append(regex.getRegex())
return ignoreRegex
##
# Set the time needed to find a failure.
@ -413,43 +422,35 @@ class Filter(JailThread):
def findFailure(self, line):
failList = list()
# Checks if failregex is defined.
if self.__failRegexObj == None:
logSys.error("No failregex is set")
return failList
# Checks if ignoreregex is defined.
if not self.__ignoreRegexObj == None:
match = self.__ignoreRegexObj.search(line)
if match:
# Checks if we must ignore this line.
for ignoreRegex in self.__ignoreRegex:
ignoreRegex.search(line)
if ignoreRegex.hasMatched():
# The ignoreregex matched. Return.
logSys.debug("Ignoring this line")
return failList
match = self.__failRegexObj.search(line)
if match:
# The failregex matched.
date = self.dateDetector.getUnixTime(match.string)
if date == None:
logSys.debug("Found a match but no valid date/time found "
+ "for " + match.string + ". Please contact "
+ "the author in order to get support for "
+ "this format")
else:
try:
matchGroup = match.group("host")
# For strange reasons, match.group can return None with some
# regular expressions. However, these expressions can be
# compiled successfully.
if matchGroup == None:
logSys.error("Unexpected error. Please correct your "
+ "configuration.")
else:
ipMatch = DNSUtils.textToIp(match.group("host"))
# Iterates over all the regular expressions.
for failRegex in self.__failRegex:
failRegex.search(line)
if failRegex.hasMatched():
# The failregex matched.
date = self.dateDetector.getUnixTime(line)
if date == None:
logSys.debug("Found a match but no valid date/time found "
+ "for " + line + ". Please contact the "
+ "author in order to get support for this "
+ "format")
else:
try:
host = failRegex.getHost()
ipMatch = DNSUtils.textToIp(host)
if ipMatch:
for ip in ipMatch:
failList.append([ip, date])
except IndexError:
logSys.error("There is no 'host' group in the rule. " +
"Please correct your configuration.")
# We matched a regex, it is enough to stop.
break
except RegexException, e:
logSys.error(e)
return failList

88
server/regex.py Normal file
View File

@ -0,0 +1,88 @@
# 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$
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import re, sre_constants
##
# Regular expression class.
#
# This class represents a regular expression with its compiled version.
class Regex:
##
# Constructor.
#
# Creates a new object. This method can throw RegexException in order to
# avoid construction of invalid object.
# @param value the regular expression
def __init__(self, regex):
self._matchCache = None
try:
self._regexObj = re.compile(regex)
self._regex = regex
except sre_constants.error:
raise RegexException("Unable to compile regular expression '%s'" %
regex)
##
# Gets the regular expression.
#
# The effective regular expression used is returned.
# @return the regular expression
def getRegex(self):
return self._regex
##
# Searches the regular expression.
#
# Sets an internal cache (match object) in order to avoid searching for
# the pattern again. This method must be called before calling any other
# method of this object.
# @param value the line
def search(self, value):
self._matchCache = self._regexObj.search(value)
##
# Checks if the previous call to search() matched.
#
# @return True if a match was found, False otherwise
def hasMatched(self):
if self._matchCache:
return True
else:
return False
##
# Exception dedicated to the class Regex.
class RegexException(Exception):
pass

View File

@ -165,14 +165,20 @@ class Server:
def getFindTime(self, name):
return self.__jails.getFilter(name).getFindTime()
def setFailRegex(self, name, value):
self.__jails.getFilter(name).setFailRegex(value)
def addFailRegex(self, name, value):
self.__jails.getFilter(name).addFailRegex(value)
def delFailRegex(self, name, index):
self.__jails.getFilter(name).delFailRegex(index)
def getFailRegex(self, name):
return self.__jails.getFilter(name).getFailRegex()
def setIgnoreRegex(self, name, value):
self.__jails.getFilter(name).setIgnoreRegex(value)
def addIgnoreRegex(self, name, value):
self.__jails.getFilter(name).addIgnoreRegex(value)
def delIgnoreRegex(self, name, index):
self.__jails.getFilter(name).delIgnoreRegex(index)
def getIgnoreRegex(self, name):
return self.__jails.getFilter(name).getIgnoreRegex()

View File

@ -143,13 +143,21 @@ class Transmitter:
value = command[2]
self.__server.setTimePattern(name, value)
return self.__server.getTimePattern(name)
elif command[1] == "failregex":
elif command[1] == "addfailregex":
value = command[2]
self.__server.setFailRegex(name, value)
self.__server.addFailRegex(name, value)
return self.__server.getFailRegex(name)
elif command[1] == "ignoreregex":
elif command[1] == "delfailregex":
value = int(command[2])
self.__server.delFailRegex(name, value)
return self.__server.getFailRegex(name)
elif command[1] == "addignoreregex":
value = command[2]
self.__server.setIgnoreRegex(name, value)
self.__server.addIgnoreRegex(name, value)
return self.__server.getIgnoreRegex(name)
elif command[1] == "delignoreregex":
value = int(command[2])
self.__server.delIgnoreRegex(name, value)
return self.__server.getIgnoreRegex(name)
elif command[1] == "findtime":
value = command[2]

View File

@ -99,7 +99,7 @@ class GetFailures(unittest.TestCase):
output = ('193.168.0.128', 3, 1124013599.0)
self.__filter.addLogPath(GetFailures.FILENAME_01)
self.__filter.setFailRegex("(?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)")
self.__filter.addFailRegex("(?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)")
self.__filter.getFailures(GetFailures.FILENAME_01)
@ -116,7 +116,7 @@ class GetFailures(unittest.TestCase):
output = ('141.3.81.106', 4, 1124013539.0)
self.__filter.addLogPath(GetFailures.FILENAME_02)
self.__filter.setFailRegex("Failed .* (?:::f{4,6}:)(?P<host>\S*)")
self.__filter.addFailRegex("Failed .* (?:::f{4,6}:)(?P<host>\S*)")
self.__filter.getFailures(GetFailures.FILENAME_02)
@ -127,13 +127,13 @@ class GetFailures(unittest.TestCase):
ip = ticket.getIP()
found = (ip, attempts, date)
self.assertEqual(found, output)
self.assertEqual(found, output)
def testGetFailures03(self):
output = ('203.162.223.135', 6, 1124013544.0)
self.__filter.addLogPath(GetFailures.FILENAME_03)
self.__filter.setFailRegex("error,relay=(?:::f{4,6}:)?(?P<host>\S*),.*550 User unknown")
self.__filter.addFailRegex("error,relay=(?:::f{4,6}:)?(?P<host>\S*),.*550 User unknown")
self.__filter.getFailures(GetFailures.FILENAME_03)
@ -151,7 +151,7 @@ class GetFailures(unittest.TestCase):
('212.41.96.185', 4, 1124013598.0)]
self.__filter.addLogPath(GetFailures.FILENAME_04)
self.__filter.setFailRegex("Invalid user .* (?P<host>\S*)")
self.__filter.addFailRegex("Invalid user .* (?P<host>\S*)")
self.__filter.getFailures(GetFailures.FILENAME_04)
@ -165,4 +165,33 @@ class GetFailures(unittest.TestCase):
self.assertEqual(found, output[i])
except FailManagerEmpty:
pass
def testGetFailuresMultiRegex(self):
output = ('141.3.81.106', 8, 1124013541.0)
self.__filter.addLogPath(GetFailures.FILENAME_02)
self.__filter.addFailRegex("Failed .* from <HOST>")
self.__filter.addFailRegex("Accepted .* from <HOST>")
self.__filter.getFailures(GetFailures.FILENAME_02)
ticket = self.__filter.failManager.toBan()
attempts = ticket.getAttempt()
date = ticket.getTime()
ip = ticket.getIP()
found = (ip, attempts, date)
self.assertEqual(found, output)
def testGetFailuresIgnoreRegex(self):
output = ('141.3.81.106', 8, 1124013541.0)
self.__filter.addLogPath(GetFailures.FILENAME_02)
self.__filter.addFailRegex("Failed .* from <HOST>")
self.__filter.addFailRegex("Accepted .* from <HOST>")
self.__filter.addIgnoreRegex("for roehl")
self.__filter.getFailures(GetFailures.FILENAME_02)
self.assertRaises(FailManagerEmpty, self.__filter.failManager.toBan)