Blame SOURCES/firewalld-0.3.9-RHBZ#1183008.patch

3d17f4
Adapted versions of
3d17f4
3d17f4
commit d72384cfc3eba7db5739f83a28f3476b9553c856
3d17f4
Author: Jiri Popelka <jpopelka@redhat.com>
3d17f4
Date:   Fri Jul 25 14:12:19 2014 +0200
3d17f4
3d17f4
    Check built-in chains in direct chain handling functions. (RHBZ#1120619)
3d17f4
    
3d17f4
    also rename ipXtables/ebtables.CHAINS to BUILT_IN_CHAINS
3d17f4
3d17f4
commit d4c839f838d0772b19d521ff826065e14f9a569d
3d17f4
Author: Jiri Popelka <jpopelka@redhat.com>
3d17f4
Date:   Mon Aug 4 15:59:54 2014 +0200
3d17f4
3d17f4
    Direct & LockdownWhitelist: clear() -> cleanup()
3d17f4
    
3d17f4
    these were renamed in fb656f53bc
3d17f4
3d17f4
commit fb656f53bc0eac095694ba61af6933632abf0f20
3d17f4
Author: Thomas Woerner <twoerner@redhat.com>
3d17f4
Date:   Tue Oct 22 17:21:55 2013 +0200
3d17f4
3d17f4
    Fix cleanup and initializations to get leaked memory to 0 at all times
3d17f4
3d17f4
commit 07550d550e618a3040153341eb8218551c3aa776
3d17f4
Author: Jiri Popelka <jpopelka@redhat.com>
3d17f4
Date:   Tue Sep 30 16:39:41 2014 +0200
3d17f4
3d17f4
    permanent direct: more tests for ipv & table
3d17f4
    
3d17f4
    see also 9139b468e5
3d17f4
3d17f4
commit 9139b468e5ffbe515dfd9892401eadb13a293a0b
3d17f4
Author: Jiri Popelka <jpopelka@redhat.com>
3d17f4
Date:   Tue Jul 15 18:21:47 2014 +0200
3d17f4
3d17f4
    FirewallDirect: check ipv & table sooner to provide consistent errors
3d17f4
    
3d17f4
    thanks to Jakub Jelen
3d17f4
3d17f4
commit 1a5670befb208018196b4f897fb84033e544f886
3d17f4
Author: Jiri Popelka <jpopelka@redhat.com>
3d17f4
Date:   Tue Oct 14 09:46:46 2014 +0200
3d17f4
3d17f4
    Rich_Rule.check(): action can't be used with icmp-block/forward-port/masquerade
3d17f4
3d17f4
commit 76751826d97577fe2b41abf8c5448c653df49651
3d17f4
Author: Thomas Woerner <twoerner@redhat.com>
3d17f4
Date:   Tue Feb 11 23:34:09 2014 +0100
3d17f4
3d17f4
    firewalld: No load failed error for absent direct.xml file
3d17f4
3d17f4
commit 524438c41fae5a0b239d2273871ffe54c61e65de
3d17f4
Author: Thomas Woerner <twoerner@redhat.com>
3d17f4
Date:   Tue Jul 7 13:01:12 2015 +0200
3d17f4
3d17f4
    fw.py._start: Fix reload with runtime rules, but no direct.xml (RHBZ#1183008)
3d17f4
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/ebtables.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/ebtables.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/ebtables.py.RHBZ#1183008	2015-07-07 13:10:10.938698154 +0200
3d17f4
+++ firewalld-0.3.9/src/firewall/core/ebtables.py	2015-07-07 13:10:11.074695768 +0200
3d17f4
@@ -25,7 +25,7 @@ from firewall.core.logger import log
3d17f4
 PROC_IPxTABLE_NAMES = {
3d17f4
 }
3d17f4
 
3d17f4
-CHAINS = {
3d17f4
+BUILT_IN_CHAINS = {
3d17f4
     "broute": [ "BROUTING" ],
3d17f4
     "nat": [ "PREROUTING", "POSTROUTING", "OUTPUT" ],
3d17f4
     "filter": [ "INPUT", "OUTPUT", "FORWARD" ],
3d17f4
@@ -60,7 +60,7 @@ class ebtables:
3d17f4
 
3d17f4
     def available_tables(self, table=None):
3d17f4
         ret = []
3d17f4
-        tables = [ table ] if table else CHAINS.keys()
3d17f4
+        tables = [ table ] if table else BUILT_IN_CHAINS.keys()
3d17f4
         for table in tables:
3d17f4
             try:
3d17f4
                 self.__run(["-t", table, "-L"])
3d17f4
@@ -71,7 +71,7 @@ class ebtables:
3d17f4
         return ret
3d17f4
 
3d17f4
     def used_tables(self):
3d17f4
-        return list(CHAINS.keys())
3d17f4
+        return list(BUILT_IN_CHAINS.keys())
3d17f4
 
3d17f4
     def flush(self):
3d17f4
         tables = self.used_tables()
3d17f4
@@ -86,13 +86,13 @@ class ebtables:
3d17f4
         if which == "used":
3d17f4
             tables = self.used_tables()
3d17f4
         else:
3d17f4
-            tables = list(CHAINS.keys())
3d17f4
+            tables = list(BUILT_IN_CHAINS.keys())
3d17f4
 
3d17f4
         if "nat" in tables:
3d17f4
             tables.remove("nat") # nat can not set policies in nat table
3d17f4
 
3d17f4
         for table in tables:
3d17f4
-            for chain in CHAINS[table]:
3d17f4
+            for chain in BUILT_IN_CHAINS[table]:
3d17f4
                 self.__run([ "-t", table, "-P", chain, policy ])
3d17f4
 
3d17f4
 ebtables_available_tables = ebtables().available_tables()
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/fw_config.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw_config.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/fw_config.py.RHBZ#1183008	2013-12-03 14:59:48.000000000 +0100
3d17f4
+++ firewalld-0.3.9/src/firewall/core/fw_config.py	2015-07-07 13:13:50.709829789 +0200
3d17f4
@@ -131,7 +131,7 @@ class FirewallConfig:
3d17f4
 
3d17f4
     def update_direct(self):
3d17f4
         if not os.path.exists(FIREWALLD_DIRECT):
3d17f4
-            self._direct.clear()
3d17f4
+            self._direct.cleanup()
3d17f4
         else:
3d17f4
             self._direct.read()
3d17f4
 
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/fw_direct.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw_direct.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/fw_direct.py.RHBZ#1183008	2015-07-07 13:10:11.072695804 +0200
3d17f4
+++ firewalld-0.3.9/src/firewall/core/fw_direct.py	2015-07-07 13:10:11.075695751 +0200
3d17f4
@@ -132,9 +132,41 @@ class FirewallDirect:
3d17f4
                     except FirewallError as error:
3d17f4
                         log.warning(str(error))
3d17f4
 
3d17f4
+    def _check_ipv(self, ipv):
3d17f4
+        ipvs = ['ipv4', 'ipv6', 'eb']
3d17f4
+        if ipv not in ipvs:
3d17f4
+            raise FirewallError(INVALID_IPV,
3d17f4
+                                "'%s' not in '%s'" % (ipv, ipvs))
3d17f4
+
3d17f4
+    def _check_ipv_table(self, ipv, table):
3d17f4
+        self._check_ipv(ipv)
3d17f4
+
3d17f4
+        tables = ipXtables.BUILT_IN_CHAINS.keys() if ipv in [ 'ipv4', 'ipv6' ] \
3d17f4
+                                         else ebtables.BUILT_IN_CHAINS.keys()
3d17f4
+        if table not in tables:
3d17f4
+            raise FirewallError(INVALID_TABLE,
3d17f4
+                                "'%s' not in '%s'" % (table, tables))
3d17f4
+
3d17f4
+    def _check_builtin_chain(self, ipv, table, chain):
3d17f4
+        if ipv in ['ipv4', 'ipv6']:
3d17f4
+            built_in_chains = ipXtables.BUILT_IN_CHAINS[table]
3d17f4
+            our_chains = ipXtables.OUR_CHAINS[table]
3d17f4
+        else:
3d17f4
+            built_in_chains = ebtables.BUILT_IN_CHAINS[table]
3d17f4
+            our_chains = ebtables.OUR_CHAINS[table]
3d17f4
+        if chain in built_in_chains:
3d17f4
+            raise FirewallError(BUILTIN_CHAIN,
3d17f4
+                 "chain '%s' is built-in chain" % chain)
3d17f4
+        if chain in our_chains:
3d17f4
+            raise FirewallError(BUILTIN_CHAIN,
3d17f4
+                 "chain '%s' is reserved" % chain)
3d17f4
+
3d17f4
+
3d17f4
     # DIRECT CHAIN
3d17f4
 
3d17f4
     def __chain(self, add, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
+        self._check_builtin_chain(ipv, table, chain)
3d17f4
         table_id = (ipv, table)
3d17f4
 
3d17f4
         if add:
3d17f4
@@ -174,11 +206,14 @@ class FirewallDirect:
3d17f4
         self.__chain(False, ipv, table, chain)
3d17f4
 
3d17f4
     def query_chain(self, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
+        self._check_builtin_chain(ipv, table, chain)
3d17f4
         table_id = (ipv, table)
3d17f4
-        return (table_id in self._chains and \
3d17f4
-                    chain in self._chains[table_id])
3d17f4
+        return (table_id in self._chains and
3d17f4
+                   chain in self._chains[table_id])
3d17f4
 
3d17f4
     def get_chains(self, ipv, table):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         table_id = (ipv, table)
3d17f4
         if table_id in self._chains:
3d17f4
             return self._chains[table_id]
3d17f4
@@ -195,13 +230,14 @@ class FirewallDirect:
3d17f4
     # DIRECT RULE
3d17f4
 
3d17f4
     def __rule(self, enable, ipv, table, chain, priority, args):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         _chain = chain
3d17f4
         # use "%s_chain" for built-in chains
3d17f4
 
3d17f4
         if ipv in [ "ipv4", "ipv6" ]:
3d17f4
-            _CHAINS = ipXtables.CHAINS
3d17f4
+            _CHAINS = ipXtables.BUILT_IN_CHAINS
3d17f4
         else:
3d17f4
-            _CHAINS = ebtables.CHAINS
3d17f4
+            _CHAINS = ebtables.BUILT_IN_CHAINS
3d17f4
 
3d17f4
         if table in _CHAINS and chain in _CHAINS[table]:
3d17f4
             _chain = "%s_direct" % (chain)
3d17f4
@@ -303,11 +339,13 @@ class FirewallDirect:
3d17f4
         self.__rule(False, ipv, table, chain, priority, args)
3d17f4
 
3d17f4
     def query_rule(self, ipv, table, chain, priority, args):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         chain_id = (ipv, table, chain)
3d17f4
         return (chain_id in self._rules and \
3d17f4
                 (priority, args) in self._rules[chain_id])
3d17f4
 
3d17f4
     def get_rules(self, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         chain_id = (ipv, table, chain)
3d17f4
         if chain_id in self._rules:
3d17f4
             return list(self._rules[chain_id].keys())
3d17f4
@@ -332,12 +370,6 @@ class FirewallDirect:
3d17f4
 
3d17f4
     # DIRECT PASSTHROUGH (tracked)
3d17f4
 
3d17f4
-    def _check_ipv(self, ipv):
3d17f4
-        ipvs = [ 'ipv4', 'ipv6', 'eb' ]
3d17f4
-        if ipv not in ipvs:
3d17f4
-            raise FirewallError(INVALID_IPV,
3d17f4
-                                "'%s' not in '%s'" % (ipv, ipvs))
3d17f4
-
3d17f4
     def __passthrough(self, enable, ipv, args):
3d17f4
         self._check_ipv(ipv)
3d17f4
 
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/fw.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/fw.py.RHBZ#1183008	2015-07-07 13:10:11.072695804 +0200
3d17f4
+++ firewalld-0.3.9/src/firewall/core/fw.py	2015-07-07 13:10:11.075695751 +0200
3d17f4
@@ -203,15 +203,16 @@ class Firewall:
3d17f4
         self.zone.apply_zones()
3d17f4
 
3d17f4
         # load direct rules
3d17f4
-        log.debug1("Loading direct rules file '%s'" % FIREWALLD_DIRECT)
3d17f4
         obj = Direct(FIREWALLD_DIRECT)
3d17f4
-        try:
3d17f4
-            obj.read()
3d17f4
-        except Exception as msg:
3d17f4
-            log.debug1("Failed to load direct rules file '%s': %s",
3d17f4
-                      FIREWALLD_DIRECT, msg)
3d17f4
-        else:
3d17f4
-            self.direct.set_permanent_config(obj)
3d17f4
+        if os.path.exists(FIREWALLD_DIRECT):
3d17f4
+            log.debug1("Loading direct rules file '%s'" % FIREWALLD_DIRECT)
3d17f4
+            try:
3d17f4
+                obj.read()
3d17f4
+            except Exception as msg:
3d17f4
+                log.debug1("Failed to load direct rules file '%s': %s",
3d17f4
+                           FIREWALLD_DIRECT, msg)
3d17f4
+
3d17f4
+        self.direct.set_permanent_config(obj)
3d17f4
         self.config.set_direct(copy.deepcopy(obj))
3d17f4
 
3d17f4
         # check if default_zone is a valid zone
3d17f4
@@ -394,7 +395,7 @@ class Firewall:
3d17f4
                 rule.pop(1)
3d17f4
 
3d17f4
             table = None
3d17f4
-            for t in ipXtables.CHAINS.keys():
3d17f4
+            for t in ipXtables.BUILT_IN_CHAINS.keys():
3d17f4
                 if t in rule:
3d17f4
                     table = t
3d17f4
             if table and not self.is_table_available(ipv, table):
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/fw_zone.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw_zone.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/fw_zone.py.RHBZ#1183008	2015-07-07 13:10:11.068695874 +0200
3d17f4
+++ firewalld-0.3.9/src/firewall/core/fw_zone.py	2015-07-07 13:10:11.076695733 +0200
3d17f4
@@ -26,7 +26,8 @@ from firewall.functions import portStr,
3d17f4
     checkProtocol, enable_ip_forwarding, check_single_address
3d17f4
 from firewall.core.rich import *
3d17f4
 from firewall.errors import *
3d17f4
-from firewall.core.ipXtables import ip4tables_available_tables, ip6tables_available_tables
3d17f4
+from firewall.core.ipXtables import ip4tables_available_tables,\
3d17f4
+    ip6tables_available_tables, OUR_CHAINS
3d17f4
 
3d17f4
 mangle = []
3d17f4
 if "mangle" in ip4tables_available_tables:
3d17f4
@@ -187,6 +188,10 @@ class FirewallZone:
3d17f4
                 ipvs.append("ipv6")
3d17f4
 
3d17f4
             for ipv in ipvs:
3d17f4
+                OUR_CHAINS[table].update(set([_zone,
3d17f4
+                                              "%s_log" % _zone,
3d17f4
+                                              "%s_deny" % _zone,
3d17f4
+                                              "%s_allow" % _zone]))
3d17f4
                 chains.append((ipv, [ _zone, "-t", table ]))
3d17f4
                 chains.append((ipv, [ "%s_log" % (_zone), "-t", table ]))
3d17f4
                 chains.append((ipv, [ "%s_deny" % (_zone), "-t", table ]))
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/io/direct.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/io/direct.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/io/direct.py.RHBZ#1183008	2015-07-07 13:10:11.030696540 +0200
3d17f4
+++ firewalld-0.3.9/src/firewall/core/io/direct.py	2015-07-07 13:10:11.076695733 +0200
3d17f4
@@ -29,6 +29,9 @@ from firewall.functions import splitArgs
3d17f4
 from firewall.errors import *
3d17f4
 from firewall.core.io.io_object import *
3d17f4
 from firewall.core.logger import log
3d17f4
+from firewall.core import ipXtables
3d17f4
+from firewall.core import ebtables
3d17f4
+
3d17f4
 
3d17f4
 class direct_ContentHandler(IO_Object_ContentHandler):
3d17f4
     def __init__(self, item):
3d17f4
@@ -188,9 +191,25 @@ class Direct(IO_Object):
3d17f4
             for args in self.passthroughs[key]:
3d17f4
                 print ("    ('%s')" % ("','".join(args)))
3d17f4
 
3d17f4
+    def _check_ipv(self, ipv):
3d17f4
+        ipvs = ['ipv4', 'ipv6', 'eb']
3d17f4
+        if ipv not in ipvs:
3d17f4
+            raise FirewallError(INVALID_IPV,
3d17f4
+                                "'%s' not in '%s'" % (ipv, ipvs))
3d17f4
+
3d17f4
+    def _check_ipv_table(self, ipv, table):
3d17f4
+        self._check_ipv(ipv)
3d17f4
+
3d17f4
+        tables = ipXtables.BUILT_IN_CHAINS.keys() if ipv in ['ipv4', 'ipv6'] \
3d17f4
+                                         else ebtables.BUILT_IN_CHAINS.keys()
3d17f4
+        if table not in tables:
3d17f4
+            raise FirewallError(INVALID_TABLE,
3d17f4
+                                "'%s' not in '%s'" % (table, tables))
3d17f4
+
3d17f4
     # chains
3d17f4
 
3d17f4
     def add_chain(self, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table)
3d17f4
         if key not in self.chains:
3d17f4
             self.chains[key] = [ ]
3d17f4
@@ -202,6 +221,7 @@ class Direct(IO_Object):
3d17f4
                         + "already in list, ignoring")
3d17f4
 
3d17f4
     def remove_chain(self, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table)
3d17f4
         if key in self.chains and chain in self.chains[key]:
3d17f4
             self.chains[key].remove(chain)
3d17f4
@@ -213,10 +233,12 @@ class Direct(IO_Object):
3d17f4
                 (chain, table, ipv))
3d17f4
 
3d17f4
     def query_chain(self, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table)
3d17f4
         return (key in self.chains and chain in self.chains[key])
3d17f4
 
3d17f4
     def get_chains(self, ipv, table):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table)
3d17f4
         if key in self.chains:
3d17f4
             return self.chains[key]
3d17f4
@@ -230,6 +252,7 @@ class Direct(IO_Object):
3d17f4
     # rules
3d17f4
 
3d17f4
     def add_rule(self, ipv, table, chain, priority, args):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table, chain)
3d17f4
         if key not in self.rules:
3d17f4
             self.rules[key] = LastUpdatedOrderedDict()
3d17f4
@@ -243,6 +266,7 @@ class Direct(IO_Object):
3d17f4
                         + "already in list, ignoring")
3d17f4
 
3d17f4
     def remove_rule(self, ipv, table, chain, priority, args):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table, chain)
3d17f4
         value = (priority, tuple(args))
3d17f4
         if key in self.rules and value in self.rules[key]:
3d17f4
@@ -255,6 +279,7 @@ class Direct(IO_Object):
3d17f4
                 "with ipv '%s' and priority %d not in list" % (ipv, priority))
