|
|
1ac3f6 |
From e399840e91c766531923c017ffa00bbc01e7bbe6 Mon Sep 17 00:00:00 2001
|
|
|
1ac3f6 |
From: Eric Garver <eric@garver.life>
|
|
|
1ac3f6 |
Date: Fri, 12 Feb 2021 14:23:21 -0500
|
|
|
1ac3f6 |
Subject: [PATCH 35/36] fix(ipset): normalize entries in CIDR notation
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
This will convert things like 10.0.1.0/22 to 10.0.0.0/22. Fix up test
|
|
|
1ac3f6 |
cases in which the error code changed due to this.
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
(cherry picked from commit e4dc44fcfd214b27c718eb4d99d3b137495b9626)
|
|
|
1ac3f6 |
---
|
|
|
1ac3f6 |
src/firewall/client.py | 9 ++++++++-
|
|
|
1ac3f6 |
src/firewall/core/fw_ipset.py | 11 ++++++++++-
|
|
|
1ac3f6 |
src/firewall/core/ipset.py | 13 +++++++++++++
|
|
|
1ac3f6 |
src/firewall/server/config_ipset.py | 10 ++++++++--
|
|
|
1ac3f6 |
src/tests/regression/rhbz1601610.at | 19 +++++++++++++------
|
|
|
1ac3f6 |
5 files changed, 52 insertions(+), 10 deletions(-)
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
diff --git a/src/firewall/client.py b/src/firewall/client.py
|
|
|
1ac3f6 |
index 51bf09c8fad6..aa6bd7cd282b 100644
|
|
|
1ac3f6 |
--- a/src/firewall/client.py
|
|
|
1ac3f6 |
+++ b/src/firewall/client.py
|
|
|
1ac3f6 |
@@ -34,6 +34,7 @@ from firewall.core.base import DEFAULT_ZONE_TARGET, DEFAULT_POLICY_TARGET, DEFAU
|
|
|
1ac3f6 |
from firewall.dbus_utils import dbus_to_python
|
|
|
1ac3f6 |
from firewall.functions import b2u
|
|
|
1ac3f6 |
from firewall.core.rich import Rich_Rule
|
|
|
1ac3f6 |
+from firewall.core.ipset import normalize_ipset_entry
|
|
|
1ac3f6 |
from firewall import errors
|
|
|
1ac3f6 |
from firewall.errors import FirewallError
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
@@ -1616,12 +1617,16 @@ class FirewallClientIPSetSettings(object):
|
|
|
1ac3f6 |
if "timeout" in self.settings[4] and \
|
|
|
1ac3f6 |
self.settings[4]["timeout"] != "0":
|
|
|
1ac3f6 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT)
|
|
|
1ac3f6 |
- self.settings[5] = entries
|
|
|
1ac3f6 |
+ _entries = set()
|
|
|
1ac3f6 |
+ for _entry in dbus_to_python(entries, list):
|
|
|
1ac3f6 |
+ _entries.add(normalize_ipset_entry(_entry))
|
|
|
1ac3f6 |
+ self.settings[5] = list(_entries)
|
|
|
1ac3f6 |
@handle_exceptions
|
|
|
1ac3f6 |
def addEntry(self, entry):
|
|
|
1ac3f6 |
if "timeout" in self.settings[4] and \
|
|
|
1ac3f6 |
self.settings[4]["timeout"] != "0":
|
|
|
1ac3f6 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
if entry not in self.settings[5]:
|
|
|
1ac3f6 |
self.settings[5].append(entry)
|
|
|
1ac3f6 |
else:
|
|
|
1ac3f6 |
@@ -1631,6 +1636,7 @@ class FirewallClientIPSetSettings(object):
|
|
|
1ac3f6 |
if "timeout" in self.settings[4] and \
|
|
|
1ac3f6 |
self.settings[4]["timeout"] != "0":
|
|
|
1ac3f6 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
if entry in self.settings[5]:
|
|
|
1ac3f6 |
self.settings[5].remove(entry)
|
|
|
1ac3f6 |
else:
|
|
|
1ac3f6 |
@@ -1640,6 +1646,7 @@ class FirewallClientIPSetSettings(object):
|
|
|
1ac3f6 |
if "timeout" in self.settings[4] and \
|
|
|
1ac3f6 |
self.settings[4]["timeout"] != "0":
|
|
|
1ac3f6 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
return entry in self.settings[5]
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
# ipset config
|
|
|
1ac3f6 |
diff --git a/src/firewall/core/fw_ipset.py b/src/firewall/core/fw_ipset.py
|
|
|
1ac3f6 |
index 6ebda2d56213..e5348949413c 100644
|
|
|
1ac3f6 |
--- a/src/firewall/core/fw_ipset.py
|
|
|
1ac3f6 |
+++ b/src/firewall/core/fw_ipset.py
|
|
|
1ac3f6 |
@@ -24,7 +24,8 @@
|
|
|
1ac3f6 |
__all__ = [ "FirewallIPSet" ]
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
from firewall.core.logger import log
|
|
|
1ac3f6 |
-from firewall.core.ipset import remove_default_create_options as rm_def_cr_opts
|
|
|
1ac3f6 |
+from firewall.core.ipset import remove_default_create_options as rm_def_cr_opts, \
|
|
|
1ac3f6 |
+ normalize_ipset_entry
|
|
|
1ac3f6 |
from firewall.core.io.ipset import IPSet
|
|
|
1ac3f6 |
from firewall import errors
|
|
|
1ac3f6 |
from firewall.errors import FirewallError
|
|
|
1ac3f6 |
@@ -189,6 +190,7 @@ class FirewallIPSet(object):
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
def add_entry(self, name, entry):
|
|
|
1ac3f6 |
obj = self.get_ipset(name, applied=True)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
IPSet.check_entry(entry, obj.options, obj.type)
|
|
|
1ac3f6 |
if entry in obj.entries:
|
|
|
1ac3f6 |
@@ -208,6 +210,7 @@ class FirewallIPSet(object):
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
def remove_entry(self, name, entry):
|
|
|
1ac3f6 |
obj = self.get_ipset(name, applied=True)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
# no entry check for removal
|
|
|
1ac3f6 |
if entry not in obj.entries:
|
|
|
1ac3f6 |
@@ -226,6 +229,7 @@ class FirewallIPSet(object):
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
def query_entry(self, name, entry):
|
|
|
1ac3f6 |
obj = self.get_ipset(name, applied=True)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
if "timeout" in obj.options and obj.options["timeout"] != "0":
|
|
|
1ac3f6 |
# no entries visible for ipsets with timeout
|
|
|
1ac3f6 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT, name)
|
|
|
1ac3f6 |
@@ -239,6 +243,11 @@ class FirewallIPSet(object):
|
|
|
1ac3f6 |
def set_entries(self, name, entries):
|
|
|
1ac3f6 |
obj = self.get_ipset(name, applied=True)
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
+ _entries = set()
|
|
|
1ac3f6 |
+ for _entry in entries:
|
|
|
1ac3f6 |
+ _entries.add(normalize_ipset_entry(_entry))
|
|
|
1ac3f6 |
+ entries = list(_entries)
|
|
|
1ac3f6 |
+
|
|
|
1ac3f6 |
for entry in entries:
|
|
|
1ac3f6 |
IPSet.check_entry(entry, obj.options, obj.type)
|
|
|
1ac3f6 |
if "timeout" not in obj.options or obj.options["timeout"] == "0":
|
|
|
1ac3f6 |
diff --git a/src/firewall/core/ipset.py b/src/firewall/core/ipset.py
|
|
|
1ac3f6 |
index 0d632143ce13..5bb21856f648 100644
|
|
|
1ac3f6 |
--- a/src/firewall/core/ipset.py
|
|
|
1ac3f6 |
+++ b/src/firewall/core/ipset.py
|
|
|
1ac3f6 |
@@ -24,6 +24,7 @@
|
|
|
1ac3f6 |
__all__ = [ "ipset", "check_ipset_name", "remove_default_create_options" ]
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
import os.path
|
|
|
1ac3f6 |
+import ipaddress
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
from firewall import errors
|
|
|
1ac3f6 |
from firewall.errors import FirewallError
|
|
|
1ac3f6 |
@@ -289,3 +290,15 @@ def remove_default_create_options(options):
|
|
|
1ac3f6 |
IPSET_DEFAULT_CREATE_OPTIONS[opt] == _options[opt]:
|
|
|
1ac3f6 |
del _options[opt]
|
|
|
1ac3f6 |
return _options
|
|
|
1ac3f6 |
+
|
|
|
1ac3f6 |
+def normalize_ipset_entry(entry):
|
|
|
1ac3f6 |
+ """ Normalize IP addresses in entry """
|
|
|
1ac3f6 |
+ _entry = []
|
|
|
1ac3f6 |
+ for _part in entry.split(","):
|
|
|
1ac3f6 |
+ try:
|
|
|
1ac3f6 |
+ _part.index("/")
|
|
|
1ac3f6 |
+ _entry.append(str(ipaddress.ip_network(_part, strict=False)))
|
|
|
1ac3f6 |
+ except ValueError:
|
|
|
1ac3f6 |
+ _entry.append(_part)
|
|
|
1ac3f6 |
+
|
|
|
1ac3f6 |
+ return ",".join(_entry)
|
|
|
1ac3f6 |
diff --git a/src/firewall/server/config_ipset.py b/src/firewall/server/config_ipset.py
|
|
|
1ac3f6 |
index 8c647bc29ab9..18ef5783de62 100644
|
|
|
1ac3f6 |
--- a/src/firewall/server/config_ipset.py
|
|
|
1ac3f6 |
+++ b/src/firewall/server/config_ipset.py
|
|
|
1ac3f6 |
@@ -33,7 +33,7 @@ from firewall.dbus_utils import dbus_to_python, \
|
|
|
1ac3f6 |
dbus_introspection_prepare_properties, \
|
|
|
1ac3f6 |
dbus_introspection_add_properties
|
|
|
1ac3f6 |
from firewall.core.io.ipset import IPSet
|
|
|
1ac3f6 |
-from firewall.core.ipset import IPSET_TYPES
|
|
|
1ac3f6 |
+from firewall.core.ipset import IPSET_TYPES, normalize_ipset_entry
|
|
|
1ac3f6 |
from firewall.core.logger import log
|
|
|
1ac3f6 |
from firewall.server.decorators import handle_exceptions, \
|
|
|
1ac3f6 |
dbus_handle_exceptions, dbus_service_method
|
|
|
1ac3f6 |
@@ -406,7 +406,10 @@ class FirewallDConfigIPSet(slip.dbus.service.Object):
|
|
|
1ac3f6 |
in_signature='as')
|
|
|
1ac3f6 |
@dbus_handle_exceptions
|
|
|
1ac3f6 |
def setEntries(self, entries, sender=None):
|
|
|
1ac3f6 |
- entries = dbus_to_python(entries, list)
|
|
|
1ac3f6 |
+ _entries = set()
|
|
|
1ac3f6 |
+ for _entry in dbus_to_python(entries, list):
|
|
|
1ac3f6 |
+ _entries.add(normalize_ipset_entry(_entry))
|
|
|
1ac3f6 |
+ entries = list(_entries)
|
|
|
1ac3f6 |
log.debug1("%s.setEntries('[%s]')", self._log_prefix,
|
|
|
1ac3f6 |
",".join(entries))
|
|
|
1ac3f6 |
self.parent.accessCheck(sender)
|
|
|
1ac3f6 |
@@ -421,6 +424,7 @@ class FirewallDConfigIPSet(slip.dbus.service.Object):
|
|
|
1ac3f6 |
@dbus_handle_exceptions
|
|
|
1ac3f6 |
def addEntry(self, entry, sender=None):
|
|
|
1ac3f6 |
entry = dbus_to_python(entry, str)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
log.debug1("%s.addEntry('%s')", self._log_prefix, entry)
|
|
|
1ac3f6 |
self.parent.accessCheck(sender)
|
|
|
1ac3f6 |
settings = list(self.getSettings())
|
|
|
1ac3f6 |
@@ -436,6 +440,7 @@ class FirewallDConfigIPSet(slip.dbus.service.Object):
|
|
|
1ac3f6 |
@dbus_handle_exceptions
|
|
|
1ac3f6 |
def removeEntry(self, entry, sender=None):
|
|
|
1ac3f6 |
entry = dbus_to_python(entry, str)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
log.debug1("%s.removeEntry('%s')", self._log_prefix, entry)
|
|
|
1ac3f6 |
self.parent.accessCheck(sender)
|
|
|
1ac3f6 |
settings = list(self.getSettings())
|
|
|
1ac3f6 |
@@ -451,6 +456,7 @@ class FirewallDConfigIPSet(slip.dbus.service.Object):
|
|
|
1ac3f6 |
@dbus_handle_exceptions
|
|
|
1ac3f6 |
def queryEntry(self, entry, sender=None): # pylint: disable=W0613
|
|
|
1ac3f6 |
entry = dbus_to_python(entry, str)
|
|
|
1ac3f6 |
+ entry = normalize_ipset_entry(entry)
|
|
|
1ac3f6 |
log.debug1("%s.queryEntry('%s')", self._log_prefix, entry)
|
|
|
1ac3f6 |
settings = list(self.getSettings())
|
|
|
1ac3f6 |
if "timeout" in settings[4] and settings[4]["timeout"] != "0":
|
|
|
1ac3f6 |
diff --git a/src/tests/regression/rhbz1601610.at b/src/tests/regression/rhbz1601610.at
|
|
|
1ac3f6 |
index ede2c45b88c1..a716539a8acf 100644
|
|
|
1ac3f6 |
--- a/src/tests/regression/rhbz1601610.at
|
|
|
1ac3f6 |
+++ b/src/tests/regression/rhbz1601610.at
|
|
|
1ac3f6 |
@@ -6,11 +6,14 @@ CHECK_IPSET
|
|
|
1ac3f6 |
FWD_CHECK([-q --new-ipset=foobar --permanent --type=hash:net])
|
|
|
1ac3f6 |
FWD_RELOAD
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
-FWD_CHECK([-q --ipset=foobar --add-entry=10.1.1.0/22])
|
|
|
1ac3f6 |
-FWD_CHECK([-q --ipset=foobar --add-entry=10.1.2.0/22], 13, ignore, ignore)
|
|
|
1ac3f6 |
-FWD_CHECK([-q --ipset=foobar --add-entry=10.2.0.0/22])
|
|
|
1ac3f6 |
+FWD_CHECK([--ipset=foobar --add-entry=10.1.1.0/22], 0, [ignore])
|
|
|
1ac3f6 |
+FWD_CHECK([--ipset=foobar --query-entry 10.1.2.0/22], 0, [ignore])
|
|
|
1ac3f6 |
+FWD_CHECK([--ipset=foobar --add-entry=10.1.2.0/22], 0, [ignore], [dnl
|
|
|
1ac3f6 |
+Warning: ALREADY_ENABLED: '10.1.0.0/22' already is in 'foobar'
|
|
|
1ac3f6 |
+])
|
|
|
1ac3f6 |
+FWD_CHECK([--ipset=foobar --add-entry=10.2.0.0/22], 0, [ignore])
|
|
|
1ac3f6 |
FWD_CHECK([--ipset=foobar --get-entries], 0, [dnl
|
|
|
1ac3f6 |
-10.1.1.0/22
|
|
|
1ac3f6 |
+10.1.0.0/22
|
|
|
1ac3f6 |
10.2.0.0/22
|
|
|
1ac3f6 |
])
|
|
|
1ac3f6 |
NFT_LIST_SET([foobar], 0, [dnl
|
|
|
1ac3f6 |
@@ -31,6 +34,9 @@ Members:
|
|
|
1ac3f6 |
])
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
FWD_CHECK([-q --ipset=foobar --remove-entry=10.1.1.0/22])
|
|
|
1ac3f6 |
+FWD_CHECK([--ipset=foobar --query-entry 10.1.1.0/22], 1, [ignore])
|
|
|
1ac3f6 |
+FWD_CHECK([--ipset=foobar --query-entry 10.1.2.0/22], 1, [ignore])
|
|
|
1ac3f6 |
+FWD_CHECK([--ipset=foobar --query-entry 10.2.0.0/22], 0, [ignore])
|
|
|
1ac3f6 |
FWD_CHECK([--ipset=foobar --get-entries], 0, [dnl
|
|
|
1ac3f6 |
10.2.0.0/22
|
|
|
1ac3f6 |
])
|
|
|
1ac3f6 |
@@ -52,7 +58,7 @@ Members:
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
FWD_CHECK([-q --permanent --ipset=foobar --add-entry=10.1.1.0/22])
|
|
|
1ac3f6 |
FWD_CHECK([--permanent --ipset=foobar --get-entries], 0, [dnl
|
|
|
1ac3f6 |
-10.1.1.0/22
|
|
|
1ac3f6 |
+10.1.0.0/22
|
|
|
1ac3f6 |
])
|
|
|
1ac3f6 |
FWD_CHECK([-q --permanent --ipset=foobar --remove-entry=10.1.1.0/22])
|
|
|
1ac3f6 |
FWD_CHECK([--permanent --ipset=foobar --get-entries], 0, [
|
|
|
1ac3f6 |
@@ -101,4 +107,5 @@ Members:
|
|
|
1ac3f6 |
|
|
|
1ac3f6 |
FWD_END_TEST([-e '/ERROR: COMMAND_FAILED:.*already added.*/d'dnl
|
|
|
1ac3f6 |
-e '/ERROR: COMMAND_FAILED:.*element.*exists/d'dnl
|
|
|
1ac3f6 |
- -e '/Kernel support protocol versions/d'])
|
|
|
1ac3f6 |
+ -e '/Kernel support protocol versions/d'dnl
|
|
|
1ac3f6 |
+ -e '/WARNING: ALREADY_ENABLED:/d'])
|
|
|
1ac3f6 |
--
|
|
|
1ac3f6 |
2.27.0
|
|
|
1ac3f6 |
|