Merge branch '0.10-extend-proto-banned' into 0.10

pull/2814/head
sebres 2020-05-25 15:04:12 +02:00
commit b8e2b77265
8 changed files with 113 additions and 6 deletions

View File

@ -55,6 +55,8 @@ protocol = [
["stop", "stops all jails and terminate the server"],
["unban --all", "unbans all IP addresses (in all jails and database)"],
["unban <IP> ... <IP>", "unbans <IP> (in all jails and database)"],
["banned", "return jails with banned IPs as dictionary"],
["banned <IP> ... <IP>]", "return list(s) of jails where given IP(s) are banned"],
["status", "gets the current status of the server"],
["ping", "tests if the server is alive"],
["echo", "for internal usage, returns back and outputs a given string"],
@ -120,6 +122,8 @@ protocol = [
["set <JAIL> action <ACT> <PROPERTY> <VALUE>", "sets the <VALUE> of <PROPERTY> for the action <ACT> for <JAIL>"],
["set <JAIL> action <ACT> <METHOD>[ <JSONKWARGS>]", "calls the <METHOD> with <JSONKWARGS> for the action <ACT> for <JAIL>"],
['', "JAIL INFORMATION", ""],
["get <JAIL> banned", "return banned IPs of <JAIL>"],
["get <JAIL> banned <IP> ... <IP>]", "return 1 if IP is banned in <JAIL> otherwise 0, or a list of 1/0 for multiple IPs"],
["get <JAIL> logpath", "gets the list of the monitored files for <JAIL>"],
["get <JAIL> logencoding", "gets the encoding of the log files for <JAIL>"],
["get <JAIL> journalmatch", "gets the journal filter match for <JAIL>"],

View File

@ -210,6 +210,14 @@ class Actions(JailThread, Mapping):
def getBanTime(self):
return self.__banManager.getBanTime()
def getBanned(self, ids):
lst = self.__banManager.getBanList()
if not ids:
return lst
if len(ids) == 1:
return 1 if ids[0] in lst else 0
return map(lambda ip: 1 if ip in lst else 0, ids)
def addBannedIP(self, ip):
"""Ban an IP or list of IPs."""
unixTime = MyTime.time()

View File

@ -521,6 +521,32 @@ class Server:
cnt += jail.actions.removeBannedIP(value, ifexists=ifexists)
return cnt
def banned(self, name=None, ids=None):
if name is not None:
# single jail:
jails = [self.__jails[name]]
else:
# in all jails:
jails = self.__jails.values()
# check banned ids:
res = []
if name is None and ids:
for ip in ids:
ret = []
for jail in jails:
if jail.actions.getBanned([ip]):
ret.append(jail.name)
res.append(ret)
else:
for jail in jails:
ret = jail.actions.getBanned(ids)
if name is not None:
return ret
res.append(ret)
else:
res.append({jail.name: ret})
return res
def getBanTime(self, name):
return self.__jails[name].actions.getBanTime()

View File

@ -118,6 +118,9 @@ class Transmitter:
if len(value) == 1 and value[0] == "--all":
return self.__server.setUnbanIP()
return self.__server.setUnbanIP(None, value)
elif name == "banned":
# check IP is banned in all jails:
return self.__server.banned(None, command[1:])
elif name == "echo":
return command[1:]
elif name == "server-status":
@ -424,7 +427,10 @@ class Transmitter:
return None
else:
return db.purgeage
# Filter
# Jail, Filter
elif command[1] == "banned":
# check IP is banned in all jails:
return self.__server.banned(name, command[2:])
elif command[1] == "logpath":
return self.__server.getLogPath(name)
elif command[1] == "logencoding":

View File

@ -37,7 +37,7 @@ from threading import Thread
from ..client import fail2banclient, fail2banserver, fail2bancmdline
from ..client.fail2bancmdline import Fail2banCmdLine
from ..client.fail2banclient import exec_command_line as _exec_client, VisualWait
from ..client.fail2banclient import exec_command_line as _exec_client, CSocket, VisualWait
from ..client.fail2banserver import Fail2banServer, exec_command_line as _exec_server
from .. import protocol
from ..server import server
@ -421,6 +421,14 @@ class Fail2banClientServerBase(LogCaptureTestCase):
self.assertRaises(exitType, self.exec_command_line[0],
(self.exec_command_line[1:] + startparams + args))
def execCmdDirect(self, startparams, *args):
sock = startparams[startparams.index('-s')+1]
s = CSocket(sock)
try:
return s.send(args)
finally:
s.close()
#
# Common tests
#
@ -1007,6 +1015,30 @@ class Fail2banServerTest(Fail2banClientServerBase):
"[test-jail2] Found 192.0.2.3",
"[test-jail2] Ban 192.0.2.3",
all=True)
# test banned command:
self.assertSortedEqual(self.execCmdDirect(startparams,
'banned'), (0, [
{'test-jail1': ['192.0.2.4', '192.0.2.1', '192.0.2.8', '192.0.2.3', '192.0.2.2']},
{'test-jail2': ['192.0.2.4', '192.0.2.9', '192.0.2.8']}
]
))
self.assertSortedEqual(self.execCmdDirect(startparams,
'banned', '192.0.2.1', '192.0.2.4', '192.0.2.222'), (0, [
['test-jail1'], ['test-jail1', 'test-jail2'], []
]
))
self.assertSortedEqual(self.execCmdDirect(startparams,
'get', 'test-jail1', 'banned')[1], [
'192.0.2.4', '192.0.2.1', '192.0.2.8', '192.0.2.3', '192.0.2.2'])
self.assertSortedEqual(self.execCmdDirect(startparams,
'get', 'test-jail2', 'banned')[1], [
'192.0.2.4', '192.0.2.9', '192.0.2.8'])
self.assertEqual(self.execCmdDirect(startparams,
'get', 'test-jail1', 'banned', '192.0.2.3')[1], 1)
self.assertEqual(self.execCmdDirect(startparams,
'get', 'test-jail1', 'banned', '192.0.2.9')[1], 0)
self.assertEqual(self.execCmdDirect(startparams,
'get', 'test-jail1', 'banned', '192.0.2.3', '192.0.2.9')[1], [1, 0])
# rotate logs:
_write_file(test1log, "w+")

View File

@ -390,7 +390,15 @@ class TestsUtilsTest(LogCaptureTestCase):
self.assertSortedEqual(['Z', {'A': ['B', 'C'], 'B': ['E', 'F']}], [{'B': ['F', 'E'], 'A': ['C', 'B']}, 'Z'],
level=-1)
self.assertRaises(AssertionError, lambda: self.assertSortedEqual(
['Z', {'A': ['B', 'C'], 'B': ['E', 'F']}], [{'B': ['F', 'E'], 'A': ['C', 'B']}, 'Z']))
['Z', {'A': ['B', 'C'], 'B': ['E', 'F']}], [{'B': ['F', 'E'], 'A': ['C', 'B']}, 'Z'],
nestedOnly=True))
self.assertSortedEqual(
(0, [['A1'], ['A2', 'A1'], []]),
(0, [['A1'], ['A1', 'A2'], []]),
)
self.assertSortedEqual(list('ABC'), list('CBA'))
self.assertRaises(AssertionError, self.assertSortedEqual, ['ABC'], ['CBA'])
self.assertRaises(AssertionError, self.assertSortedEqual, [['ABC']], [['CBA']])
self._testAssertionErrorRE(r"\['A'\] != \['C', 'B'\]",
self.assertSortedEqual, ['A'], ['C', 'B'])
self._testAssertionErrorRE(r"\['A', 'B'\] != \['B', 'C'\]",

View File

@ -556,7 +556,7 @@ if not hasattr(unittest.TestCase, 'assertDictEqual'):
self.fail(msg)
unittest.TestCase.assertDictEqual = assertDictEqual
def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None):
def assertSortedEqual(self, a, b, level=1, nestedOnly=False, key=repr, msg=None):
"""Compare complex elements (like dict, list or tuple) in sorted order until
level 0 not reached (initial level = -1 meant all levels),
or if nestedOnly set to True and some of the objects still contains nested lists or dicts.
@ -566,6 +566,13 @@ def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None):
if isinstance(v, dict):
return any(isinstance(v, (dict, list, tuple)) for v in v.itervalues())
return any(isinstance(v, (dict, list, tuple)) for v in v)
if nestedOnly:
_nest_sorted = sorted
else:
def _nest_sorted(v, key=key):
if isinstance(v, (set, list, tuple)):
return sorted(list(_nest_sorted(v, key) for v in v), key=key)
return v
# level comparison routine:
def _assertSortedEqual(a, b, level, nestedOnly, key):
# first the lengths:
@ -584,8 +591,8 @@ def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None):
elif v1 != v2:
raise ValueError('%r != %r' % (a, b))
else: # list, tuple, something iterable:
a = sorted(a, key=key)
b = sorted(b, key=key)
a = _nest_sorted(a, key=key)
b = _nest_sorted(b, key=key)
for v1, v2 in zip(a, b):
if isinstance(v1, (dict, list, tuple)) and isinstance(v2, (dict, list, tuple)):
_assertSortedEqual(v1, v2, level-1 if level != 0 else 0, nestedOnly, key)

View File

@ -111,6 +111,14 @@ jails and database)
unbans <IP> (in all jails and
database)
.TP
\fBbanned\fR
return jails with banned IPs as
dictionary
.TP
\fBbanned <IP> ... <IP>]\fR
return list(s) of jails where
given IP(s) are banned
.TP
\fBstatus\fR
gets the current status of the
server
@ -356,6 +364,14 @@ for <JAIL>
.IP
JAIL INFORMATION
.TP
\fBget <JAIL> banned\fR
return banned IPs of <JAIL>
.TP
\fBget <JAIL> banned <IP> ... <IP>]\fR
return 1 if IP is banned in <JAIL>
otherwise 0, or a list of 1/0 for
multiple IPs
.TP
\fBget <JAIL> logpath\fR
gets the list of the monitored
files for <JAIL>