3d17f4
 
3d17f4
     def remove_rules(self, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table, chain)
3d17f4
         if key in self.rules:
3d17f4
             for value in self.rules[key].keys():
3d17f4
@@ -263,11 +288,13 @@ class Direct(IO_Object):
3d17f4
                 del self.rules[key]
3d17f4
 
3d17f4
     def query_rule(self, ipv, table, chain, priority, args):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table, chain)
3d17f4
         value = (priority, tuple(args))
3d17f4
         return (key in self.rules and value in self.rules[key])
3d17f4
 
3d17f4
     def get_rules(self, ipv, table, chain):
3d17f4
+        self._check_ipv_table(ipv, table)
3d17f4
         key = (ipv, table, chain)
3d17f4
         if key in self.rules:
3d17f4
             return self.rules[key]
3d17f4
@@ -281,6 +308,7 @@ class Direct(IO_Object):
3d17f4
 #    # passthrough
3d17f4
 #
3d17f4
     def add_passthrough(self, ipv, args):
3d17f4
+        self._check_ipv(ipv)
3d17f4
         if ipv not in self.passthroughs:
3d17f4
             self.passthroughs[ipv] = [ ]
3d17f4
         if args not in self.passthroughs[ipv]:
3d17f4
@@ -291,6 +319,7 @@ class Direct(IO_Object):
3d17f4
                         + "already in list, ignoring")
