diff --git a/fail2ban/server/ipdns.py b/fail2ban/server/ipdns.py index 880e3f30..8109c21a 100644 --- a/fail2ban/server/ipdns.py +++ b/fail2ban/server/ipdns.py @@ -171,7 +171,7 @@ class IPAddr(object): # IP address without CIDR mask if len(s) > 2: raise ValueError("invalid ipstr %r, too many plen representation" % (ipstr,)) - if "." in s[1]: # 255.255.255.0 style mask + if "." in s[1] or ":" in s[1]: # 255.255.255.0 resp. ffff:: style mask s[1] = IPAddr.masktoplen(s[1]) s[1] = long(s[1]) return s @@ -235,7 +235,7 @@ class IPAddr(object): return self.ntoa def __reduce__(self): - """IPAddr pickle-handler, that simple wrap IPAddr to the str + """IPAddr pickle-handler, that simply wraps IPAddr to the str Returns a string as instance to be pickled, because fail2ban-client can't unserialize IPAddr objects @@ -392,17 +392,29 @@ class IPAddr(object): return (self.addr & mask) == net.addr + # Pre-calculated map: addr to maskplen + def __getMaskMap(): + m6 = (1 << 128)-1 + m4 = (1 << 32)-1 + mmap = {m6: 128, m4: 32, 0: 0} + m = 0 + for i in xrange(0, 128): + m |= 1 << i + if i < 32: + mmap[m ^ m4] = 32-1-i + mmap[m ^ m6] = 128-1-i + return mmap + + MAP_ADDR2MASKPLEN = __getMaskMap() + @property def maskplen(self): mplen = 0 if self._maskplen is not None: return self._maskplen - maddr = self._addr - while maddr: - if not (maddr & 0x80000000): - raise ValueError("invalid mask %r, no plen representation" % (str(self),)) - maddr = (maddr << 1) & 0xFFFFFFFFL - mplen += 1 + mplen = IPAddr.MAP_ADDR2MASKPLEN.get(self._addr) + if mplen is None: + raise ValueError("invalid mask %r, no plen representation" % (str(self),)) self._maskplen = mplen return mplen diff --git a/fail2ban/tests/filtertestcase.py b/fail2ban/tests/filtertestcase.py index 5e493f83..1d4db3a2 100644 --- a/fail2ban/tests/filtertestcase.py +++ b/fail2ban/tests/filtertestcase.py @@ -1452,11 +1452,24 @@ class DNSUtilsNetworkTests(unittest.TestCase): self.assertEqual(IPAddr('93.184.0.1', 24).ntoa, '93.184.0.0/24') self.assertEqual(IPAddr('192.168.1.0/255.255.255.128').ntoa, '192.168.1.0/25') + self.assertEqual(IPAddr('93.184.0.1/32').ntoa, '93.184.0.1') + self.assertEqual(IPAddr('93.184.0.1/255.255.255.255').ntoa, '93.184.0.1') + self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8::', 120)), '2606:2800:220:1:248:1893:25c8:0/120') self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8::', 120).ntoa, '2606:2800:220:1:248:1893:25c8:0/120') self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8:0/120')), '2606:2800:220:1:248:1893:25c8:0/120') self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8:0/120').ntoa, '2606:2800:220:1:248:1893:25c8:0/120') + self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::', 25)), '2606:2880::/25') + self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ff80::')), '2606:2880::/25') + self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ffff:ffff:ffff:ffff:ffff:ffff::')), + '2606:28ff:220:1:248:1893:25c8:0/112') + + self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/128')), + '2606:28ff:220:1:248:1893:25c8:0') + self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')), + '2606:28ff:220:1:248:1893:25c8:0') + def testIPAddr_CIDR_Repr(self): self.assertEqual(["127.0.0.0/8", "::/32", "2001:db8::/32"], [IPAddr("127.0.0.0", 8), IPAddr("::1", 32), IPAddr("2001:db8::", 32)] diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py index 90f7aaf2..b79a5652 100644 --- a/fail2ban/tests/servertestcase.py +++ b/fail2ban/tests/servertestcase.py @@ -1021,7 +1021,11 @@ class ServerConfigReaderTests(LogCaptureTestCase): cmd[2] = 'polling' # change log path to test log of jail (to prevent "Permission denied" on /var/logs/ for test-user): elif len(cmd) > 3 and cmd[0] == 'set' and cmd[2] == 'addlogpath': - cmd[3] = os.path.join(TEST_FILES_DIR, 'logs', cmd[1]) + fn = os.path.join(TEST_FILES_DIR, 'logs', cmd[1]) + # fallback to testcase01 if jail has not an own test log-file (currently should be no matter): + if not os.path.exists(fn): # pragma: no cover + fn = os.path.join(TEST_FILES_DIR, 'testcase01.log') + cmd[3] = fn # if fast add dummy regex to prevent too long compile of all regexp (we don't use it in this test at all): elif unittest.F2B.fast and ( len(cmd) > 3 and cmd[0] in ('set', 'multi-set') and cmd[2] == 'addfailregex'