Merge branch 'differentiate-ip-fid--gh-3217'

pull/3229/head
sebres 2022-02-18 20:20:46 +01:00
commit bc075ea682
17 changed files with 155 additions and 87 deletions

View File

@ -18,6 +18,9 @@ ver. 1.0.1-dev-1 (20??/??/??) - development nightly edition
- due to change of `actioncheck` behavior (gh-488), some actions can be incompatible as regards
the invariant check, if `actionban` or `actionunban` would not throw an error (exit code
different from 0) in case of unsane environment.
- actions that have used tag `<ip>` (instead of `<fid>` or `<F-ID>`) to get failure-ID may become
incompatible, if filter uses IP-related tags (like `<ADDR>` or `<HOST>`) additionally to `<F-ID>`
and the values are different (gh-3217)
### Fixes
* readline fixed to consider interim new-line character as part of code point in multi-byte logs
@ -34,6 +37,8 @@ ver. 1.0.1-dev-1 (20??/??/??) - development nightly edition
* better recognition of log rotation, better performance by reopen: avoid unnecessary seek to begin of file
(and hash calculation)
* file filter reads only complete lines (ended with new-line) now, so waits for end of line (for its completion)
* actions differentiate tags `<ip>` and `<fid>` (`<F-ID>`), if IP-address deviates from ID then the value
of `<ip>` is not equal `<fid>` anymore (gh-3217)
* `action.d/ufw.conf` (gh-3018):
- new option `add` (default `prepend`), can be supplied as `insert 1` for ufw versions before v.0.36 (gh-2331, gh-3018)
- new options `kill-mode` and `kill` to drop established connections of intruder (see action for details, gh-3018)

View File

@ -331,7 +331,7 @@ class Fail2banRegex(object):
fltFile = None
fltOpt = {}
if regextype == 'fail':
if re.search(r'^/{0,3}[\w/_\-.]+(?:\[.*\])?$', value):
if re.search(r'^(?ms)/{0,3}[\w/_\-.]+(?:\[.*\])?$', value):
try:
fltName, fltOpt = extractOptions(value)
if "." in fltName[~5:]:
@ -520,10 +520,14 @@ class Fail2banRegex(object):
def _prepaireOutput(self):
"""Prepares output- and fetch-function corresponding given '--out' option (format)"""
ofmt = self._opts.out
if ofmt in ('id', 'ip'):
if ofmt in ('id', 'fid'):
def _out(ret):
for r in ret:
output(r[1])
elif ofmt == 'ip':
def _out(ret):
for r in ret:
output(r[3].get('ip', r[1]))
elif ofmt == 'msg':
def _out(ret):
for r in ret:

View File

@ -72,8 +72,9 @@ class FilterReader(DefinitionInitConfigReader):
def _fillStream(stream, opts, jailName):
prio0idx = 0
for opt, value in opts.iteritems():
# Do not send a command if the value is not set (empty).
if value is None: continue
if opt in ("failregex", "ignoreregex"):
if value is None: continue
multi = []
for regex in value.split('\n'):
# Do not send a command if the rule is empty.
@ -91,8 +92,6 @@ class FilterReader(DefinitionInitConfigReader):
elif opt in ('datepattern'):
stream.append(["set", jailName, opt, value])
elif opt == 'journalmatch':
# Do not send a command if the match is empty.
if value is None: continue
for match in value.split("\n"):
if match == '': continue
stream.append(

View File

@ -497,7 +497,7 @@ class Actions(JailThread, Mapping):
bTicket = BanTicket.wrap(ticket)
btime = ticket.getBanTime(self.banManager.getBanTime())
ip = bTicket.getIP()
ip = bTicket.getID()
aInfo = self._getActionInfo(bTicket)
reason = {}
if self.banManager.addBanTicket(bTicket, reason=reason):
@ -575,10 +575,10 @@ class Actions(JailThread, Mapping):
Ticket to reban
"""
actions = actions or self._actions
ip = ticket.getIP()
ip = ticket.getID()
aInfo = self._getActionInfo(ticket)
if log:
logSys.notice("[%s] Reban %s%s", self._jail.name, aInfo["ip"], (', action %r' % actions.keys()[0] if len(actions) == 1 else ''))
logSys.notice("[%s] Reban %s%s", self._jail.name, ip, (', action %r' % actions.keys()[0] if len(actions) == 1 else ''))
for name, action in actions.iteritems():
try:
logSys.debug("[%s] action %r: reban %s", self._jail.name, name, ip)
@ -703,10 +703,10 @@ class Actions(JailThread, Mapping):
unbactions = self._actions
else:
unbactions = actions
ip = ticket.getIP()
ip = ticket.getID()
aInfo = self._getActionInfo(ticket)
if log:
logSys.notice("[%s] Unban %s", self._jail.name, aInfo["ip"])
logSys.notice("[%s] Unban %s", self._jail.name, ip)
for name, action in unbactions.iteritems():
try:
logSys.debug("[%s] action %r: unban %s", self._jail.name, name, ip)

View File

@ -599,7 +599,7 @@ class Fail2BanDb(object):
ticket : BanTicket
Ticket of the ban to be added.
"""
ip = str(ticket.getIP())
ip = str(ticket.getID())
try:
del self._bansMergedCache[(ip, jail)]
except KeyError:

View File

@ -553,7 +553,7 @@ class Filter(JailThread):
ticket = None
if isinstance(ip, FailTicket):
ticket = ip
ip = ticket.getIP()
ip = ticket.getID()
elif not isinstance(ip, IPAddr):
ip = IPAddr(ip)
return self._inIgnoreIPList(ip, ticket, log_ignore)
@ -702,10 +702,7 @@ class Filter(JailThread):
"""Processes the line for failures and populates failManager
"""
try:
for element in self.processLine(line, date):
ip = element[1]
unixTime = element[2]
fail = element[3]
for (_, ip, unixTime, fail) in self.processLine(line, date):
logSys.debug("Processing line with time:%s and ip:%s",
unixTime, ip)
# ensure the time is not in the future, e. g. by some estimated (assumed) time:
@ -841,11 +838,9 @@ class Filter(JailThread):
failList = list()
ll = logSys.getEffectiveLevel()
returnRawHost = self.returnRawHost
cidr = IPAddr.CIDR_UNSPEC
if self.__useDns == "raw":
returnRawHost = True
cidr = IPAddr.CIDR_RAW
defcidr = IPAddr.CIDR_UNSPEC
if self.__useDns == "raw" or self.returnRawHost:
defcidr = IPAddr.CIDR_RAW
if self.__lineBufferSize > 1:
self.__lineBuffer.append(tupleLine)
@ -908,7 +903,8 @@ class Filter(JailThread):
if not self.checkAllRegex or self.__lineBufferSize > 1:
self.__lineBuffer, buf = failRegex.getUnmatchedTupleLines(), None
# merge data if multi-line failure:
raw = returnRawHost
cidr = defcidr
raw = (defcidr == IPAddr.CIDR_RAW)
if preGroups:
currFail, fail = fail, preGroups.copy()
fail.update(currFail)
@ -927,49 +923,50 @@ class Filter(JailThread):
# failure-id:
fid = fail.get('fid')
# ip-address or host:
host = fail.get('ip4')
if host is not None:
ip = fail.get('ip4')
if ip is not None:
cidr = int(fail.get('cidr') or IPAddr.FAM_IPv4)
raw = True
else:
host = fail.get('ip6')
if host is not None:
ip = fail.get('ip6')
if ip is not None:
cidr = int(fail.get('cidr') or IPAddr.FAM_IPv6)
raw = True
if host is None:
host = fail.get('dns')
if host is None:
# first try to check we have mlfid case (cache connection id):
if fid is None and mlfid is None:
# if no failure-id also (obscure case, wrong regex), throw error inside getFailID:
fid = failRegex.getFailID()
host = fid
cidr = IPAddr.CIDR_RAW
raw = True
else:
ip = fail.get('dns')
if ip is None:
# first try to check we have mlfid case (cache connection id):
if fid is None and mlfid is None:
# if no failure-id also (obscure case, wrong regex), throw error inside getFailID:
fid = failRegex.getFailID()
ip = fid
raw = True
# if mlfid case (not failure):
if host is None:
if ip is None:
if ll <= 7: logSys.log(7, "No failure-id by mlfid %r in regex %s: %s",
mlfid, failRegexIndex, fail.get('mlfforget', "waiting for identifier"))
fail['mlfpending'] = 1; # mark failure is pending
if not self.checkAllRegex and self.ignorePending: return failList
ips = [None]
fids = [None]
# if raw - add single ip or failure-id,
# otherwise expand host to multiple ips using dns (or ignore it if not valid):
elif raw:
ip = IPAddr(host, cidr)
# check host equal failure-id, if not - failure with complex id:
if fid is not None and fid != host:
ip = IPAddr(fid, IPAddr.CIDR_RAW)
ips = [ip]
# check ip/host equal failure-id, if not - failure with complex id:
if fid is None or fid == ip:
fid = IPAddr(ip, cidr)
else:
fail['ip'] = IPAddr(ip, cidr)
fid = IPAddr(fid, defcidr)
fids = [fid]
# otherwise, try to use dns conversion:
else:
ips = DNSUtils.textToIp(host, self.__useDns)
fids = DNSUtils.textToIp(ip, self.__useDns)
# if checkAllRegex we must make a copy (to be sure next RE doesn't change merged/cached failure):
if self.checkAllRegex and mlfid is not None:
fail = fail.copy()
# append failure with match to the list:
for ip in ips:
failList.append([failRegexIndex, ip, date, fail])
for fid in fids:
failList.append([failRegexIndex, fid, date, fail])
if not self.checkAllRegex:
break
except RegexException as e: # pragma: no cover - unsure if reachable

View File

@ -257,6 +257,8 @@ class IPAddr(object):
FAM_IPv6 = CIDR_RAW - socket.AF_INET6
def __new__(cls, ipstr, cidr=CIDR_UNSPEC):
if cidr == IPAddr.CIDR_UNSPEC and isinstance(ipstr, (tuple, list)):
cidr = IPAddr.CIDR_RAW
if cidr == IPAddr.CIDR_RAW: # don't cache raw
ip = super(IPAddr, cls).__new__(cls)
ip.__init(ipstr, cidr)

View File

@ -295,7 +295,7 @@ class Jail(object):
):
try:
#logSys.debug('restored ticket: %s', ticket)
if self.filter.inIgnoreIPList(ticket.getIP(), log_ignore=True): continue
if self.filter.inIgnoreIPList(ticket.getID(), log_ignore=True): continue
# mark ticked was restored from database - does not put it again into db:
ticket.restored = True
# correct start time / ban time (by the same end of ban):

View File

@ -372,7 +372,7 @@ class ObserverThread(JailThread):
# check jail active :
if not jail.isAlive() or not jail.getBanTimeExtra("increment"):
return
ip = ticket.getIP()
ip = ticket.getID()
unixTime = ticket.getTime()
logSys.debug("[%s] Observer: failure found %s", jail.name, ip)
# increase retry count for known (bad) ip, corresponding banCount of it (one try will count than 2, 3, 5, 9 ...) :
@ -435,7 +435,7 @@ class ObserverThread(JailThread):
if not jail.isAlive() or not jail.database:
return banTime
be = jail.getBanTimeExtra()
ip = ticket.getIP()
ip = ticket.getID()
orgBanTime = banTime
# check ip was already banned (increment time of ban):
try:
@ -474,7 +474,7 @@ class ObserverThread(JailThread):
return
try:
oldbtime = btime
ip = ticket.getIP()
ip = ticket.getID()
logSys.debug("[%s] Observer: ban found %s, %s", jail.name, ip, btime)
# if not permanent and ban time was not set - check time should be increased:
if btime != -1 and ticket.getBanTime() is None:
@ -514,7 +514,7 @@ class ObserverThread(JailThread):
"""
try:
btime = ticket.getBanTime()
ip = ticket.getIP()
ip = ticket.getID()
logSys.debug("[%s] Observer: prolong %s, %s", jail.name, ip, btime)
# prolong ticket via actions that expected this:
jail.actions._prolongBan(ticket)

View File

@ -33,7 +33,7 @@ logSys = getLogger(__name__)
class Ticket(object):
__slots__ = ('_ip', '_flags', '_banCount', '_banTime', '_time', '_data', '_retry', '_lastReset')
__slots__ = ('_id', '_flags', '_banCount', '_banTime', '_time', '_data', '_retry', '_lastReset')
MAX_TIME = 0X7FFFFFFFFFFF ;# 4461763-th year
@ -48,7 +48,7 @@ class Ticket(object):
@param matches (log) lines caused the ticket
"""
self.setIP(ip)
self.setID(ip)
self._flags = 0;
self._banCount = 0;
self._banTime = None;
@ -65,7 +65,7 @@ class Ticket(object):
def __str__(self):
return "%s: ip=%s time=%s bantime=%s bancount=%s #attempts=%d matches=%r" % \
(self.__class__.__name__.split('.')[-1], self._ip, self._time,
(self.__class__.__name__.split('.')[-1], self._id, self._time,
self._banTime, self._banCount,
self._data['failures'], self._data.get('matches', []))
@ -74,7 +74,7 @@ class Ticket(object):
def __eq__(self, other):
try:
return self._ip == other._ip and \
return self._id == other._id and \
round(self._time, 2) == round(other._time, 2) and \
self._data == other._data
except AttributeError:
@ -86,18 +86,17 @@ class Ticket(object):
if v is not None:
setattr(self, n, v)
def setIP(self, value):
def setID(self, value):
# guarantee using IPAddr instead of unicode, str for the IP
if isinstance(value, basestring):
value = IPAddr(value)
self._ip = value
self._id = value
def getID(self):
return self._data.get('fid', self._ip)
return self._id
def getIP(self):
return self._ip
return self._data.get('ip', self._id)
def setTime(self, value):
self._time = value

View File

@ -100,23 +100,23 @@ class AddFailure(unittest.TestCase):
self.assertFalse(self.__banManager._inBanList(ticket))
def testBanTimeIncr(self):
ticket = BanTicket(self.__ticket.getIP(), self.__ticket.getTime())
ticket = BanTicket(self.__ticket.getID(), self.__ticket.getTime())
## increase twice and at end permanent, check time/count increase:
c = 0
for i in (1000, 2000, -1):
self.__banManager.addBanTicket(self.__ticket); c += 1
ticket.setBanTime(i)
self.assertFalse(self.__banManager.addBanTicket(ticket)); # no incr of c (already banned)
self.assertEqual(str(self.__banManager.getTicketByID(ticket.getIP())),
"BanTicket: ip=%s time=%s bantime=%s bancount=%s #attempts=0 matches=[]" % (ticket.getIP(), ticket.getTime(), i, c))
self.assertEqual(str(self.__banManager.getTicketByID(ticket.getID())),
"BanTicket: ip=%s time=%s bantime=%s bancount=%s #attempts=0 matches=[]" % (ticket.getID(), ticket.getTime(), i, c))
## after permanent, it should remain permanent ban time (-1):
self.__banManager.addBanTicket(self.__ticket); c += 1
ticket.setBanTime(-1)
self.assertFalse(self.__banManager.addBanTicket(ticket)); # no incr of c (already banned)
ticket.setBanTime(1000)
self.assertFalse(self.__banManager.addBanTicket(ticket)); # no incr of c (already banned)
self.assertEqual(str(self.__banManager.getTicketByID(ticket.getIP())),
"BanTicket: ip=%s time=%s bantime=%s bancount=%s #attempts=0 matches=[]" % (ticket.getIP(), ticket.getTime(), -1, c))
self.assertEqual(str(self.__banManager.getTicketByID(ticket.getID())),
"BanTicket: ip=%s time=%s bantime=%s bancount=%s #attempts=0 matches=[]" % (ticket.getID(), ticket.getTime(), -1, c))
def testUnban(self):
btime = self.__banManager.getBanTime()

View File

@ -192,7 +192,7 @@ class DatabaseTest(LogCaptureTestCase):
ticket.setAttempt(3)
self.assertEqual(bans[0], ticket)
# second ban found also:
self.assertEqual(bans[1].getIP(), "1.2.3.8")
self.assertEqual(bans[1].getID(), "1.2.3.8")
# updated ?
self.assertEqual(self.db.updateDb(Fail2BanDb.__version__), Fail2BanDb.__version__)
# check current bans (should find 2 tickets after upgrade):
@ -312,7 +312,7 @@ class DatabaseTest(LogCaptureTestCase):
for i, ticket in enumerate(tickets):
DefLogSys.debug('readtickets[%d]: %r', i, readtickets[i].getData())
DefLogSys.debug(' == tickets[%d]: %r', i, ticket.getData())
self.assertEqual(readtickets[i].getIP(), ticket.getIP())
self.assertEqual(readtickets[i].getID(), ticket.getID())
self.assertEqual(len(readtickets[i].getMatches()), len(ticket.getMatches()))
self.pruneLog('[test-phase 2] simulate errors')
@ -354,10 +354,10 @@ class DatabaseTest(LogCaptureTestCase):
def testDelBan(self):
tickets = self._testAdd3Bans()
# delete single IP:
self.db.delBan(self.jail, tickets[0].getIP())
self.db.delBan(self.jail, tickets[0].getID())
self.assertEqual(len(self.db.getBans(jail=self.jail)), 2)
# delete two IPs:
self.db.delBan(self.jail, tickets[1].getIP(), tickets[2].getIP())
self.db.delBan(self.jail, tickets[1].getID(), tickets[2].getID())
self.assertEqual(len(self.db.getBans(jail=self.jail)), 0)
def testFlushBans(self):
@ -398,7 +398,7 @@ class DatabaseTest(LogCaptureTestCase):
# should retrieve 2 matches only, but count of all attempts:
self.db.maxMatches = maxMatches;
ticket = self.db.getBansMerged("127.0.0.1")
self.assertEqual(ticket.getIP(), "127.0.0.1")
self.assertEqual(ticket.getID(), "127.0.0.1")
self.assertEqual(ticket.getAttempt(), len(failures))
self.assertEqual(len(ticket.getMatches()), maxMatches)
self.assertEqual(ticket.getMatches(), matches2find[-maxMatches:])
@ -456,13 +456,13 @@ class DatabaseTest(LogCaptureTestCase):
# All for IP 127.0.0.1
ticket = self.db.getBansMerged("127.0.0.1")
self.assertEqual(ticket.getIP(), "127.0.0.1")
self.assertEqual(ticket.getID(), "127.0.0.1")
self.assertEqual(ticket.getAttempt(), 70)
self.assertEqual(ticket.getMatches(), ["abc\n", "123\n", "ABC\n"])
# All for IP 127.0.0.1 for single jail
ticket = self.db.getBansMerged("127.0.0.1", jail=self.jail)
self.assertEqual(ticket.getIP(), "127.0.0.1")
self.assertEqual(ticket.getID(), "127.0.0.1")
self.assertEqual(ticket.getAttempt(), 30)
self.assertEqual(ticket.getMatches(), ["abc\n", "123\n"])
@ -490,8 +490,8 @@ class DatabaseTest(LogCaptureTestCase):
tickets = self.db.getBansMerged()
self.assertEqual(len(tickets), 2)
self.assertSortedEqual(
list(set(ticket.getIP() for ticket in tickets)),
[ticket.getIP() for ticket in tickets])
list(set(ticket.getID() for ticket in tickets)),
[ticket.getID() for ticket in tickets])
tickets = self.db.getBansMerged(jail=jail2)
self.assertEqual(len(tickets), 1)
@ -510,7 +510,7 @@ class DatabaseTest(LogCaptureTestCase):
tickets = self.db.getCurrentBans(jail=self.jail)
self.assertEqual(len(tickets), 2)
ticket = self.db.getCurrentBans(jail=None, ip="127.0.0.1");
self.assertEqual(ticket.getIP(), "127.0.0.1")
self.assertEqual(ticket.getID(), "127.0.0.1")
# positive case (1 ticket not yet expired):
tickets = self.db.getCurrentBans(jail=self.jail, forbantime=15,

View File

@ -355,23 +355,35 @@ class Fail2banRegexTest(LogCaptureTestCase):
self.assertLogged('kevin')
self.pruneLog()
# multiple id combined to a tuple (id, tuple_id):
self.assertTrue(_test_exec('-o', 'id',
self.assertTrue(_test_exec('-o', 'id', '-d', '{^LN-BEG}EPOCH',
'1591983743.667 192.0.2.1 192.0.2.2',
r'^\s*<F-ID/> <F-TUPLE_ID>\S+</F-TUPLE_ID>'))
self.assertLogged(str(('192.0.2.1', '192.0.2.2')))
self.pruneLog()
# multiple id combined to a tuple, id first - (id, tuple_id_1, tuple_id_2):
self.assertTrue(_test_exec('-o', 'id',
self.assertTrue(_test_exec('-o', 'id', '-d', '{^LN-BEG}EPOCH',
'1591983743.667 left 192.0.2.3 right',
r'^\s*<F-TUPLE_ID_1>\S+</F-TUPLE_ID_1> <F-ID/> <F-TUPLE_ID_2>\S+</F-TUPLE_ID_2>'))
self.assertLogged(str(('192.0.2.3', 'left', 'right')))
self.pruneLog()
# id had higher precedence as ip-address:
self.assertTrue(_test_exec('-o', 'id',
self.assertTrue(_test_exec('-o', 'id', '-d', '{^LN-BEG}EPOCH',
'1591983743.667 left [192.0.2.4]:12345 right',
r'^\s*<F-TUPLE_ID_1>\S+</F-TUPLE_ID_1> <F-ID><ADDR>:<F-PORT/></F-ID> <F-TUPLE_ID_2>\S+</F-TUPLE_ID_2>'))
self.assertLogged(str(('[192.0.2.4]:12345', 'left', 'right')))
self.pruneLog()
# ip is not id anymore (if IP-address deviates from ID):
self.assertTrue(_test_exec('-o', 'ip', '-d', '{^LN-BEG}EPOCH',
'1591983743.667 left [192.0.2.4]:12345 right',
r'^\s*<F-TUPLE_ID_1>\S+</F-TUPLE_ID_1> <F-ID><ADDR>:<F-PORT/></F-ID> <F-TUPLE_ID_2>\S+</F-TUPLE_ID_2>'))
self.assertNotLogged(str(('[192.0.2.4]:12345', 'left', 'right')))
self.assertLogged('192.0.2.4')
self.pruneLog()
self.assertTrue(_test_exec('-o', 'ID:<fid> | IP:<ip>', '-d', '{^LN-BEG}EPOCH',
'1591983743.667 left [192.0.2.4]:12345 right',
r'^\s*<F-TUPLE_ID_1>\S+</F-TUPLE_ID_1> <F-ID><ADDR>:<F-PORT/></F-ID> <F-TUPLE_ID_2>\S+</F-TUPLE_ID_2>'))
self.assertLogged('ID:'+str(('[192.0.2.4]:12345', 'left', 'right'))+' | IP:192.0.2.4')
self.pruneLog()
# row with id :
self.assertTrue(_test_exec('-o', 'row', STR_00, RE_00_ID))
self.assertLogged("['kevin'", "'ip4': '192.0.2.0'", "'fid': 'kevin'", all=True)
@ -393,6 +405,43 @@ class Fail2banRegexTest(LogCaptureTestCase):
self.assertLogged('192.0.2.0, kevin, inet4')
self.pruneLog()
def testStalledIPByNoFailFrmtOutput(self):
opts = (
'-c', CONFIG_DIR,
"-d", r"^(?:%a )?%b %d %H:%M:%S(?:\.%f)?(?: %ExY)?",
)
log = (
'May 27 00:16:33 host sshd[2364]: User root not allowed because account is locked\n'
'May 27 00:16:33 host sshd[2364]: Received disconnect from 192.0.2.76 port 58846:11: Bye Bye [preauth]'
)
_test = lambda *args: _test_exec(*(opts + args))
# with MLFID from prefregex and IP after failure obtained from F-NOFAIL RE:
self.assertTrue(_test('-o', 'IP:<ip>', log, 'sshd'))
self.assertLogged('IP:192.0.2.76')
self.pruneLog()
# test diverse ID/IP constellations:
def _test_variants(flt="sshd", prefix=""):
# with different ID/IP from failregex (ID/User from first, IP from second message):
self.assertTrue(_test('-o', 'ID:"<fid>" | IP:<ip> | U:<F-USER>', log,
flt+'[failregex="'
'^'+prefix+'<F-ID>User <F-USER>\S+</F-USER></F-ID> not allowed\n'
'^'+prefix+'Received disconnect from <ADDR>'
'"]'))
self.assertLogged('ID:"User root" | IP:192.0.2.76 | U:root')
self.pruneLog()
# with different ID/IP from failregex (User from first, ID and IP from second message):
self.assertTrue(_test('-o', 'ID:"<fid>" | IP:<ip> | U:<F-USER>', log,
flt+'[failregex="'
'^'+prefix+'User <F-USER>\S+</F-USER> not allowed\n'
'^'+prefix+'Received disconnect from <F-ID><ADDR> port \d+</F-ID>'
'"]'))
self.assertLogged('ID:"192.0.2.76 port 58846" | IP:192.0.2.76 | U:root')
self.pruneLog()
# first with sshd and prefregex:
_test_variants()
# the same without prefregex and MLFID directly in failregex (no merge with prefregex groups):
_test_variants('common', prefix="\s*\S+ sshd\[<F-MLFID>\d+</F-MLFID>\]:\s+")
def testNoDateTime(self):
# datepattern doesn't match:
self.assertTrue(_test_exec('-d', '{^LN-BEG}EPOCH', '-o', 'Found-ID:<F-ID>', STR_00_NODT, RE_00_ID))

View File

@ -150,8 +150,8 @@ class AddFailure(unittest.TestCase):
self.__failManager.setMaxRetry(5)
#ticket = FailTicket('193.168.0.128', None)
ticket = self.__failManager.toBan()
self.assertEqual(ticket.getIP(), "193.168.0.128")
self.assertTrue(isinstance(ticket.getIP(), (str, IPAddr)))
self.assertEqual(ticket.getID(), "193.168.0.128")
self.assertTrue(isinstance(ticket.getID(), (str, IPAddr)))
# finish with rudimentary tests of the ticket
# verify consistent str
@ -180,9 +180,9 @@ class AddFailure(unittest.TestCase):
def testWindow(self):
self._addDefItems()
ticket = self.__failManager.toBan()
self.assertNotEqual(ticket.getIP(), "100.100.10.10")
self.assertNotEqual(ticket.getID(), "100.100.10.10")
ticket = self.__failManager.toBan()
self.assertNotEqual(ticket.getIP(), "100.100.10.10")
self.assertNotEqual(ticket.getID(), "100.100.10.10")
self.assertRaises(FailManagerEmpty, self.__failManager.toBan)
def testBgService(self):

View File

@ -141,7 +141,7 @@ def _ticket_tuple(ticket):
"""
attempts = ticket.getAttempt()
date = ticket.getTime()
ip = ticket.getIP()
ip = ticket.getID()
matches = ticket.getMatches()
return (ip, attempts, date, matches)
@ -1460,7 +1460,7 @@ def get_monitor_failures_journal_testcase(Filter_): # pragma: systemd no cover
self.assertTrue(ticket)
attempts = ticket.getAttempt()
ip = ticket.getIP()
ip = ticket.getID()
ticket.getMatches()
self.assertEqual(ip, test_ip)
@ -1646,7 +1646,7 @@ def get_monitor_failures_journal_testcase(Filter_): # pragma: systemd no cover
self.waitForTicks(1)
self.waitFailTotal(6, 10)
self.assertTrue(Utils.wait_for(lambda: len(self.jail) == 2, 10))
self.assertSortedEqual([self.jail.getFailTicket().getIP(), self.jail.getFailTicket().getIP()],
self.assertSortedEqual([self.jail.getFailTicket().getID(), self.jail.getFailTicket().getID()],
["192.0.2.1", "192.0.2.2"])
cls = MonitorJournalFailures

View File

@ -367,14 +367,14 @@ class BanTimeIncrDB(LogCaptureTestCase):
# this old ticket should be removed now:
restored_tickets = self.db.getCurrentBans(fromtime=stime, correctBanTime=False)
self.assertEqual(len(restored_tickets), 2)
self.assertEqual(restored_tickets[0].getIP(), ip)
self.assertEqual(restored_tickets[0].getID(), ip)
# purge remove 1st ip
self.db._purgeAge = -48*60*60
self.db.purge()
restored_tickets = self.db.getCurrentBans(fromtime=stime, correctBanTime=False)
self.assertEqual(len(restored_tickets), 1)
self.assertEqual(restored_tickets[0].getIP(), ip+'1')
self.assertEqual(restored_tickets[0].getID(), ip+'1')
# this should purge all bans, bips and logs - nothing should be found now
self.db._purgeAge = -240*60*60

View File

@ -39,6 +39,7 @@ class TicketTests(unittest.TestCase):
# Ticket
t = Ticket('193.168.0.128', tm, matches)
self.assertEqual(t.getID(), '193.168.0.128')
self.assertEqual(t.getIP(), '193.168.0.128')
self.assertEqual(t.getTime(), tm)
self.assertEqual(t.getMatches(), matches2)
@ -65,6 +66,7 @@ class TicketTests(unittest.TestCase):
matches = ['first', 'second']
ft = FailTicket('193.168.0.128', tm, matches)
ft.setBanTime(60*60)
self.assertEqual(ft.getID(), '193.168.0.128')
self.assertEqual(ft.getIP(), '193.168.0.128')
self.assertEqual(ft.getTime(), tm)
self.assertEqual(ft.getMatches(), matches2)
@ -116,6 +118,17 @@ class TicketTests(unittest.TestCase):
self.assertEqual(ft2.getTime(), ft.getTime())
self.assertEqual(ft2.getBanTime(), ft.getBanTime())
def testDiffIDAndIPTicket(self):
tm = MyTime.time()
# different ID (string) and IP:
t = Ticket('123-456-678', tm, data={'ip':'192.0.2.1'})
self.assertEqual(t.getID(), '123-456-678')
self.assertEqual(t.getIP(), '192.0.2.1')
# different ID (tuple) and IP:
t = Ticket(('192.0.2.1', '5000'), tm, data={'ip':'192.0.2.1'})
self.assertEqual(t.getID(), ('192.0.2.1', '5000'))
self.assertEqual(t.getIP(), '192.0.2.1')
def testTicketFlags(self):
flags = ('restored', 'banned')
ticket = Ticket('test', 0)