3d17f4
 
3d17f4
     def remove_passthrough(self, ipv, args):
3d17f4
+        self._check_ipv(ipv)
3d17f4
         if ipv in self.passthroughs and args in self.passthroughs[ipv]:
3d17f4
             self.passthroughs[ipv].remove(args)
3d17f4
             if len(self.passthroughs[ipv]) == 0:
3d17f4
@@ -300,9 +329,11 @@ class Direct(IO_Object):
3d17f4
                 ("',".join(args), ipv) + "not in list"
3d17f4
 
3d17f4
     def query_passthrough(self, ipv, args):
3d17f4
+        self._check_ipv(ipv)
3d17f4
         return (ipv in self.passthroughs and args in self.passthroughs[ipv])
3d17f4
 
3d17f4
     def get_passthroughs(self, ipv):
3d17f4
+        self._check_ipv(ipv)
3d17f4
         if ipv in self.passthroughs:
3d17f4
             return self.passthroughs[ipv]
3d17f4
         else:
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/ipXtables.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/ipXtables.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/ipXtables.py.RHBZ#1183008	2015-07-07 13:10:11.066695909 +0200
3d17f4
+++ firewalld-0.3.9/src/firewall/core/ipXtables.py	2015-07-07 13:10:11.076695733 +0200
3d17f4
@@ -34,7 +34,7 @@ PROC_IPxTABLE_NAMES = {
3d17f4
     "ipv6": "/proc/net/ip6_tables_names",
3d17f4
 }
3d17f4
 
3d17f4
-CHAINS = {
3d17f4
+BUILT_IN_CHAINS = {
3d17f4
     "security": [ "INPUT", "OUTPUT", "FORWARD" ],
3d17f4
     "raw": [ "PREROUTING", "OUTPUT" ],
3d17f4
     "mangle": [ "PREROUTING", "POSTROUTING", "INPUT", "OUTPUT", "FORWARD" ],
3d17f4
@@ -53,38 +53,49 @@ ICMP = {
3d17f4
 }
3d17f4
 
3d17f4
 DEFAULT_RULES = { }
3d17f4
+OUR_CHAINS = {} # chains created by firewalld
3d17f4
 
3d17f4
 DEFAULT_RULES["security"] = [ ]
3d17f4
-for chain in CHAINS["security"]:
3d17f4
+OUR_CHAINS["security"] = set()
3d17f4
+for chain in BUILT_IN_CHAINS["security"]:
3d17f4
     DEFAULT_RULES["security"].append("-N %s_direct" % chain)
3d17f4
     DEFAULT_RULES["security"].append("-I %s 1 -j %s_direct" % (chain, chain))
3d17f4
+    OUR_CHAINS["security"].add("%s_direct" % chain)
3d17f4
 
3d17f4
 DEFAULT_RULES["raw"] = [ ]
3d17f4
-for chain in CHAINS["raw"]:
3d17f4
+OUR_CHAINS["raw"] = set()
3d17f4
+for chain in BUILT_IN_CHAINS["raw"]:
3d17f4
     DEFAULT_RULES["raw"].append("-N %s_direct" % chain)
3d17f4
     DEFAULT_RULES["raw"].append("-I %s 1 -j %s_direct" % (chain, chain))
3d17f4
+    OUR_CHAINS["raw"].add("%s_direct" % chain)
3d17f4
 
3d17f4
 DEFAULT_RULES["mangle"] = [ ]
3d17f4
-for chain in CHAINS["mangle"]:
3d17f4
+OUR_CHAINS["mangle"] = set()
3d17f4
+for chain in BUILT_IN_CHAINS["mangle"]:
3d17f4
     DEFAULT_RULES["mangle"].append("-N %s_direct" % chain)
3d17f4
     DEFAULT_RULES["mangle"].append("-I %s 1 -j %s_direct" % (chain, chain))
3d17f4
+    OUR_CHAINS["mangle"].add("%s_direct" % chain)
3d17f4
 
3d17f4
     if chain == "PREROUTING":
3d17f4
         DEFAULT_RULES["mangle"].append("-N %s_ZONES_SOURCE" % chain)
3d17f4
         DEFAULT_RULES["mangle"].append("-N %s_ZONES" % chain)
3d17f4
         DEFAULT_RULES["mangle"].append("-I %s 2 -j %s_ZONES_SOURCE" % (chain, chain))
3d17f4
         DEFAULT_RULES["mangle"].append("-I %s 3 -j %s_ZONES" % (chain, chain))
3d17f4
+        OUR_CHAINS["mangle"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
3d17f4
 
3d17f4
 DEFAULT_RULES["nat"] = [ ]
3d17f4
-for chain in CHAINS["nat"]:
3d17f4
+OUR_CHAINS["nat"] = set()
3d17f4
+for chain in BUILT_IN_CHAINS["nat"]:
3d17f4
     DEFAULT_RULES["nat"].append("-N %s_direct" % chain)
3d17f4
     DEFAULT_RULES["nat"].append("-I %s 1 -j %s_direct" % (chain, chain))
3d17f4
+    OUR_CHAINS["nat"].add("%s_direct" % chain)
3d17f4
 
3d17f4
     if chain in [ "PREROUTING", "POSTROUTING" ]:
3d17f4
         DEFAULT_RULES["nat"].append("-N %s_ZONES_SOURCE" % chain)
3d17f4
         DEFAULT_RULES["nat"].append("-N %s_ZONES" % chain)
3d17f4
         DEFAULT_RULES["nat"].append("-I %s 2 -j %s_ZONES_SOURCE" % (chain, chain))
3d17f4
         DEFAULT_RULES["nat"].append("-I %s 3 -j %s_ZONES" % (chain, chain))
3d17f4
+        OUR_CHAINS["nat"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
3d17f4
 
3d17f4
 DEFAULT_RULES["filter"] = [
3d17f4
     "-N INPUT_direct",
3d17f4
@@ -119,6 +130,11 @@ DEFAULT_RULES["filter"] = [
3d17f4
 
3d17f4
     "-I OUTPUT 1 -j OUTPUT_direct",
3d17f4
 ]
3d17f4
+OUR_CHAINS["filter"] = set(["INPUT_direct", "INPUT_ZONES_SOURCE", "INPUT_ZONES",
3d17f4
+                          "FORWARD_direct", "FORWARD_IN_ZONES_SOURCE",
3d17f4
+                          "FORWARD_IN_ZONES", "FORWARD_OUT_ZONES_SOURCE",
3d17f4
+                          "FORWARD_OUT_ZONES", "OUTPUT_direct"])
3d17f4
+
3d17f4
 
3d17f4
 class ip4tables:
3d17f4
     ipv = "ipv4"
3d17f4
@@ -151,7 +167,7 @@ class ip4tables:
3d17f4
 
3d17f4
     def available_tables(self, table=None):
3d17f4
         ret = []
3d17f4
-        tables = [ table ] if table else CHAINS.keys()
3d17f4
+        tables = [ table ] if table else BUILT_IN_CHAINS.keys()
3d17f4
         for table in tables:
3d17f4
             try:
3d17f4
                 self.__run(["-t", table, "-L"])
3d17f4
@@ -199,13 +215,13 @@ class ip4tables:
3d17f4
         if which == "used":
3d17f4
             tables = self.used_tables()
3d17f4
         else:
3d17f4
-            tables = list(CHAINS.keys())
3d17f4
+            tables = list(BUILT_IN_CHAINS.keys())
3d17f4
 
3d17f4
         if "nat" in tables:
3d17f4
             tables.remove("nat") # nat can not set policies in nat table
3d17f4
 
3d17f4
         for table in tables:
3d17f4
-            for chain in CHAINS[table]:
3d17f4
+            for chain in BUILT_IN_CHAINS[table]:
3d17f4
                 self.__run([ "-t", table, "-P", chain, policy ])
3d17f4
 
3d17f4
 class ip6tables(ip4tables):
3d17f4
diff -up firewalld-0.3.9/src/firewall/core/rich.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/rich.py
3d17f4
--- firewalld-0.3.9/src/firewall/core/rich.py.RHBZ#1183008	2015-07-07 13:10:11.070695839 +0200
3d17f4
+++ firewalld-0.3.9/src/firewall/core/rich.py	2015-07-07 13:10:11.076695733 +0200
3d17f4
@@ -481,6 +481,8 @@ class Rich_Rule(object):
3d17f4
         elif type(self.element) == Rich_Masquerade:
3d17f4
             if self.destination != None:
3d17f4
                 raise FirewallError(INVALID_RULE, "masquerade and destination")
3d17f4
+            if self.action:
3d17f4
+                raise FirewallError(INVALID_RULE, "masquerade and action")
3d17f4
 
3d17f4
         # icmp-block
3d17f4
         elif type(self.element) == Rich_IcmpBlock:
3d17f4
@@ -488,8 +490,8 @@ class Rich_Rule(object):
3d17f4
             # knowledge about this, therefore only simple check
3d17f4
             if self.element.name == None or len(self.element.name) < 1:
3d17f4
                 raise FirewallError(INVALID_ICMPTYPE, str(self.element.name))
3d17f4
-            if self.action and type(self.action) == Rich_Accept:
3d17f4
-                raise FirewallError(INVALID_RULE, "icmpblock and accept")
3d17f4
+            if self.action:
3d17f4
+                raise FirewallError(INVALID_RULE, "icmp-block and action")
3d17f4
 
3d17f4
         # forward-port
3d17f4
         elif type(self.element) == Rich_ForwardPort:
3d17f4
@@ -508,6 +510,8 @@ class Rich_Rule(object):
3d17f4
                 raise FirewallError(INVALID_ADDR, self.element.to_address)
3d17f4
             if self.family == None:
3d17f4
                 raise FirewallError(INVALID_FAMILY)
3d17f4
+            if self.action:
3d17f4
+                raise FirewallError(INVALID_RULE, "forward-port and action")
3d17f4
 
3d17f4
         # other element and not empty?
3d17f4
         elif self.element != None: