diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1122739,1128563.patch b/SOURCES/firewalld-0.3.9-RHBZ#1122739,1128563.patch new file mode 100644 index 0000000..841a4c9 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1122739,1128563.patch @@ -0,0 +1,95 @@ +commit 302d7f28fb9c09d624e34d9b9966a7d2974bbd3a +Author: Jiri Popelka +Date: Thu Aug 14 14:44:13 2014 +0200 + + man: '--permanent --add-interface' vs. ZONE= in ifcfg (RHBZ#1128563) + +diff --git a/doc/xml/firewall-cmd.xml b/doc/xml/firewall-cmd.xml +index 44f6799..dabb9a4 100644 +--- a/doc/xml/firewall-cmd.xml ++++ b/doc/xml/firewall-cmd.xml +@@ -648,8 +648,10 @@ + Bind interface interface to zone zone. If zone is omitted, default zone will be used. + + +- As a end user you don't need this in most cases, because NetworkManager adds interfaces into zones automatically. +- For permanent association of interface with a zone, see 'How to set or change a zone for a connection?' in firewalld.zones5. ++ As a end user you don't need this in most cases, because NetworkManager (or legacy network service) adds interfaces into zones automatically (according to option from ifcfg-interface file). ++ You should do it only if there's no /etc/sysconfig/network-scripts/ifcfg-interface file. ++ If there is such file and you add interface to zone with this option, make sure the zone is the same in both cases, otherwise the behaviour would be undefined. ++ For permanent association of interface with a zone, see also 'How to set or change a zone for a connection?' in firewalld.zones5. + + + +diff --git a/doc/xml/firewalld.xml b/doc/xml/firewalld.xml +index 4ccf4e3..24d7541 100644 +--- a/doc/xml/firewalld.xml ++++ b/doc/xml/firewalld.xml +@@ -123,7 +123,12 @@ + firewalld provides support for zones, predefined services and ICMP types and has a separation of runtime and permanent configuration options. Permanent configuration is loaded from XML files in /usr/lib/firewalld or /etc/firewalld (see ). + + +- If NetworkManager is not used, there are some limitations: firewalld will not get notified about network device renames. If firewalld gets started after the network is already up, the connections are not bound to a zone. Manually created interfaces are not bound to a zone. Please add them to a zone with firewall-cmd --zone=zone --add-interface=interface. ++ If NetworkManager is not used, there are some limitations: firewalld will not get notified about network device renames. ++ If firewalld gets started after the network is already up, the connections and manually created interfaces are not bound to a zone. ++ You can add them to a zone with firewall-cmd [--permanent] --zone=zone --add-interface=interface, ++ but make sure that if there's a /etc/sysconfig/network-scripts/ifcfg-interface, ++ the zone specified there with ZONE=zone ++ is the same (or both are empty/missing for default zone), otherwise the behaviour would be undefined. + + + +commit f0d25a618c26dc47c552e63ac7d7c9a2c57151b7 +Author: Thomas Woerner +Date: Tue Jul 7 10:32:31 2015 +0200 + + man: Interface handling with and without NetworkManager (RHBZ#1122739 RHBZ#1128563) + +diff --git a/doc/xml/firewall-cmd.xml b/doc/xml/firewall-cmd.xml +index 74c9e1c..8603ca8 100644 +--- a/doc/xml/firewall-cmd.xml ++++ b/doc/xml/firewall-cmd.xml +@@ -660,9 +660,10 @@ + Bind interface interface to zone zone. If zone is omitted, default zone will be used. + + +- As a end user you don't need this in most cases, because NetworkManager (or legacy network service) adds interfaces into zones automatically (according to option from ifcfg-interface file). ++ As a end user you don't need this in most cases, because NetworkManager (or legacy network service) adds interfaces into zones automatically (according to option from ifcfg-interface file) if NM_CONTROLLED=no is not set. + You should do it only if there's no /etc/sysconfig/network-scripts/ifcfg-interface file. + If there is such file and you add interface to zone with this option, make sure the zone is the same in both cases, otherwise the behaviour would be undefined. ++ Please also have a look at the firewalld1 man page in the Concepts section. + For permanent association of interface with a zone, see also 'How to set or change a zone for a connection?' in firewalld.zones5. + + +diff --git a/doc/xml/firewalld.xml b/doc/xml/firewalld.xml +index df26ff7..ee16cd0 100644 +--- a/doc/xml/firewalld.xml ++++ b/doc/xml/firewalld.xml +@@ -123,13 +123,24 @@ + firewalld provides support for zones, predefined services and ICMP types and has a separation of runtime and permanent configuration options. Permanent configuration is loaded from XML files in /usr/lib/firewalld or /etc/firewalld (see ). + + +- If NetworkManager is not used, there are some limitations: firewalld will not get notified about network device renames. +- If firewalld gets started after the network is already up, the connections and manually created interfaces are not bound to a zone. +- You can add them to a zone with firewall-cmd [--permanent] --zone=zone --add-interface=interface, ++ If NetworkManager is not in use and firewalld gets started after the network is already up, the connections and manually created interfaces are not bound to the zone specified in the ifcfg file. ++ The interfaces will automatically be handled by the default zone. ++ firewalld will also not get notified about network device renames. ++ All this also applies to interfaces that are not controlled by NetworkManager if NM_CONTROLLED=no is set. ++ ++ ++ You can add these interfaces to a zone with firewall-cmd [--permanent] --zone=zone --add-interface=interface, + but make sure that if there's a /etc/sysconfig/network-scripts/ifcfg-interface, + the zone specified there with ZONE=zone + is the same (or both are empty/missing for default zone), otherwise the behaviour would be undefined. + ++ ++ If firewalld gets reloaded, it will restore the interface bindings that were in place before reloading to keep interface bindings stable in the case of NetworkManager uncontrolled interfaces. ++ This mechanism is not possible in the case of a firewalld service restart. ++ ++ ++ It is essential to keep the ZONE= setting in the ifcfg file consistent to the binding in firewalld in the case of NetworkManager uncontrolled interfaces. ++ + + + Zones diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1142741.patch b/SOURCES/firewalld-0.3.9-RHBZ#1142741.patch new file mode 100644 index 0000000..0fb09a0 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1142741.patch @@ -0,0 +1,37 @@ +commit e361f33c2bf42acb2e4db578169326b11041b796 +Author: Jay Cornwall +Date: Fri May 9 07:44:52 2014 -0500 + + firewalld: Apply all rich rules for non-default targets + + If a zone had a non-default target then rich PORT and PROTOCOL + rules would not be applied. + + Signed-off-by: Jiri Popelka + +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index 1e99fef..7f20b48 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -820,8 +820,8 @@ class FirewallZone: + + table = "filter" + chains.append([ table, "INPUT" ]) +- target = self._zones[zone].target.format(chain=SHORTCUTS["INPUT"], +- zone=zone) ++ target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS["INPUT"], ++ zone=zone) + + command = [ ] + self.__rule_source(rule.source, command) +@@ -841,8 +841,8 @@ class FirewallZone: + + table = "filter" + chains.append([ table, "INPUT" ]) +- target = self._zones[zone].target.format(chain=SHORTCUTS["INPUT"], +- zone=zone) ++ target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS["INPUT"], ++ zone=zone) + + command = [ ] + self.__rule_source(rule.source, command) diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1150656.patch b/SOURCES/firewalld-0.3.9-RHBZ#1150656.patch new file mode 100644 index 0000000..08b71bb --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1150656.patch @@ -0,0 +1,33 @@ +Adapted version of + +commit fddf73570d392f815942fc5915a5f7110ffa389e +Author: Jiri Popelka +Date: Mon Oct 20 15:18:16 2014 +0200 + + New iscsi-target service. (RHBZ#1150656) + +#diff --git a/config/Makefile.am b/config/Makefile.am +#index aab86b4..93a8649 100644 +#--- a/config/Makefile.am +#+++ b/config/Makefile.am +#@@ -84,6 +84,7 @@ EXTRA_DIST = \ +# services/ipp-client.xml \ +# services/ipp.xml \ +# services/ipsec.xml \ +#+ services/iscsi-target.xml \ +# services/kadmin.xml \ +# services/kerberos.xml \ +# services/kpasswd.xml \ +diff --git a/config/services/iscsi-target.xml b/config/services/iscsi-target.xml +new file mode 100644 +index 0000000..fef08f9 +--- /dev/null ++++ b/config/services/iscsi-target.xml +@@ -0,0 +1,7 @@ ++ ++ ++ iSCSI target ++ Internet SCSI target is a storage resource located on an iSCSI server. ++ ++ ++ diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1150659.patch b/SOURCES/firewalld-0.3.9-RHBZ#1150659.patch new file mode 100644 index 0000000..7913538 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1150659.patch @@ -0,0 +1,33 @@ +Adapted version of + +commit 99dccf9ad72e067a68a541de62b5bc3ef52655a7 +Author: Jiri Popelka +Date: Thu Oct 16 11:00:17 2014 +0200 + + new rsynd service + +#diff --git a/config/Makefile.am b/config/Makefile.am +#index ea50b92..aab86b4 100644 +#--- a/config/Makefile.am +#+++ b/config/Makefile.am +#@@ -109,6 +109,7 @@ EXTRA_DIST = \ +# services/puppetmaster.xml \ +# services/radius.xml \ +# services/rpc-bind.xml \ +#+ services/rsyncd.xml \ +# services/samba-client.xml \ +# services/samba.xml \ +# services/sane.xml \ +diff --git a/config/services/rsyncd.xml b/config/services/rsyncd.xml +new file mode 100644 +index 0000000..09adf16 +--- /dev/null ++++ b/config/services/rsyncd.xml +@@ -0,0 +1,7 @@ ++ ++ ++ Rsync in daemon mode ++ Rsync in daemon mode works as a central server, in order to house centralized files and keep them synchronized. ++ ++ ++ diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1161745.patch b/SOURCES/firewalld-0.3.9-RHBZ#1161745.patch new file mode 100644 index 0000000..29a4c3c --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1161745.patch @@ -0,0 +1,65 @@ +Adapted version of + +commit b3b451d6f8946986b8f50c8bcddeef50ed7a5f8f +Author: Jiri Popelka +Date: Mon Oct 27 17:45:46 2014 +0100 + + ipXtables: use -w or -w2 if supported + + iptables (since 1.4.20) has a locking mechanism [1], + which prevents multiple instances of the program from running concurrently. + + It can happen that some other daemon (libvirtd [2], docker [3]) + is calling iptables at the same time as firewalld. + In that case the second one which calls iptables fails with: + "Another app is currently holding the xtables lock. + Perhaps you want to use the -w option?" + + The easiest work-around is the use the suggested "-w" option, + which makes the second iptables instance wait till the lock is released. + Even better is to use "-w2" [2] which makes it wait for max 2 seconds. + + [1] https://git.netfilter.org/iptables/commit/?id=93587a04d0f2511e108bbc4d87a8b9d28a5c5dd8 + [2] https://bugzilla.redhat.com/show_bug.cgi?id=1098281 + [3] https://bugzilla.redhat.com/show_bug.cgi?id=1151067 + [4] https://git.netfilter.org/iptables/commit/?id=aaa4ace72ba1d195bbf436134a336816c33f7bd0 + +diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py +index 8f61bb8..e8381f2 100644 +--- a/src/firewall/core/ipXtables.py ++++ b/src/firewall/core/ipXtables.py +@@ -125,10 +125,14 @@ class ip4tables: + + def __init__(self): + self._command = COMMAND[self.ipv] ++ self.wait_option = self._detect_wait_option() + + def __run(self, args): + # convert to string list +- _args = ["%s" % item for item in args] ++ if self.wait_option: ++ _args = [self.wait_option] + ["%s" % item for item in args] ++ else: ++ _args = ["%s" % item for item in args] + log.debug2("%s: %s %s", self.__class__, self._command, " ".join(_args)) + (status, ret) = runProg(self._command, _args) + if status != 0: +@@ -170,6 +174,18 @@ class ip4tables: + + return tables + ++ def _detect_wait_option(self): ++ wait_option = "" ++ (status, ret) = runProg(self._command, ["-w", "-L"]) # since iptables-1.4.20 ++ if status == 0: ++ wait_option = "-w" # wait for xtables lock ++ (status, ret) = runProg(self._command, ["-w2", "-L"]) # since iptables > 1.4.21 ++ if status == 0: ++ wait_option = "-w2" # wait max 2 seconds ++ log.debug2("%s: %s will be using %s option.", self.__class__, self._command, wait_option) ++ ++ return wait_option ++ + def flush(self): + tables = self.used_tables() + for table in tables: diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1164605.patch b/SOURCES/firewalld-0.3.9-RHBZ#1164605.patch new file mode 100644 index 0000000..5ec8e0f --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1164605.patch @@ -0,0 +1,42 @@ +commit 5e0b34d6492109e5039cb367a97a1a4564a1c545 +Author: Jiri Popelka +Date: Wed Dec 3 18:28:17 2014 +0100 + + Don't use ipv6header for protocol matching. (RHBZ#1065565) + + for example + ip6tables -m ipv6header --header tcp -j ACCEPT + doesn't work even iptables-extensions(8) claims: + 'A protocol name from /etc/protocols and numeric value also allowed.' + + It might be a bug in iptables, but I think using ipv6header just for + protocol matching is overkill anyway and using --protocol should be fine. + +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index cb7b7c9..ed6e995 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -798,10 +798,7 @@ class FirewallZone: + if proto in [ "tcp", "udp" ]: + command += [ "-m", proto, "-p", proto ] + else: +- if ipv == "ipv4": +- command += [ "-p", proto ] +- else: +- command += [ "-m", "ipv6header", "--header", proto ] ++ command += [ "-p", proto ] + if port: + command += [ "--dport", "%s" % portStr(port) ] + if ipv in svc.destination and svc.destination[ipv] != "": +@@ -1092,10 +1089,7 @@ class FirewallZone: + if proto in [ "tcp", "udp" ]: + rule += [ "-m", proto, "-p", proto ] + else: +- if ipv == "ipv4": +- rule += [ "-p", proto ] +- else: +- rule += [ "-m", "ipv6header", "--header", proto ] ++ rule += [ "-p", proto ] + if port: + rule += [ "--dport", "%s" % portStr(port) ] + if ipv in svc.destination and svc.destination[ipv] != "": diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1176813.patch b/SOURCES/firewalld-0.3.9-RHBZ#1176813.patch new file mode 100644 index 0000000..b340ef3 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1176813.patch @@ -0,0 +1,39 @@ +Adapted version of + +commit a45c84008ae27aae36a5a67c5f9b08bca64aaf55 +Author: Jiri Popelka +Date: Tue Jan 6 18:00:49 2015 +0100 + + Iptables doesn't like limit of 1/d (RHBZ#1176813) + + It should eventually be fixed in iptables, + this is a workaround for broken versions. + +diff --git a/doc/xml/firewalld.richlanguage.xml b/doc/xml/firewalld.richlanguage.xml +index 0556f20..39a9ec7 100644 +--- a/doc/xml/firewalld.richlanguage.xml ++++ b/doc/xml/firewalld.richlanguage.xml +@@ -226,7 +226,7 @@ log [prefix="prefix text"] [level="log l + Log new connection attempts to the rule with kernel logging for example in syslog. You can define a prefix text that will be added to the log message as a prefix. Log level can be one of "", "", "", "", "", "", "" or "", where default (i.e. if there's no one specified) is "". See syslog3 for description of levels. + + +- It is possible to limit logging: The rate is a natural positive number [1, ..], the duration is of "s", "m", "h", "d". "s" means seconds, "m" minutes, "h" hours and "d" days. The maximum limit value is "1/d" which means at maximum one log entry per day. ++ It is possible to limit logging: The rate is a natural positive number [1, ..], the duration is of "s", "m", "h", "d". "s" means seconds, "m" minutes, "h" hours and "d" days. The maximum limit value is "2/d" which means at maximum one log entry per day. + + + +diff --git a/src/firewall/core/rich.py b/src/firewall/core/rich.py +index 21dc86a..1c93d4f 100644 +--- a/src/firewall/core/rich.py ++++ b/src/firewall/core/rich.py +@@ -183,6 +183,10 @@ class Rich_Limit(object): + if 10000 * mult / rate == 0: + raise FirewallError(INVALID_LIMIT, "%s too fast" % self.value) + ++ if rate == 1 and duration == "d": ++ # iptables (v1.4.21) doesn't accept 1/d ++ raise FirewallError(INVALID_LIMIT, "%s too slow" % self.value) ++ + def __str__(self): + return 'limit value="%s"' % (self.value) + diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1182671.patch b/SOURCES/firewalld-0.3.9-RHBZ#1182671.patch new file mode 100644 index 0000000..799f56c --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1182671.patch @@ -0,0 +1,180 @@ +Adapted version of + +commit 133e8e7cc77dfe10269ac146f3c03810f50062dd +Author: Thomas Woerner +Date: Thu Jan 15 17:36:09 2015 +0100 + + Fix readdition of removed permanent direct settings (RHBZ#1182641) + + Permanent direct settings are not recognized as such while reloading firewalld + after adding the rules to the permanent environment if firewalld has been + reloaded after adding the settings in the first place and after they have been + removed again from the permanent environment again. + + A new test has been added to firewall-cmd_test.sh for verification. + +diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py +index 7787103..2ac7484 100644 +--- a/src/firewall/core/fw.py ++++ b/src/firewall/core/fw.py +@@ -211,9 +211,7 @@ class Firewall: + log.debug1("Failed to load direct rules file '%s': %s", + FIREWALLD_DIRECT, msg) + else: +- self.direct.set_config((obj.get_all_chains(), +- obj.get_all_rules(), +- obj.get_all_passthroughs())) ++ self.direct.set_permanent_config(obj) + self.config.set_direct(copy.deepcopy(obj)) + + # check if default_zone is a valid zone +@@ -652,7 +650,7 @@ class Firewall: + for zone in self.zone.get_zones(): + _zone_interfaces[zone] = self.zone.get_settings(zone)["interfaces"] + # save direct config +- _direct_config = self.direct.get_config() ++ _direct_config = self.direct.get_runtime_config() + _old_dz = self.get_default_zone() + + # stop +diff --git a/src/firewall/core/fw_direct.py b/src/firewall/core/fw_direct.py +index 358d182..a4cbf51 100644 +--- a/src/firewall/core/fw_direct.py ++++ b/src/firewall/core/fw_direct.py +@@ -56,10 +56,51 @@ class FirewallDirect: + self._rules = LastUpdatedOrderedDict() + self._rule_priority_positions = { } + self._passthroughs = LastUpdatedOrderedDict() ++ self._obj = None + + def cleanup(self): + self.__init_vars() + ++ def set_permanent_config(self, obj): ++ # Apply permanent configuration and save the obj to be able to ++ # remove permanent configuration settings within get_runtime_config ++ # for use in firewalld reload. ++ self._obj = obj ++ self.set_config((obj.get_all_chains(), ++ obj.get_all_rules(), ++ obj.get_all_passthroughs())) ++ ++ def get_runtime_config(self): ++ # Return only runtime changes ++ # Remove all chains, rules and passthroughs that are in self._obj ++ # (permanent config applied in firewalld _start. ++ chains = LastUpdatedOrderedDict() ++ rules = LastUpdatedOrderedDict() ++ passthroughs = LastUpdatedOrderedDict() ++ ++ for table_id in self._chains: ++ (ipv, table) = table_id ++ for chain in self._chains[table_id]: ++ if not self._obj.query_chain(ipv, table, chain): ++ chains.setdefault(table_id, [ ]).append(chain) ++ ++ for chain_id in self._rules: ++ (ipv, table, chain) = chain_id ++ for (priority, args) in self._rules[chain_id]: ++ if not self._obj.query_rule(ipv, table, chain, priority, args): ++ if not chain_id in rules: ++ rules[chain_id] = LastUpdatedOrderedDict() ++ rules[chain_id][rule_id] = priority ++ ++ for ipv in self._passthroughs: ++ for args in self._passthroughs[ipv]: ++ if not self._obj.query_passthrough(ipv, args): ++ if not ipv in passthroughs: ++ passthroughs[ipv] = [ ] ++ passthroughs[ipv].append(args) ++ ++ return (chains, rules, passthroughs) ++ + def get_config(self): + return (self._chains, self._rules, self._passthroughs) + +#diff --git a/src/tests/firewall-cmd_test.sh b/src/tests/firewall-cmd_test.sh +#index 75f6e2f..2b03e6a 100755 +#--- a/src/tests/firewall-cmd_test.sh +#+++ b/src/tests/firewall-cmd_test.sh +#@@ -85,6 +85,20 @@ assert_bad() { +# fi +# } +# +#+assert_bad_contains() { +#+ local args="${1}" +#+ local value="${2}" +#+ local ret +#+ +#+ ret=$(${path}firewall-cmd ${args}) > /dev/null +#+ if [[ ( "$?" -ne 0 ) || ( "${ret}" = *${value}* ) ]]; then +#+ ((failures++)) +#+ echo -e "${args} ... ${RED}${failures}. FAILED (non-zero exit status or '${ret}' does contain '${value}')${RESTORE}" +#+ else +#+ echo "${args} ... OK" +#+ fi +#+} +#+ +# # rich rules need separate assert methods because of quotation hell +# assert_rich_good() { +# local operation="${1}" +#@@ -563,6 +577,22 @@ assert_good "--permanent --direct --remove-chain ipv4 filter ${mychain_ +# assert_bad "--permanent --direct --query-chain ipv4 filter ${mychain_p}" +# assert_good "--permanent --direct --remove-chain ipv4 filter dummy" # removing nonexisting chain is just warning +# +#+rule1="ipv4 nat OUTPUT 0 -s 1.2.3.4 -d 1.2.3.4 -p tcp --dport 80 -j REDIRECT --to-ports 81" +#+rule2="ipv4 nat OUTPUT 0 -s 1.2.3.4 -d 1.2.3.4 -p tcp --dport 80 -j REDIRECT --to-ports 82" +#+assert_good "--permanent --direct --add-rule ${rule1}" +#+assert_good_contains "--permanent --direct --get-all-rules" "${rule1}" +#+assert_good "--reload" +#+assert_good_contains "--direct --get-all-rules" "${rule1}" +#+assert_good "--permanent --direct --remove-rule ${rule1}" +#+assert_good "--permanent --direct --add-rule ${rule2}" +#+assert_good_contains "--permanent --direct --get-all-rules" "${rule2}" +#+assert_good "--reload" +#+assert_bad_contains "--direct --get-all-rules" "${rule1}" +#+assert_good_contains "--direct --get-all-rules" "${rule2}" +#+assert_good "--permanent --direct --remove-rule ${rule2}" +#+assert_good "--reload" +#+assert_bad_contains "--direct --get-all-rules" "${rule2}" +#+ +# # lockdown +# +# cmd="/usr/bin/command" +commit e74cf839be5c51f4d5dec739b92c0c0f11d54f46 +Merge: b5cc946 e32c402 +Author: Thomas Woerner +Date: Mon May 18 13:43:07 2015 +0200 + + Merge pull request #17 from jpopelka/landscape-io + + Fix flaws found by landscape.io + + +commit e85770bf37e785fed2f14839e64929215ffdd40f +Author: Mathieu Le Marec - Pasquet +Date: Tue May 12 18:46:16 2015 +0200 + + Another attempt to fix reload with direct rules. + + This refs #12 #13 + This fixes #14 + + Signed-off-by: Mathieu Le Marec - Pasquet + +diff --git a/src/firewall/core/fw_direct.py b/src/firewall/core/fw_direct.py +index 48dd18f..1e0e009 100644 +--- a/src/firewall/core/fw_direct.py ++++ b/src/firewall/core/fw_direct.py +@@ -88,9 +88,9 @@ class FirewallDirect: + (ipv, table, chain) = chain_id + for (priority, args) in self._rules[chain_id]: + if not self._obj.query_rule(ipv, table, chain, priority, args): +- if not chain_id in rules: ++ if chain_id not in rules: + rules[chain_id] = LastUpdatedOrderedDict() +- rules[chain_id][rule_id] = priority ++ rules[chain_id][(priority, args)] = priority + + for ipv in self._passthroughs: + for args in self._passthroughs[ipv]: diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1183008.patch b/SOURCES/firewalld-0.3.9-RHBZ#1183008.patch new file mode 100644 index 0000000..57f5375 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1183008.patch @@ -0,0 +1,544 @@ +Adapted versions of + +commit d72384cfc3eba7db5739f83a28f3476b9553c856 +Author: Jiri Popelka +Date: Fri Jul 25 14:12:19 2014 +0200 + + Check built-in chains in direct chain handling functions. (RHBZ#1120619) + + also rename ipXtables/ebtables.CHAINS to BUILT_IN_CHAINS + +commit d4c839f838d0772b19d521ff826065e14f9a569d +Author: Jiri Popelka +Date: Mon Aug 4 15:59:54 2014 +0200 + + Direct & LockdownWhitelist: clear() -> cleanup() + + these were renamed in fb656f53bc + +commit fb656f53bc0eac095694ba61af6933632abf0f20 +Author: Thomas Woerner +Date: Tue Oct 22 17:21:55 2013 +0200 + + Fix cleanup and initializations to get leaked memory to 0 at all times + +commit 07550d550e618a3040153341eb8218551c3aa776 +Author: Jiri Popelka +Date: Tue Sep 30 16:39:41 2014 +0200 + + permanent direct: more tests for ipv & table + + see also 9139b468e5 + +commit 9139b468e5ffbe515dfd9892401eadb13a293a0b +Author: Jiri Popelka +Date: Tue Jul 15 18:21:47 2014 +0200 + + FirewallDirect: check ipv & table sooner to provide consistent errors + + thanks to Jakub Jelen + +commit 1a5670befb208018196b4f897fb84033e544f886 +Author: Jiri Popelka +Date: Tue Oct 14 09:46:46 2014 +0200 + + Rich_Rule.check(): action can't be used with icmp-block/forward-port/masquerade + +commit 76751826d97577fe2b41abf8c5448c653df49651 +Author: Thomas Woerner +Date: Tue Feb 11 23:34:09 2014 +0100 + + firewalld: No load failed error for absent direct.xml file + +commit 524438c41fae5a0b239d2273871ffe54c61e65de +Author: Thomas Woerner +Date: Tue Jul 7 13:01:12 2015 +0200 + + fw.py._start: Fix reload with runtime rules, but no direct.xml (RHBZ#1183008) + +diff -up firewalld-0.3.9/src/firewall/core/ebtables.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/ebtables.py +--- firewalld-0.3.9/src/firewall/core/ebtables.py.RHBZ#1183008 2015-07-07 13:10:10.938698154 +0200 ++++ firewalld-0.3.9/src/firewall/core/ebtables.py 2015-07-07 13:10:11.074695768 +0200 +@@ -25,7 +25,7 @@ from firewall.core.logger import log + PROC_IPxTABLE_NAMES = { + } + +-CHAINS = { ++BUILT_IN_CHAINS = { + "broute": [ "BROUTING" ], + "nat": [ "PREROUTING", "POSTROUTING", "OUTPUT" ], + "filter": [ "INPUT", "OUTPUT", "FORWARD" ], +@@ -60,7 +60,7 @@ class ebtables: + + def available_tables(self, table=None): + ret = [] +- tables = [ table ] if table else CHAINS.keys() ++ tables = [ table ] if table else BUILT_IN_CHAINS.keys() + for table in tables: + try: + self.__run(["-t", table, "-L"]) +@@ -71,7 +71,7 @@ class ebtables: + return ret + + def used_tables(self): +- return list(CHAINS.keys()) ++ return list(BUILT_IN_CHAINS.keys()) + + def flush(self): + tables = self.used_tables() +@@ -86,13 +86,13 @@ class ebtables: + if which == "used": + tables = self.used_tables() + else: +- tables = list(CHAINS.keys()) ++ tables = list(BUILT_IN_CHAINS.keys()) + + if "nat" in tables: + tables.remove("nat") # nat can not set policies in nat table + + for table in tables: +- for chain in CHAINS[table]: ++ for chain in BUILT_IN_CHAINS[table]: + self.__run([ "-t", table, "-P", chain, policy ]) + + ebtables_available_tables = ebtables().available_tables() +diff -up firewalld-0.3.9/src/firewall/core/fw_config.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw_config.py +--- firewalld-0.3.9/src/firewall/core/fw_config.py.RHBZ#1183008 2013-12-03 14:59:48.000000000 +0100 ++++ firewalld-0.3.9/src/firewall/core/fw_config.py 2015-07-07 13:13:50.709829789 +0200 +@@ -131,7 +131,7 @@ class FirewallConfig: + + def update_direct(self): + if not os.path.exists(FIREWALLD_DIRECT): +- self._direct.clear() ++ self._direct.cleanup() + else: + self._direct.read() + +diff -up firewalld-0.3.9/src/firewall/core/fw_direct.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw_direct.py +--- firewalld-0.3.9/src/firewall/core/fw_direct.py.RHBZ#1183008 2015-07-07 13:10:11.072695804 +0200 ++++ firewalld-0.3.9/src/firewall/core/fw_direct.py 2015-07-07 13:10:11.075695751 +0200 +@@ -132,9 +132,41 @@ class FirewallDirect: + except FirewallError as error: + log.warning(str(error)) + ++ def _check_ipv(self, ipv): ++ ipvs = ['ipv4', 'ipv6', 'eb'] ++ if ipv not in ipvs: ++ raise FirewallError(INVALID_IPV, ++ "'%s' not in '%s'" % (ipv, ipvs)) ++ ++ def _check_ipv_table(self, ipv, table): ++ self._check_ipv(ipv) ++ ++ tables = ipXtables.BUILT_IN_CHAINS.keys() if ipv in [ 'ipv4', 'ipv6' ] \ ++ else ebtables.BUILT_IN_CHAINS.keys() ++ if table not in tables: ++ raise FirewallError(INVALID_TABLE, ++ "'%s' not in '%s'" % (table, tables)) ++ ++ def _check_builtin_chain(self, ipv, table, chain): ++ if ipv in ['ipv4', 'ipv6']: ++ built_in_chains = ipXtables.BUILT_IN_CHAINS[table] ++ our_chains = ipXtables.OUR_CHAINS[table] ++ else: ++ built_in_chains = ebtables.BUILT_IN_CHAINS[table] ++ our_chains = ebtables.OUR_CHAINS[table] ++ if chain in built_in_chains: ++ raise FirewallError(BUILTIN_CHAIN, ++ "chain '%s' is built-in chain" % chain) ++ if chain in our_chains: ++ raise FirewallError(BUILTIN_CHAIN, ++ "chain '%s' is reserved" % chain) ++ ++ + # DIRECT CHAIN + + def __chain(self, add, ipv, table, chain): ++ self._check_ipv_table(ipv, table) ++ self._check_builtin_chain(ipv, table, chain) + table_id = (ipv, table) + + if add: +@@ -174,11 +206,14 @@ class FirewallDirect: + self.__chain(False, ipv, table, chain) + + def query_chain(self, ipv, table, chain): ++ self._check_ipv_table(ipv, table) ++ self._check_builtin_chain(ipv, table, chain) + table_id = (ipv, table) +- return (table_id in self._chains and \ +- chain in self._chains[table_id]) ++ return (table_id in self._chains and ++ chain in self._chains[table_id]) + + def get_chains(self, ipv, table): ++ self._check_ipv_table(ipv, table) + table_id = (ipv, table) + if table_id in self._chains: + return self._chains[table_id] +@@ -195,13 +230,14 @@ class FirewallDirect: + # DIRECT RULE + + def __rule(self, enable, ipv, table, chain, priority, args): ++ self._check_ipv_table(ipv, table) + _chain = chain + # use "%s_chain" for built-in chains + + if ipv in [ "ipv4", "ipv6" ]: +- _CHAINS = ipXtables.CHAINS ++ _CHAINS = ipXtables.BUILT_IN_CHAINS + else: +- _CHAINS = ebtables.CHAINS ++ _CHAINS = ebtables.BUILT_IN_CHAINS + + if table in _CHAINS and chain in _CHAINS[table]: + _chain = "%s_direct" % (chain) +@@ -303,11 +339,13 @@ class FirewallDirect: + self.__rule(False, ipv, table, chain, priority, args) + + def query_rule(self, ipv, table, chain, priority, args): ++ self._check_ipv_table(ipv, table) + chain_id = (ipv, table, chain) + return (chain_id in self._rules and \ + (priority, args) in self._rules[chain_id]) + + def get_rules(self, ipv, table, chain): ++ self._check_ipv_table(ipv, table) + chain_id = (ipv, table, chain) + if chain_id in self._rules: + return list(self._rules[chain_id].keys()) +@@ -332,12 +370,6 @@ class FirewallDirect: + + # DIRECT PASSTHROUGH (tracked) + +- def _check_ipv(self, ipv): +- ipvs = [ 'ipv4', 'ipv6', 'eb' ] +- if ipv not in ipvs: +- raise FirewallError(INVALID_IPV, +- "'%s' not in '%s'" % (ipv, ipvs)) +- + def __passthrough(self, enable, ipv, args): + self._check_ipv(ipv) + +diff -up firewalld-0.3.9/src/firewall/core/fw.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw.py +--- firewalld-0.3.9/src/firewall/core/fw.py.RHBZ#1183008 2015-07-07 13:10:11.072695804 +0200 ++++ firewalld-0.3.9/src/firewall/core/fw.py 2015-07-07 13:10:11.075695751 +0200 +@@ -203,15 +203,16 @@ class Firewall: + self.zone.apply_zones() + + # load direct rules +- log.debug1("Loading direct rules file '%s'" % FIREWALLD_DIRECT) + obj = Direct(FIREWALLD_DIRECT) +- try: +- obj.read() +- except Exception as msg: +- log.debug1("Failed to load direct rules file '%s': %s", +- FIREWALLD_DIRECT, msg) +- else: +- self.direct.set_permanent_config(obj) ++ if os.path.exists(FIREWALLD_DIRECT): ++ log.debug1("Loading direct rules file '%s'" % FIREWALLD_DIRECT) ++ try: ++ obj.read() ++ except Exception as msg: ++ log.debug1("Failed to load direct rules file '%s': %s", ++ FIREWALLD_DIRECT, msg) ++ ++ self.direct.set_permanent_config(obj) + self.config.set_direct(copy.deepcopy(obj)) + + # check if default_zone is a valid zone +@@ -394,7 +395,7 @@ class Firewall: + rule.pop(1) + + table = None +- for t in ipXtables.CHAINS.keys(): ++ for t in ipXtables.BUILT_IN_CHAINS.keys(): + if t in rule: + table = t + if table and not self.is_table_available(ipv, table): +diff -up firewalld-0.3.9/src/firewall/core/fw_zone.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/fw_zone.py +--- firewalld-0.3.9/src/firewall/core/fw_zone.py.RHBZ#1183008 2015-07-07 13:10:11.068695874 +0200 ++++ firewalld-0.3.9/src/firewall/core/fw_zone.py 2015-07-07 13:10:11.076695733 +0200 +@@ -26,7 +26,8 @@ from firewall.functions import portStr, + checkProtocol, enable_ip_forwarding, check_single_address + from firewall.core.rich import * + from firewall.errors import * +-from firewall.core.ipXtables import ip4tables_available_tables, ip6tables_available_tables ++from firewall.core.ipXtables import ip4tables_available_tables,\ ++ ip6tables_available_tables, OUR_CHAINS + + mangle = [] + if "mangle" in ip4tables_available_tables: +@@ -187,6 +188,10 @@ class FirewallZone: + ipvs.append("ipv6") + + for ipv in ipvs: ++ OUR_CHAINS[table].update(set([_zone, ++ "%s_log" % _zone, ++ "%s_deny" % _zone, ++ "%s_allow" % _zone])) + chains.append((ipv, [ _zone, "-t", table ])) + chains.append((ipv, [ "%s_log" % (_zone), "-t", table ])) + chains.append((ipv, [ "%s_deny" % (_zone), "-t", table ])) +diff -up firewalld-0.3.9/src/firewall/core/io/direct.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/io/direct.py +--- firewalld-0.3.9/src/firewall/core/io/direct.py.RHBZ#1183008 2015-07-07 13:10:11.030696540 +0200 ++++ firewalld-0.3.9/src/firewall/core/io/direct.py 2015-07-07 13:10:11.076695733 +0200 +@@ -29,6 +29,9 @@ from firewall.functions import splitArgs + from firewall.errors import * + from firewall.core.io.io_object import * + from firewall.core.logger import log ++from firewall.core import ipXtables ++from firewall.core import ebtables ++ + + class direct_ContentHandler(IO_Object_ContentHandler): + def __init__(self, item): +@@ -188,9 +191,25 @@ class Direct(IO_Object): + for args in self.passthroughs[key]: + print (" ('%s')" % ("','".join(args))) + ++ def _check_ipv(self, ipv): ++ ipvs = ['ipv4', 'ipv6', 'eb'] ++ if ipv not in ipvs: ++ raise FirewallError(INVALID_IPV, ++ "'%s' not in '%s'" % (ipv, ipvs)) ++ ++ def _check_ipv_table(self, ipv, table): ++ self._check_ipv(ipv) ++ ++ tables = ipXtables.BUILT_IN_CHAINS.keys() if ipv in ['ipv4', 'ipv6'] \ ++ else ebtables.BUILT_IN_CHAINS.keys() ++ if table not in tables: ++ raise FirewallError(INVALID_TABLE, ++ "'%s' not in '%s'" % (table, tables)) ++ + # chains + + def add_chain(self, ipv, table, chain): ++ self._check_ipv_table(ipv, table) + key = (ipv, table) + if key not in self.chains: + self.chains[key] = [ ] +@@ -202,6 +221,7 @@ class Direct(IO_Object): + + "already in list, ignoring") + + def remove_chain(self, ipv, table, chain): ++ self._check_ipv_table(ipv, table) + key = (ipv, table) + if key in self.chains and chain in self.chains[key]: + self.chains[key].remove(chain) +@@ -213,10 +233,12 @@ class Direct(IO_Object): + (chain, table, ipv)) + + def query_chain(self, ipv, table, chain): ++ self._check_ipv_table(ipv, table) + key = (ipv, table) + return (key in self.chains and chain in self.chains[key]) + + def get_chains(self, ipv, table): ++ self._check_ipv_table(ipv, table) + key = (ipv, table) + if key in self.chains: + return self.chains[key] +@@ -230,6 +252,7 @@ class Direct(IO_Object): + # rules + + def add_rule(self, ipv, table, chain, priority, args): ++ self._check_ipv_table(ipv, table) + key = (ipv, table, chain) + if key not in self.rules: + self.rules[key] = LastUpdatedOrderedDict() +@@ -243,6 +266,7 @@ class Direct(IO_Object): + + "already in list, ignoring") + + def remove_rule(self, ipv, table, chain, priority, args): ++ self._check_ipv_table(ipv, table) + key = (ipv, table, chain) + value = (priority, tuple(args)) + if key in self.rules and value in self.rules[key]: +@@ -255,6 +279,7 @@ class Direct(IO_Object): + "with ipv '%s' and priority %d not in list" % (ipv, priority)) + + def remove_rules(self, ipv, table, chain): ++ self._check_ipv_table(ipv, table) + key = (ipv, table, chain) + if key in self.rules: + for value in self.rules[key].keys(): +@@ -263,11 +288,13 @@ class Direct(IO_Object): + del self.rules[key] + + def query_rule(self, ipv, table, chain, priority, args): ++ self._check_ipv_table(ipv, table) + key = (ipv, table, chain) + value = (priority, tuple(args)) + return (key in self.rules and value in self.rules[key]) + + def get_rules(self, ipv, table, chain): ++ self._check_ipv_table(ipv, table) + key = (ipv, table, chain) + if key in self.rules: + return self.rules[key] +@@ -281,6 +308,7 @@ class Direct(IO_Object): + # # passthrough + # + def add_passthrough(self, ipv, args): ++ self._check_ipv(ipv) + if ipv not in self.passthroughs: + self.passthroughs[ipv] = [ ] + if args not in self.passthroughs[ipv]: +@@ -291,6 +319,7 @@ class Direct(IO_Object): + + "already in list, ignoring") + + def remove_passthrough(self, ipv, args): ++ self._check_ipv(ipv) + if ipv in self.passthroughs and args in self.passthroughs[ipv]: + self.passthroughs[ipv].remove(args) + if len(self.passthroughs[ipv]) == 0: +@@ -300,9 +329,11 @@ class Direct(IO_Object): + ("',".join(args), ipv) + "not in list" + + def query_passthrough(self, ipv, args): ++ self._check_ipv(ipv) + return (ipv in self.passthroughs and args in self.passthroughs[ipv]) + + def get_passthroughs(self, ipv): ++ self._check_ipv(ipv) + if ipv in self.passthroughs: + return self.passthroughs[ipv] + else: +diff -up firewalld-0.3.9/src/firewall/core/ipXtables.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/ipXtables.py +--- firewalld-0.3.9/src/firewall/core/ipXtables.py.RHBZ#1183008 2015-07-07 13:10:11.066695909 +0200 ++++ firewalld-0.3.9/src/firewall/core/ipXtables.py 2015-07-07 13:10:11.076695733 +0200 +@@ -34,7 +34,7 @@ PROC_IPxTABLE_NAMES = { + "ipv6": "/proc/net/ip6_tables_names", + } + +-CHAINS = { ++BUILT_IN_CHAINS = { + "security": [ "INPUT", "OUTPUT", "FORWARD" ], + "raw": [ "PREROUTING", "OUTPUT" ], + "mangle": [ "PREROUTING", "POSTROUTING", "INPUT", "OUTPUT", "FORWARD" ], +@@ -53,38 +53,49 @@ ICMP = { + } + + DEFAULT_RULES = { } ++OUR_CHAINS = {} # chains created by firewalld + + DEFAULT_RULES["security"] = [ ] +-for chain in CHAINS["security"]: ++OUR_CHAINS["security"] = set() ++for chain in BUILT_IN_CHAINS["security"]: + DEFAULT_RULES["security"].append("-N %s_direct" % chain) + DEFAULT_RULES["security"].append("-I %s 1 -j %s_direct" % (chain, chain)) ++ OUR_CHAINS["security"].add("%s_direct" % chain) + + DEFAULT_RULES["raw"] = [ ] +-for chain in CHAINS["raw"]: ++OUR_CHAINS["raw"] = set() ++for chain in BUILT_IN_CHAINS["raw"]: + DEFAULT_RULES["raw"].append("-N %s_direct" % chain) + DEFAULT_RULES["raw"].append("-I %s 1 -j %s_direct" % (chain, chain)) ++ OUR_CHAINS["raw"].add("%s_direct" % chain) + + DEFAULT_RULES["mangle"] = [ ] +-for chain in CHAINS["mangle"]: ++OUR_CHAINS["mangle"] = set() ++for chain in BUILT_IN_CHAINS["mangle"]: + DEFAULT_RULES["mangle"].append("-N %s_direct" % chain) + DEFAULT_RULES["mangle"].append("-I %s 1 -j %s_direct" % (chain, chain)) ++ OUR_CHAINS["mangle"].add("%s_direct" % chain) + + if chain == "PREROUTING": + DEFAULT_RULES["mangle"].append("-N %s_ZONES_SOURCE" % chain) + DEFAULT_RULES["mangle"].append("-N %s_ZONES" % chain) + DEFAULT_RULES["mangle"].append("-I %s 2 -j %s_ZONES_SOURCE" % (chain, chain)) + DEFAULT_RULES["mangle"].append("-I %s 3 -j %s_ZONES" % (chain, chain)) ++ OUR_CHAINS["mangle"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain])) + + DEFAULT_RULES["nat"] = [ ] +-for chain in CHAINS["nat"]: ++OUR_CHAINS["nat"] = set() ++for chain in BUILT_IN_CHAINS["nat"]: + DEFAULT_RULES["nat"].append("-N %s_direct" % chain) + DEFAULT_RULES["nat"].append("-I %s 1 -j %s_direct" % (chain, chain)) ++ OUR_CHAINS["nat"].add("%s_direct" % chain) + + if chain in [ "PREROUTING", "POSTROUTING" ]: + DEFAULT_RULES["nat"].append("-N %s_ZONES_SOURCE" % chain) + DEFAULT_RULES["nat"].append("-N %s_ZONES" % chain) + DEFAULT_RULES["nat"].append("-I %s 2 -j %s_ZONES_SOURCE" % (chain, chain)) + DEFAULT_RULES["nat"].append("-I %s 3 -j %s_ZONES" % (chain, chain)) ++ OUR_CHAINS["nat"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain])) + + DEFAULT_RULES["filter"] = [ + "-N INPUT_direct", +@@ -119,6 +130,11 @@ DEFAULT_RULES["filter"] = [ + + "-I OUTPUT 1 -j OUTPUT_direct", + ] ++OUR_CHAINS["filter"] = set(["INPUT_direct", "INPUT_ZONES_SOURCE", "INPUT_ZONES", ++ "FORWARD_direct", "FORWARD_IN_ZONES_SOURCE", ++ "FORWARD_IN_ZONES", "FORWARD_OUT_ZONES_SOURCE", ++ "FORWARD_OUT_ZONES", "OUTPUT_direct"]) ++ + + class ip4tables: + ipv = "ipv4" +@@ -151,7 +167,7 @@ class ip4tables: + + def available_tables(self, table=None): + ret = [] +- tables = [ table ] if table else CHAINS.keys() ++ tables = [ table ] if table else BUILT_IN_CHAINS.keys() + for table in tables: + try: + self.__run(["-t", table, "-L"]) +@@ -199,13 +215,13 @@ class ip4tables: + if which == "used": + tables = self.used_tables() + else: +- tables = list(CHAINS.keys()) ++ tables = list(BUILT_IN_CHAINS.keys()) + + if "nat" in tables: + tables.remove("nat") # nat can not set policies in nat table + + for table in tables: +- for chain in CHAINS[table]: ++ for chain in BUILT_IN_CHAINS[table]: + self.__run([ "-t", table, "-P", chain, policy ]) + + class ip6tables(ip4tables): +diff -up firewalld-0.3.9/src/firewall/core/rich.py.RHBZ#1183008 firewalld-0.3.9/src/firewall/core/rich.py +--- firewalld-0.3.9/src/firewall/core/rich.py.RHBZ#1183008 2015-07-07 13:10:11.070695839 +0200 ++++ firewalld-0.3.9/src/firewall/core/rich.py 2015-07-07 13:10:11.076695733 +0200 +@@ -481,6 +481,8 @@ class Rich_Rule(object): + elif type(self.element) == Rich_Masquerade: + if self.destination != None: + raise FirewallError(INVALID_RULE, "masquerade and destination") ++ if self.action: ++ raise FirewallError(INVALID_RULE, "masquerade and action") + + # icmp-block + elif type(self.element) == Rich_IcmpBlock: +@@ -488,8 +490,8 @@ class Rich_Rule(object): + # knowledge about this, therefore only simple check + if self.element.name == None or len(self.element.name) < 1: + raise FirewallError(INVALID_ICMPTYPE, str(self.element.name)) +- if self.action and type(self.action) == Rich_Accept: +- raise FirewallError(INVALID_RULE, "icmpblock and accept") ++ if self.action: ++ raise FirewallError(INVALID_RULE, "icmp-block and action") + + # forward-port + elif type(self.element) == Rich_ForwardPort: +@@ -508,6 +510,8 @@ class Rich_Rule(object): + raise FirewallError(INVALID_ADDR, self.element.to_address) + if self.family == None: + raise FirewallError(INVALID_FAMILY) ++ if self.action: ++ raise FirewallError(INVALID_RULE, "forward-port and action") + + # other element and not empty? + elif self.element != None: diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1183688.patch b/SOURCES/firewalld-0.3.9-RHBZ#1183688.patch new file mode 100644 index 0000000..555c17b --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1183688.patch @@ -0,0 +1,43 @@ +Adapted verison of + +commit 6302c06317a42338fb6ce19cf313d8eda2833378 +Author: Jiri Popelka +Date: Wed Jan 21 17:24:22 2015 +0100 + + Change Polkit domain of some methods from PK_ACTION_DIRECT to PK_ACTION_DIRECT_INFO (RHBZ#1184463) + + queryPassthrough() + getAllPassthroughs() + getPassthroughs() + +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index aa7bef0..7d02671 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1821,7 +1821,7 @@ class FirewallD(slip.dbus.service.Object): + self.fw.direct.remove_passthrough(ipv, args) + self.PassthroughRemoved(ipv, args) + +- @slip.dbus.polkit.require_auth(PK_ACTION_DIRECT) ++ @slip.dbus.polkit.require_auth(PK_ACTION_INFO) + @dbus_service_method(DBUS_INTERFACE_DIRECT, in_signature='sas', + out_signature='b') + @dbus_handle_exceptions +@@ -1833,7 +1833,7 @@ class FirewallD(slip.dbus.service.Object): + (ipv, "','".join(args))) + return self.fw.direct.query_passthrough(ipv, args) + +- @slip.dbus.polkit.require_auth(PK_ACTION_DIRECT) ++ @slip.dbus.polkit.require_auth(PK_ACTION_INFO) + @dbus_service_method(DBUS_INTERFACE_DIRECT, in_signature='', + out_signature='a(sas)') + @dbus_handle_exceptions +@@ -1852,7 +1852,7 @@ class FirewallD(slip.dbus.service.Object + for passthrough in self.getAllPassthroughs(): + self.removePassthrough(*passthrough) + +- @slip.dbus.polkit.require_auth(PK_ACTION_DIRECT) ++ @slip.dbus.polkit.require_auth(PK_ACTION_INFO) + @dbus_service_method(DBUS_INTERFACE_DIRECT, in_signature='s', + out_signature='aas') + @dbus_handle_exceptions diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1194382.patch b/SOURCES/firewalld-0.3.9-RHBZ#1194382.patch new file mode 100644 index 0000000..d28b48e --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1194382.patch @@ -0,0 +1,40 @@ +commit 3580db37e9bc1b6a8784902717e82895b8038c90 +Author: Antoni S. Puimedon +Date: Tue Oct 7 19:53:46 2014 +0200 + + services: Add vdsm's service configuration + + oVirt's Virtual Desktop and Server Manager is the daemon that sits + on each hypervisor host to control VM lifecycle, storage and + networking. In order to do that, it needs to have some ports open. + This patch adds it as a default service. + + Signed-off-by: Antoni S. Puimedon + Signed-off-by: Jiri Popelka + +#diff --git a/config/Makefile.am b/config/Makefile.am +#index 9ab014b..1670b06 100644 +#--- a/config/Makefile.am +#+++ b/config/Makefile.am +#@@ -124,6 +124,7 @@ EXTRA_DIST = \ +# services/tftp.xml \ +# services/tor-socks.xml \ +# services/transmission-client.xml \ +#+ services/vdsm.xml \ +# services/vnc-server.xml \ +# services/wbem-https.xml \ +# services/xmpp-bosh.xml \ +diff --git a/config/services/vdsm.xml b/config/services/vdsm.xml +new file mode 100644 +index 0000000..6d28077 +--- /dev/null ++++ b/config/services/vdsm.xml +@@ -0,0 +1,8 @@ ++ ++ ++ oVirt's Virtual Desktop and Server Manager ++ The VDSM service is required by a Virtualization Manager to manage the Linux hosts. VDSM manages and monitors the host's storage, memory and networks as well as virtual machine creation, other host administration tasks, statistics gathering, and log collection. ++ ++ ++ ++ diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1206490.patch b/SOURCES/firewalld-0.3.9-RHBZ#1206490.patch new file mode 100644 index 0000000..a216fc3 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1206490.patch @@ -0,0 +1,58 @@ +commit 410f7540e4dc69fc8602a7057a83ee1f799b043f +Author: Thomas Woerner +Date: Wed May 28 16:51:04 2014 +0200 + + New services for freeipa-ldap, freeipa-ldaps and freeipa-replication + + Thanks to Stephen Gallagher + +diff --git a/config/services/freeipa-ldap.xml b/config/services/freeipa-ldap.xml +new file mode 100644 +index 0000000..c176966 +--- /dev/null ++++ b/config/services/freeipa-ldap.xml +@@ -0,0 +1,13 @@ ++ ++ ++ FreeIPA with LDAP ++ FreeIPA is an LDAP and Kerberos domain controller for Linux systems. Enable this option if you plan to provide a FreeIPA Domain Controller using the LDAP protocol. You can also enable the 'freeipa-ldaps' service if you want to provide the LDAPS protocol. Enable the 'dns' service if this FreeIPA server provides DNS services and 'freeipa-replication' service if this FreeIPA server is part of a multi-master replication setup. ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/config/services/freeipa-ldaps.xml b/config/services/freeipa-ldaps.xml +new file mode 100644 +index 0000000..c355fe9 +--- /dev/null ++++ b/config/services/freeipa-ldaps.xml +@@ -0,0 +1,13 @@ ++ ++ ++ FreeIPA with LDAPS ++ FreeIPA is an LDAP and Kerberos domain controller for Linux systems. Enable this option if you plan to provide a FreeIPA Domain Controller using the LDAPS protocol. You can also enable the 'freeipa-ldap' service if you want to provide the LDAP protocol. Enable the 'dns' service if this FreeIPA server provides DNS services and 'freeipa-replication' service if this FreeIPA server is part of a multi-master replication setup. ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/config/services/freeipa-replication.xml b/config/services/freeipa-replication.xml +new file mode 100644 +index 0000000..7e8c4f1 +--- /dev/null ++++ b/config/services/freeipa-replication.xml +@@ -0,0 +1,6 @@ ++ ++ ++ FreeIPA replication ++ FreeIPA is an LDAP and Kerberos domain controller for Linux systems. Enable this option if you want to enable LDAP replication between FreeIPA servers. ++ ++ diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1217678.patch b/SOURCES/firewalld-0.3.9-RHBZ#1217678.patch new file mode 100644 index 0000000..c2cd255 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1217678.patch @@ -0,0 +1,1004 @@ +commit d34ba69740071bfbe920914b55b1c822fc5516e6 +Author: Jiri Popelka +Date: Tue Feb 25 18:40:56 2014 +0100 + + firewall-offline-cmd(1): document new options + +diff --git a/doc/xml/firewall-offline-cmd.xml b/doc/xml/firewall-offline-cmd.xml +index dbd09da..7b6f3ea 100644 +--- a/doc/xml/firewall-offline-cmd.xml ++++ b/doc/xml/firewall-offline-cmd.xml +@@ -114,7 +114,7 @@ + + + +- General Options ++ Lokkit Compatibility Options + + + =module +@@ -251,6 +251,984 @@ + + + ++ ++ ++ Zone Options ++ ++ ++ ++ ++ ++ Print default zone for connections and interfaces. ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ Set default zone for connections and interfaces where no zone has been selected. Setting the default zone changes the zone for the connections or interfaces, that are using the default zone. ++ ++ ++ ++ ++ ++ ++ ++ ++ Print predefined zones as a space separated list. ++ ++ ++ ++ ++ ++ ++ ++ ++ Print predefined services as a space separated list. ++ ++ ++ ++ ++ ++ ++ ++ ++ Print predefined icmptypes as a space separated list. ++ ++ ++ ++ ++ ++ =interface ++ ++ ++ Print the name of the zone the interface is bound to or no zone. ++ ++ ++ ++ ++ ++ =source/mask ++ ++ ++ Print the name of the zone the source/mask is bound to or no zone. ++ ++ ++ ++ ++ ++ ++ ++ ++ List everything added for or enabled in all zones. The output format is: ++ ++zone1 ++ interfaces: interface1 .. ++ sources: source1 .. ++ services: service1 .. ++ ports: port1 .. ++ forward-ports: ++ forward-port1 ++ .. ++ icmp-blocks: icmp-type1 .. ++ rich rules: ++ rich-rule1 ++ .. ++.. ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ Add a new permanent zone. ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ Delete an existing permanent zone. ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ Get the target of a permanent zone. ++ ++ ++ ++ ++ ++ =zone =zone ++ ++ ++ Set the target of a permanent zone. ++ ++ ++ ++ ++ ++ ++ ++ Options to Adapt and Query Zones ++ ++ Options in this section affect only one particular zone. If used with =zone option, they affect the zone zone. If the option is omitted, they affect default zone (see ). ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ List everything added for or enabled in zone. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ List services added for zone as a space separated list. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =service ++ ++ ++ Add a service for zone. If zone is omitted, default zone will be used. This option can be specified multiple times. ++ ++ ++ The service is one of the firewalld provided services. To get a list of the supported services, use firewall-cmd --get-services. ++ ++ ++ ++ ++ ++ =zone =service ++ ++ ++ Remove a service from zone. This option can be specified multiple times. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =service ++ ++ ++ Return whether service has been added for zone. If zone is omitted, default zone will be used. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ List ports added for zone as a space separated list. A port is of the form portid-portid/protocol, it can be either a port and protocol pair or a port range with a protocol. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =portid-portid/protocol ++ ++ ++ Add the port for zone. If zone is omitted, default zone will be used. This option can be specified multiple times. ++ ++ ++ The port can either be a single port number or a port range portid-portid. The protocol can either be tcp or udp. ++ ++ ++ ++ ++ ++ =zone =portid-portid/protocol ++ ++ ++ Remove the port from zone. If zone is omitted, default zone will be used. This option can be specified multiple times. ++ ++ ++ ++ ++ ++ =zone =portid-portid/protocol ++ ++ ++ Return whether the port has been added for zone. If zone is omitted, default zone will be used. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ List Internet Control Message Protocol (ICMP) type blocks added for zone as a space separated list. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =icmptype ++ ++ ++ Add an ICMP block for icmptype for zone. If zone is omitted, default zone will be used. This option can be specified multiple times. ++ ++ ++ The icmptype is the one of the icmp types firewalld supports. To get a listing of supported icmp types: firewall-cmd --get-icmptypes ++ ++ ++ ++ ++ ++ =zone =icmptype ++ ++ ++ Remove the ICMP block for icmptype from zone. If zone is omitted, default zone will be used. This option can be specified multiple times. ++ ++ ++ ++ ++ ++ =zone =icmptype ++ ++ ++ Return whether an ICMP block for icmptype has been added for zone. If zone is omitted, default zone will be used. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ List IPv4 forward ports added for zone as a space separated list. If zone is omitted, default zone will be used. ++ ++ ++ For IPv6 forward ports, please use the rich language. ++ ++ ++ ++ ++ ++ =zone =port=portid-portid:proto=protocol:toport=portid-portid:toaddr=address/mask ++ ++ ++ Add the IPv4 forward port for zone. If zone is omitted, default zone will be used. This option can be specified multiple times. ++ ++ ++ The port can either be a single port number portid or a port range portid-portid. The protocol can either be tcp or udp. The destination address is a simple IP address. ++ ++ ++ For IPv6 forward ports, please use the rich language. ++ ++ ++ ++ ++ ++ =zone =port=portid-portid:proto=protocol:toport=portid-portid:toaddr=address/mask ++ ++ ++ Remove the IPv4 forward port from zone. If zone is omitted, default zone will be used. This option can be specified multiple times. ++ ++ ++ For IPv6 forward ports, please use the rich language. ++ ++ ++ ++ ++ ++ =zone =port=portid-portid:proto=protocol:toport=portid-portid:toaddr=address/mask ++ ++ ++ Return whether the IPv4 forward port has been added for zone. If zone is omitted, default zone will be used. Returns 0 if true, 1 otherwise. ++ ++ ++ For IPv6 forward ports, please use the rich language. ++ ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ Enable IPv4 masquerade for zone. If zone is omitted, default zone will be used. Masquerading is useful if the machine is a router and machines connected over an interface in another zone should be able to use the first connection. ++ ++ ++ For IPv6 masquerading, please use the rich language. ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ Disable IPv4 masquerade for zone. If zone is omitted, default zone will be used. ++ ++ ++ For IPv6 masquerading, please use the rich language. ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ Return whether IPv4 masquerading has been enabled for zone. If zone is omitted, default zone will be used. Returns 0 if true, 1 otherwise. ++ ++ ++ For IPv6 masquerading, please use the rich language. ++ ++ ++ ++ ++ ++ ++ ++ =zone ++ ++ ++ List rich language rules added for zone as a newline separated list. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone ='rule' ++ ++ ++ Add rich language rule 'rule' for zone. This option can be specified multiple times. If zone is omitted, default zone will be used. ++ ++ ++ For the rich language rule syntax, please have a look at firewalld.richlanguage5. ++ ++ ++ ++ ++ ++ =zone ='rule' ++ ++ ++ Remove rich language rule 'rule' from zone. This option can be specified multiple times. If zone is omitted, default zone will be used. ++ ++ ++ For the rich language rule syntax, please have a look at firewalld.richlanguage5. ++ ++ ++ ++ ++ ++ =zone ='rule' ++ ++ ++ Return whether a rich language rule 'rule' has been added for zone. If zone is omitted, default zone will be used. Returns 0 if true, 1 otherwise. ++ ++ ++ For the rich language rule syntax, please have a look at firewalld.richlanguage5. ++ ++ ++ ++ ++ ++ ++ ++ Options to Handle Bindings of Interfaces ++ ++ Binding an interface to a zone means that this zone settings are used to restrict traffic via the interface. ++ ++ ++ Options in this section affect only one particular zone. If used with =zone option, they affect the zone zone. If the option is omitted, they affect default zone (see ). ++ ++ ++ For a list of predefined zones use firewall-cmd --get-zones. ++ ++ ++ An interface name is a string up to 16 characters long, that may not contain , , and . ++ ++ ++ ++ =zone ++ ++ ++ List interfaces that are bound to zone zone as a space separated list. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =interface ++ ++ ++ Bind interface interface to zone zone. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =interface ++ ++ ++ Change zone the interface interface is bound to to zone zone. If zone is omitted, default zone will be used. If old and new zone are the same, the call will be ignored without an error. If the interface has not been bound to a zone before, it will behave like . ++ ++ ++ ++ ++ ++ =zone =interface ++ ++ ++ Query whether interface interface is bound to zone zone. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ =zone =interface ++ ++ ++ Remove binding of interface interface from zone zone. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ ++ ++ Options to Handle Bindings of Sources ++ ++ Binding a source to a zone means that this zone settings will be used to restrict traffic from this source. ++ ++ ++ A source address or address range is either an IP address or a network IP address with a mask for IPv4 or IPv6. For IPv4, the mask can be a network mask or a plain number. For IPv6 the mask is a plain number. The use of host names is not supported. ++ ++ ++ Options in this section affect only one particular zone. If used with =zone option, they affect the zone zone. If the option is omitted, they affect default zone (see ). ++ ++ ++ For a list of predefined zones use firewall-cmd --get-zones. ++ ++ ++ ++ =zone ++ ++ ++ List sources that are bound to zone zone as a space separated list. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =source/mask ++ ++ ++ Bind source source/mask to zone zone. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ =zone =source/mask ++ ++ ++ Change zone the source source/mask is bound to to zone zone. If zone is omitted, default zone will be used. If old and new zone are the same, the call will be ignored without an error. If the source has not been bound to a zone before, it will behave like . ++ ++ ++ ++ ++ ++ =zone =source/mask ++ ++ ++ Query whether the source source/mask is bound to the zone zone. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ =zone =source/mask ++ ++ ++ Remove binding of source source/mask from zone zone. If zone is omitted, default zone will be used. ++ ++ ++ ++ ++ ++ ++ ++ Service Options ++ ++ ++ =service ++ ++ ++ Add a new permanent service. ++ ++ ++ ++ ++ ++ =service ++ ++ ++ Delete an existing permanent service. ++ ++ ++ ++ ++ ++ ++ ++ Internet Control Message Protocol (ICMP) type Options ++ ++ ++ =icmptype ++ ++ ++ Add a new permanent icmptype. ++ ++ ++ ++ ++ ++ =icmptype ++ ++ ++ Delete an existing permanent icmptype. ++ ++ ++ ++ ++ ++ ++ ++ Direct Options ++ ++ The direct options give a more direct access to the firewall. These options require user to know basic iptables concepts, i.e. table (filter/mangle/nat/...), chain (INPUT/OUTPUT/FORWARD/...), commands (-A/-D/-I/...), parameters (-p/-s/-d/-j/...) and targets (ACCEPT/DROP/REJECT/...). ++ ++ ++ Direct options should be used only as a last resort when it's not possible to use for example =service or ='rule'. ++ ++ ++ The first argument of each option has to be ipv4 or ipv6 or eb. With ipv4 it will be for IPv4 (iptables8), with ipv6 for IPv6 (ip6tables8) and with eb for ethernet bridges (ebtables8). ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Get all chains added to all tables. ++ ++ ++ This option concerns only chains previously added with . ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table ++ ++ ++ Get all chains added to table table as a space separated list. ++ ++ ++ This option concerns only chains previously added with . ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain ++ ++ ++ Add a new chain with name chain to table table. ++ ++ ++ There already exist basic chains to use with direct options, for example INPUT_direct chain (see iptables-save | grep direct output for all of them). ++ These chains are jumped into before chains for zones, i.e. every rule put into INPUT_direct will be checked before rules in zones. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain ++ ++ ++ Remove the chain with name chain from table table. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain ++ ++ ++ Return whether a chain with name chain exists in table table. Returns 0 if true, 1 otherwise. ++ ++ ++ This option concerns only chains previously added with . ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Get all rules added to all chains in all tables as a newline separated list of the priority and arguments. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain ++ ++ ++ Get all rules added to chain chain in table table as a newline separated list of the priority and arguments. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain priority args ++ ++ ++ Add a rule with the arguments args to chain chain in table table with priority priority. ++ ++ ++ The priority is used to order rules. Priority 0 means add rule on top of the chain, with a higher priority the rule will be added further down. Rules with the same priority are on the same level and the order of these rules is not fixed and may change. If you want to make sure that a rule will be added after another one, use a low priority for the first and a higher for the following. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain priority args ++ ++ ++ Remove a rule with priority and the arguments args from chain chain in table table. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain ++ ++ ++ Remove all rules in the chain with name chain exists in table table. ++ ++ ++ This option concerns only rules previously added with in this chain. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } table chain priority args ++ ++ ++ Return whether a rule with priority and the arguments args exists in chain chain in table table. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Get all permanent passthrough as a newline separated list of the ipv value and arguments. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } ++ ++ ++ Get all permanent passthrough rules for the ipv value as a newline separated list of the priority and arguments. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } args ++ ++ ++ Add a permanent passthrough rule with the arguments args for the ipv value. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } args ++ ++ ++ Remove a permanent passthrough rule with the arguments args for the ipv value. ++ ++ ++ ++ ++ ++ { ipv4 | ipv6 | eb } args ++ ++ ++ Return whether a permanent passthrough rule with the arguments args exists for the ipv value. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ Lockdown Options ++ ++ Local applications or services are able to change the firewall configuration if they are running as root (example: libvirt) or are authenticated using PolicyKit. With this feature administrators can lock the firewall configuration so that only applications on lockdown whitelist are able to request firewall changes. ++ ++ ++ The lockdown access check limits D-Bus methods that are changing firewall rules. Query, list and get methods are not limited. ++ ++ ++ The lockdown feature is a very light version of user and application policies for firewalld and is turned off by default. ++ ++ ++ ++ ++ ++ ++ Enable lockdown. Be careful - if firewall-cmd is not on lockdown whitelist when you enable lockdown you won't be able to disable it again with firewall-cmd, you would need to edit firewalld.conf. ++ ++ ++ ++ ++ ++ ++ ++ ++ Disable lockdown. ++ ++ ++ ++ ++ ++ ++ ++ ++ Query whether lockdown is enabled. Returns 0 if lockdown is enabled, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ Lockdown Whitelist Options ++ ++ The lockdown whitelist can contain commands, contexts, users and user ids. ++ ++ ++ If a command entry on the whitelist ends with an asterisk '*', then all command lines starting with the command will match. If the '*' is not there the absolute command inclusive arguments must match. ++ ++ ++ Commands for user root and others is not always the same. Example: As root /bin/firewall-cmd is used, as a normal user /usr/bin/firewall-cmd is be used on Fedora. ++ ++ ++ The context is the security (SELinux) context of a running application or service. To get the context of a running application use ps -e --context. ++ ++ ++ Warning: If the context is unconfined, then this will open access for more than the desired application. ++ ++ ++ The lockdown whitelist entries are checked in the following order: ++ ++ 1. context ++ 2. uid ++ 3. user ++ 4. command ++ ++ ++ ++ ++ ++ ++ ++ List all command lines that are on the whitelist. ++ ++ ++ ++ ++ ++ =command ++ ++ ++ Add the command to the whitelist. ++ ++ ++ ++ ++ ++ =command ++ ++ ++ Remove the command from the whitelist. ++ ++ ++ ++ ++ ++ =command ++ ++ ++ Query whether the command is on the whitelist. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ ++ List all contexts that are on the whitelist. ++ ++ ++ ++ ++ ++ =context ++ ++ ++ Add the context context to the whitelist. ++ ++ ++ ++ ++ ++ =context ++ ++ ++ Remove the context from the whitelist. ++ ++ ++ ++ ++ ++ =context ++ ++ ++ Query whether the context is on the whitelist. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ ++ List all user ids that are on the whitelist. ++ ++ ++ ++ ++ ++ =uid ++ ++ ++ Add the user id uid to the whitelist. ++ ++ ++ ++ ++ ++ =uid ++ ++ ++ Remove the user id uid from the whitelist. ++ ++ ++ ++ ++ ++ =uid ++ ++ ++ Query whether the user id uid is on the whitelist. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ ++ ++ ++ List all user names that are on the whitelist. ++ ++ ++ ++ ++ ++ =user ++ ++ ++ Add the user name user to the whitelist. ++ ++ ++ ++ ++ ++ =user ++ ++ ++ Remove the user name user from the whitelist. ++ ++ ++ ++ ++ ++ =user ++ ++ ++ Query whether the user name user is on the whitelist. Returns 0 if true, 1 otherwise. ++ ++ ++ ++ ++ ++ + + + &seealso; diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1254531.patch b/SOURCES/firewalld-0.3.9-RHBZ#1254531.patch new file mode 100644 index 0000000..2213bc1 --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1254531.patch @@ -0,0 +1,11 @@ +diff -up firewalld-0.3.9/config/services/RH-Satellite-6.xml.RHBZ#1254531 firewalld-0.3.9/config/services/RH-Satellite-6.xml +--- firewalld-0.3.9/config/services/RH-Satellite-6.xml.RHBZ#1254531 2015-09-09 17:20:48.513883419 +0200 ++++ firewalld-0.3.9/config/services/RH-Satellite-6.xml 2015-09-10 16:45:47.218281022 +0200 +@@ -4,6 +4,7 @@ + Red Hat Satellite 6 is a systems management server that can be used to configure new systems, subscribe to updates, and maintain installations in distributed environments. + + ++ + + + diff --git a/SOURCES/firewalld-0.3.9-RHBZ#1261502.patch b/SOURCES/firewalld-0.3.9-RHBZ#1261502.patch new file mode 100644 index 0000000..536854b --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#1261502.patch @@ -0,0 +1,734 @@ +diff -up firewalld-0.3.9/src/tests/firewall-cmd_test.sh.RHBZ#1261502 firewalld-0.3.9/src/tests/firewall-cmd_test.sh +--- firewalld-0.3.9/src/tests/firewall-cmd_test.sh.RHBZ#1261502 2015-09-09 17:20:20.935578859 +0200 ++++ firewalld-0.3.9/src/tests/firewall-cmd_test.sh 2015-09-09 17:18:24.729287573 +0200 +@@ -0,0 +1,730 @@ ++#!/bin/bash ++ ++#readonly path="/usr/bin/" ++readonly path="../" ++ ++readonly RED='\033[00;31m' ++readonly GREEN='\033[00;32m' ++readonly RESTORE='\033[0m' ++ ++assert_good() { ++ local args="${1}" ++ ++ ${path}firewall-cmd ${args} > /dev/null ++ if [[ "$?" -eq 0 ]]; then ++ echo "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e "${args} ... ${RED}${failures}. FAILED (non-zero exit status)${RESTORE}" ++ fi ++} ++ ++assert_good_notempty() { ++ local args="${1}" ++ local ret ++ ++ ret=$(${path}firewall-cmd ${args}) > /dev/null ++ if [[ ( "$?" -eq 0 ) && ( -n "${ret}" ) ]]; then ++ echo "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e "${args} ... ${RED}${failures}. FAILED (non-zero exit status or empty return value)${RESTORE}" ++ fi ++} ++ ++assert_good_empty() { ++ local args="${1}" ++ local ret ++ ++ ret=$(${path}firewall-cmd ${args}) > /dev/null ++ if [[ ( "$?" -eq 0 ) && ( -z "${ret}" ) ]]; then ++ echo "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e "${args} ... ${RED}${failures}. FAILED (non-zero exit status or non-empty return value)${RESTORE}" ++ fi ++} ++ ++assert_good_equals() { ++ local args="${1}" ++ local value="${2}" ++ local ret ++ ++ ret=$(${path}firewall-cmd ${args}) > /dev/null ++ if [[ ( "$?" -eq 0 ) && ( "${ret}" = "${value}" ) ]]; then ++ echo "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e "${args} ... ${RED}${failures}. FAILED (non-zero exit status or '${ret}' != '${value}')${RESTORE}" ++ fi ++} ++ ++assert_good_contains() { ++ local args="${1}" ++ local value="${2}" ++ local ret ++ ++ ret=$(${path}firewall-cmd ${args}) > /dev/null ++ if [[ ( "$?" -eq 0 ) && ( "${ret}" = *${value}* ) ]]; then ++ echo "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e "${args} ... ${RED}${failures}. FAILED (non-zero exit status or '${ret}' does not contain '${value}')${RESTORE}" ++ fi ++} ++ ++assert_bad() { ++ local args="${1}" ++ ++ ${path}firewall-cmd ${args} 1> /dev/null 2>&1 ++ if [[ "$?" -ne 0 ]]; then ++ echo "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e "${args} ... ${RED}${failures}. FAILED (zero exit status)${RESTORE}" ++ fi ++} ++ ++assert_bad_contains() { ++ local args="${1}" ++ local value="${2}" ++ local ret ++ ++ ret=$(${path}firewall-cmd ${args}) > /dev/null ++ if [[ ( "$?" -ne 0 ) || ( "${ret}" = *${value}* ) ]]; then ++ ((failures++)) ++ echo -e "${args} ... ${RED}${failures}. FAILED (non-zero exit status or '${ret}' does contain '${value}')${RESTORE}" ++ else ++ echo "${args} ... OK" ++ fi ++} ++ ++# rich rules need separate assert methods because of quotation hell ++assert_rich_good() { ++ local operation="${1}" ++ local args="${2}" ++ local command ++ local permanent ++ ++ [[ "${operation}" = *permanent* ]] && permanent="--permanent" ++ if [[ "${operation}" = *add* ]]; then ++ command="--add-rich-rule" ++ elif [[ "${operation}" = *remove* ]]; then ++ command="--remove-rich-rule" ++ elif [[ "${operation}" = *query* ]]; then ++ command="--query-rich-rule" ++ fi ++ ++ ${path}firewall-cmd ${permanent} ${command} "${args}" > /dev/null ++ if [[ "$?" -eq 0 ]]; then ++ echo ${permanent} ${command} "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e ${permanent} ${command} "${args} ... ${RED}${failures}. FAILED (non-zero exit status)${RESTORE}" ++ fi ++} ++ ++assert_rich_bad() { ++ local operation="${1}" ++ local args="${2}" ++ local command ++ local permanent ++ ++ [[ "${operation}" = *permanent* ]] && permanent="--permanent" ++ if [[ "${operation}" = *add* ]]; then ++ command="--add-rich-rule" ++ elif [[ "${operation}" = *remove* ]]; then ++ command="--remove-rich-rule" ++ elif [[ "${operation}" = *query* ]]; then ++ command="--query-rich-rule" ++ fi ++ ++ ${path}firewall-cmd ${permanent} ${command} "${args}" > /dev/null ++ if [[ "$?" -ne 0 ]]; then ++ echo ${permanent} ${command} "${args} ... OK" ++ else ++ ((failures++)) ++ echo -e ${permanent} ${command} "${args} ... ${RED}${failures}. FAILED (zero exit status)${RESTORE}" ++ fi ++} ++ ++if ! ${path}firewall-cmd --state --quiet; then ++ echo "FirewallD is not running" ++ exit 1 ++fi ++ ++# MAIN ++failures=0 ++ ++assert_good "-h" ++assert_good "--help" ++assert_good "-V" ++assert_good "--reload" ++assert_good "--complete-reload" ++assert_good "--panic-on" ++assert_good "--query-panic" ++assert_good "--panic-off" ++assert_bad "--query-panic" ++#assert_good "--lockdown-on" ++#assert_good "--query-lockdown" ++#assert_good "--lockdown-off" ++#assert_bad "--query-lockdown" ++ ++default_zone=$(${path}firewall-cmd --get-default-zone) ++zone="home" ++assert_good_notempty "--get-default-zone" ++assert_good "--set-default-zone=${zone}" ++assert_good_equals "--get-default-zone" "${zone}" ++assert_good "--set-default-zone=${default_zone}" ++assert_bad "--set-default-zone" # missing argument ++ ++assert_good_notempty "--get-zones" ++assert_good_notempty "--get-services" ++assert_good_notempty "--get-icmptypes" ++ ++assert_good_notempty "--permanent --get-zones" ++assert_good_notempty "--permanent --get-services" ++assert_good_notempty "--permanent --get-icmptypes" ++ ++assert_good "--list-all-zones" ++assert_good "--list-all" ++assert_good "--permanent --list-all-zones" ++assert_good "--permanent --list-all" ++ ++iface="dummy0" ++zone="work" ++assert_good "--zone=${zone} --add-interface=${iface}" ++assert_good_equals "--get-zone-of-interface=${iface}" "${zone}" ++assert_good_contains "--get-active-zones" "${zone}" ++assert_good "--zone ${zone} --query-interface=${iface}" ++zone="public" ++assert_good "--zone=${zone} --change-interface=${iface}" ++assert_good_equals "--get-zone-of-interface=${iface}" "${zone}" ++zone="dmz" ++assert_good "--zone=${zone} --change-zone=${iface}" ++assert_good_equals "--get-zone-of-interface=${iface}" "${zone}" ++assert_good_contains "--zone=${zone} --list-interfaces" "${iface}" ++assert_good "--zone=${zone} --remove-interface=${iface}" ++assert_bad "--zone=${zone} --query-interface ${iface}" ++assert_good "--zone=${zone} --change-interface=${iface}" # should work as add ++assert_good "--zone=${zone} --query-interface ${iface}" ++assert_good "--zone=${zone} --remove-interface=${iface}" ++assert_bad "--zone=${zone} --query-interface ${iface}" ++assert_bad "--get-zone-of-interface=${iface}" # in no zone ++assert_bad "--get-zone-of-interface" # missing argument ++assert_bad "--zone=${zone} --get-zones" # impossible combination ++assert_bad "--zone=${zone} --get-services" # impossible combination ++assert_bad "--zone=${zone} --get-default-zone" # impossible combination ++assert_bad "--zone=${zone} --set-default-zone" # impossible combination ++assert_bad "--zone=${zone} --get-zone-of-interface" # impossible combination ++ ++iface="perm_dummy0" ++zone="work" ++assert_good "--permanent --zone=${zone} --add-interface=${iface}" ++assert_good_equals "--permanent --get-zone-of-interface=${iface}" "${zone}" ++assert_good "--permanent --zone ${zone} --query-interface=${iface}" ++assert_good_contains "--permanent --zone=${zone} --list-interfaces" "${iface}" ++zone="public" ++assert_bad "--permanent --zone=${zone} --add-interface=${iface}" # already in another zone ++assert_good "--permanent --zone=${zone} --change-interface=${iface}" ++assert_good_equals "--permanent --get-zone-of-interface=${iface}" "${zone}" ++assert_good "--permanent --zone=${zone} --remove-interface=${iface}" ++assert_bad "--permanent --zone=${zone} --query-interface ${iface}" ++assert_good "--permanent --zone=${zone} --change-interface=${iface}" # should work as add ++assert_good_equals "--permanent --get-zone-of-interface=${iface}" "${zone}" ++assert_good "--permanent --zone=${zone} --remove-interface=${iface}" ++assert_bad "--permanent --zone=${zone} --query-interface ${iface}" ++ ++iface1="foo" ++iface2="bar" ++zone="trusted" ++assert_good "--add-interface=${iface1}" ++assert_good "--add-interface=${iface2} --zone=${default_zone}" ++assert_good "--set-default-zone=${zone}" ++assert_good_equals "--get-default-zone" "${zone}" ++# check that changing default zone moves interfaces in that zone ++assert_good "--query-interface ${iface1} --zone=${zone}" ++# check that *only* iface1 was moved to new default zone ++assert_good "--query-interface ${iface2} --zone=${default_zone}" ++assert_good "--set-default-zone=${default_zone}" ++assert_good "--remove-interface=${iface1}" ++assert_good "--remove-interface=${iface2}" ++ ++sources=( "dead:beef::babe" "3ffe:501:ffff::/64" "1.2.3.4" "192.168.1.0/24" ) ++for (( i=0;i<${#sources[@]};i++)); do ++ zone="public" ++ source=${sources[${i}]} ++ assert_good "--zone=${zone} --add-source=${source}" ++ assert_good_equals "--get-zone-of-source=${source}" "${zone}" ++ assert_good_contains "--zone=${zone} --list-sources" "${source}" ++ assert_good_contains "--zone=${zone} --list-all" "${source}" ++ assert_good_contains "--get-active-zones" "${source}" ++ assert_good "--zone ${zone} --query-source=${source}" ++ zone="work" ++ assert_good "--zone=${zone} --change-source=${source}" ++ assert_good_equals "--get-zone-of-source=${source}" "${zone}" ++ assert_good "--zone=${zone} --remove-source=${source}" ++ assert_bad "--zone ${zone} --query-source=${source}" ++ assert_bad "--get-zone-of-source=${source}" # in no zone ++ assert_bad "--get-zone-of-source" # missing argument ++done ++ ++for (( i=0;i<${#sources[@]};i++)); do ++ zone="public" ++ source=${sources[${i}]} ++ assert_good "--permanent --zone=${zone} --add-source=${source}" ++ assert_good_equals "--permanent --get-zone-of-source=${source}" "${zone}" ++ assert_good_contains "--permanent --zone=${zone} --list-sources" "${source}" ++ assert_good_contains "--permanent --zone=${zone} --list-all" "${source}" ++ assert_good "--permanent --zone ${zone} --query-source=${source}" ++ zone="work" ++ assert_bad "--permanent --zone=${zone} --add-source=${source}" # already in another zone ++ assert_good "--permanent --zone=${zone} --change-source=${source}" ++ assert_good_equals "--permanent --get-zone-of-source=${source}" "${zone}" ++ assert_good "--permanent --zone=${zone} --remove-source=${source}" ++ assert_bad "--permanent --zone ${zone} --query-source=${source}" ++done ++ ++assert_good " --add-service=dns --timeout 60 --zone=${default_zone}" ++assert_good " --query-service dns" ++assert_good "--remove-service=dns" ++assert_bad " --query-service=dns" ++assert_bad " --add-service=smtps" # bad service name ++assert_bad " --add-service=dns --timeout" # missing argument ++assert_bad " --add-service=dns --add-interface=dummy0" # impossible combination ++ ++assert_bad "--permanent --zone=external --add-service=dns --timeout 60" # impossible combination ++assert_good "--permanent --zone=external --add-service dns" ++assert_good_contains "--permanent --zone=external --list-services" "dns" ++assert_good "--permanent --zone=external --query-service dns" ++assert_good "--permanent --zone=external --remove-service=dns" ++assert_bad "--permanent --zone=external --query-service=dns" # removed ++assert_bad "--permanent --zone=external --add-service=smtps" # bad service name ++assert_bad "--permanent --zone=external --add-service=dns --add-interface=dummy0" # impossible combination ++ ++assert_good " --add-service=http --add-service=nfs --timeout=1h" ++assert_good " --query-service http" ++assert_good " --query-service=nfs --zone=${default_zone}" ++assert_good "--remove-service=nfs --remove-service=http" ++assert_bad " --query-service http" ++assert_bad " --query-service nfs" ++ ++assert_good "--permanent --add-service=http --add-service=nfs" ++assert_good "--permanent --query-service http" ++assert_good "--permanent --query-service=nfs --zone=${default_zone}" ++assert_good "--permanent --remove-service=nfs --remove-service=http" ++assert_bad "--permanent --query-service http" ++assert_bad "--permanent --query-service nfs" ++ ++assert_bad " --add-port=666" # no protocol ++assert_bad " --add-port=666/dummy" # bad protocol ++assert_good " --add-port=666/tcp --zone=${default_zone} --timeout=30m" ++assert_good "--remove-port=666/tcp" ++assert_good " --add-port=111-222/udp" ++assert_good " --query-port=111-222/udp --zone=${default_zone}" ++assert_good "--remove-port 111-222/udp" ++assert_bad " --query-port=111-222/udp" ++ ++assert_bad "--permanent --add-port=666" # no protocol ++assert_bad "--permanent --add-port=666/dummy" # bad protocol ++assert_good "--permanent --add-port=666/tcp" ++assert_good "--permanent --remove-port=666/tcp --zone=${default_zone}" ++assert_good "--permanent --add-port=111-222/udp --zone=${default_zone}" ++assert_good "--permanent --query-port=111-222/udp" ++assert_good "--permanent --remove-port 111-222/udp" ++assert_bad "--permanent --query-port=111-222/udp" ++ ++assert_good " --add-port=80/tcp --add-port 443-444/udp" ++assert_good " --query-port=80/tcp --zone=${default_zone}" ++assert_good " --query-port=443-444/udp" ++assert_good "--remove-port 80/tcp --remove-port=443-444/udp" ++assert_bad " --query-port=80/tcp" ++assert_bad " --query-port=443-444/udp" ++ ++assert_good "--permanent --add-port=80/tcp --add-port 443-444/udp" ++assert_good "--permanent --query-port=80/tcp --zone=${default_zone}" ++assert_good "--permanent --query-port=443-444/udp" ++assert_good "--permanent --remove-port 80/tcp --remove-port=443-444/udp" ++assert_bad "--permanent --query-port=80/tcp" ++assert_bad "--permanent --query-port=443-444/udp" ++ ++assert_good " --add-masquerade --zone=${default_zone}" ++assert_good " --query-masquerade " ++assert_good "--remove-masquerade" ++assert_bad " --query-masquerade" ++ ++assert_good "--permanent --add-masquerade" ++assert_good "--permanent --query-masquerade --zone=${default_zone}" ++assert_good "--permanent --remove-masquerade --zone=${default_zone}" ++assert_bad "--permanent --query-masquerade" ++ ++assert_bad "--zone=external --add-icmp-block=dummyblock" # invalid icmp type ++assert_good "--zone=external --add-icmp-block=redirect" ++assert_good "--zone=external --query-icmp-block=redirect" ++assert_good "--zone=external --remove-icmp-block redirect" ++assert_bad "--zone=external --query-icmp-block=redirect" ++ ++assert_bad "--permanent --zone=external --add-icmp-block=dummyblock" # invalid icmp type ++assert_good "--permanent --zone=external --add-icmp-block=redirect" ++assert_good "--permanent --zone=external --query-icmp-block=redirect" ++assert_good "--permanent --zone=external --remove-icmp-block redirect" ++assert_bad "--permanent --zone=external --query-icmp-block=redirect" ++ ++assert_good "--zone=external --add-icmp-block=echo-reply --add-icmp-block=router-solicitation" ++assert_good "--zone=external --query-icmp-block=echo-reply" ++assert_good "--zone=external --query-icmp-block=router-solicitation" ++assert_good "--zone=external --remove-icmp-block echo-reply --remove-icmp-block=router-solicitation" ++assert_bad "--zone=external --query-icmp-block=echo-reply" ++assert_bad "--zone=external --query-icmp-block=router-solicitation" ++ ++assert_good "--permanent --zone=external --add-icmp-block=echo-reply --add-icmp-block=router-solicitation" ++assert_good "--permanent --zone=external --query-icmp-block=echo-reply" ++assert_good "--permanent --zone=external --query-icmp-block=router-solicitation" ++assert_good "--permanent --zone=external --remove-icmp-block echo-reply --remove-icmp-block=router-solicitation" ++assert_bad "--permanent --zone=external --query-icmp-block=echo-reply" ++assert_bad "--permanent --zone=external --query-icmp-block=router-solicitation" ++ ++assert_bad " --add-forward-port=666" # no protocol ++assert_good " --add-forward-port=port=11:proto=tcp:toport=22" ++assert_good "--remove-forward-port=port=11:proto=tcp:toport=22 --zone=${default_zone}" ++assert_bad " --add-forward-port=port=33:proto=tcp:toaddr=4444" # bad address ++assert_good " --add-forward-port=port=33:proto=tcp:toaddr=4.4.4.4 --zone=${default_zone}" ++assert_good "--remove-forward-port=port=33:proto=tcp:toaddr=4.4.4.4" ++assert_good " --add-forward-port=port=55:proto=tcp:toport=66:toaddr=7.7.7.7" ++assert_good " --query-forward-port port=55:proto=tcp:toport=66:toaddr=7.7.7.7 --zone=${default_zone}" ++assert_good "--remove-forward-port=port=55:proto=tcp:toport=66:toaddr=7.7.7.7" ++assert_bad " --query-forward-port=port=55:proto=tcp:toport=66:toaddr=7.7.7.7" ++ ++assert_bad "--permanent --add-forward-port=666" # no protocol ++assert_good "--permanent --add-forward-port=port=11:proto=tcp:toport=22 --zone=${default_zone}" ++assert_good "--permanent --remove-forward-port=port=11:proto=tcp:toport=22" ++assert_bad "--permanent --add-forward-port=port=33:proto=tcp:toaddr=4444" # bad address ++assert_good "--permanent --add-forward-port=port=33:proto=tcp:toaddr=4.4.4.4" ++assert_good "--permanent --remove-forward-port=port=33:proto=tcp:toaddr=4.4.4.4 --zone=${default_zone}" ++assert_good "--permanent --add-forward-port=port=55:proto=tcp:toport=66:toaddr=7.7.7.7" ++assert_good "--permanent --query-forward-port port=55:proto=tcp:toport=66:toaddr=7.7.7.7" ++assert_good "--permanent --remove-forward-port=port=55:proto=tcp:toport=66:toaddr=7.7.7.7" ++assert_bad "--permanent --query-forward-port=port=55:proto=tcp:toport=66:toaddr=7.7.7.7" ++ ++assert_good " --add-forward-port=port=88:proto=udp:toport=99 --add-forward-port port=100:proto=tcp:toport=200" ++assert_good " --query-forward-port=port=100:proto=tcp:toport=200" ++assert_good " --query-forward-port=port=88:proto=udp:toport=99 --zone=${default_zone}" ++assert_good "--remove-forward-port port=100:proto=tcp:toport=200 --remove-forward-port=port=88:proto=udp:toport=99" ++assert_bad " --query-forward-port port=100:proto=tcp:toport=200" ++assert_bad " --query-forward-port=port=88:proto=udp:toport=99" ++ ++assert_good "--permanent --add-forward-port=port=88:proto=udp:toport=99 --add-forward-port port=100:proto=tcp:toport=200" ++assert_good "--permanent --query-forward-port=port=100:proto=tcp:toport=200" ++assert_good "--permanent --query-forward-port=port=88:proto=udp:toport=99 --zone=${default_zone}" ++assert_good "--permanent --remove-forward-port port=100:proto=tcp:toport=200 --remove-forward-port=port=88:proto=udp:toport=99" ++assert_bad "--permanent --query-forward-port port=100:proto=tcp:toport=200" ++assert_bad "--permanent --query-forward-port=port=88:proto=udp:toport=99" ++ ++assert_good_contains "--zone=home --list-services" "ssh" ++assert_good "--zone home --list-ports" ++assert_good "--list-icmp-blocks" ++assert_good "--zone=home --list-forward-ports" ++ ++assert_good_contains "--permanent --zone=work --list-services" "ssh" ++assert_good "--permanent --list-forward-ports" ++ ++assert_bad "--permanent --complete-reload" # impossible combination ++ ++myzone="myzone" ++myservice="myservice" ++myicmp="myicmp" ++ ++# create new zone ++assert_bad "--new-zone=${myzone}" # no --permanent ++assert_good "--permanent --new-zone=${myzone}" ++assert_good_contains "--permanent --get-zones" "${myzone}" ++# get/set default target ++assert_good_contains "--permanent --zone=${myzone} --get-target" "default" ++assert_bad "--permanent --zone=${myzone} --set-target=BAD" ++assert_good "--permanent --zone=${myzone} --set-target=%%REJECT%%" ++assert_good "--permanent --zone=${myzone} --set-target=DROP" ++assert_good "--permanent --zone=${myzone} --set-target=ACCEPT" ++assert_good_contains "--permanent --zone=${myzone} --get-target" "ACCEPT" ++# create new service and icmptype ++assert_good "--permanent --new-service=${myservice}" ++assert_good_contains "--permanent --get-services" "${myservice}" ++assert_good "--permanent --new-icmptype=${myicmp}" ++assert_good_contains "--permanent --get-icmptypes" "${myicmp}" ++# add them to zone ++assert_good "--permanent --zone=${myzone} --add-service=${myservice}" ++assert_good "--permanent --zone=${myzone} --add-icmp-block=${myicmp}" ++assert_good_contains "--permanent --zone=${myzone} --list-services" "${myservice}" ++assert_good_contains "--permanent --zone=${myzone} --list-icmp-blocks" "${myicmp}" ++# delete the service and icmptype ++assert_good "--permanent --delete-service=${myservice}" ++assert_good "--permanent --delete-icmptype=${myicmp}" ++# make sure they were removed also from the zone ++assert_good_empty "--permanent --zone=${myzone} --list-services" "${myservice}" ++assert_good_empty "--permanent --zone=${myzone} --list-icmp-blocks" "${myicmp}" ++assert_good "--permanent --delete-zone=${myzone}" ++ ++ ++# ... --direct ... ++modprobe dummy ++assert_good "--direct --passthrough ipv4 --table mangle --append POSTROUTING --out-interface dummy0 --protocol udp --destination-port 68 --jump CHECKSUM --checksum-fill" ++assert_good "--direct --passthrough ipv4 --table mangle --delete POSTROUTING --out-interface dummy0 --protocol udp --destination-port 68 --jump CHECKSUM --checksum-fill" ++ ++assert_bad "--direct --add-passthrough ipv7 --table filter -A INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" # bad ipv ++assert_good "--direct --add-passthrough ipv4 --table filter --append INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" ++assert_bad "--direct --query-passthrough ipv7 --table filter -A INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" # bad ipv ++assert_good "--direct --query-passthrough ipv4 --table filter --append INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" ++assert_bad "--direct --remove-passthrough ipv7 --table filter -A INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" # bad ipv ++assert_good "--direct --remove-passthrough ipv4 --table filter --append INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" ++assert_bad "--direct --query-passthrough ipv4 --table filter --append INPUT --in-interface dummy0 --protocol tcp --destination-port 67 --jump ACCEPT" ++ ++assert_good "--direct --add-passthrough ipv6 --table filter --append FORWARD --destination fd00:dead:beef:ff0::/64 --in-interface dummy0 --out-interface dummy0 --jump ACCEPT" ++assert_good_contains "--direct --get-passthroughs ipv6" "fd00:dead:beef:ff0::/64" ++assert_good_contains "--direct --get-all-passthroughs" "fd00:dead:beef:ff0::/64" ++assert_good_contains "--direct --passthrough ipv6 -nvL" "fd00:dead:beef:ff0::/64" ++assert_good "--direct --remove-passthrough ipv6 --table filter --delete FORWARD --destination fd00:dead:beef:ff0::/64 --in-interface dummy0 --out-interface dummy0 --jump ACCEPT" ++ ++assert_bad "--direct --passthrough ipv5 -nvL" # ipv5 ++assert_bad "--direct --passthrough ipv4" # missing argument ++ ++assert_good "--direct --add-chain ipv4 filter mychain" ++assert_good_contains "--direct --get-chains ipv4 filter" "mychain" ++assert_good_contains "--direct --get-all-chains" "ipv4 filter mychain" ++assert_good "--direct --query-chain ipv4 filter mychain" ++assert_bad "--direct --add-chain ipv5 filter mychain" # bad ipv ++assert_bad "--direct --add-chain ipv4 badtable mychain" # bad table name ++ ++assert_good "--direct --add-rule ipv4 filter mychain 3 -j ACCEPT" ++assert_good_contains "--direct --get-rules ipv4 filter mychain" "3 -j ACCEPT" ++assert_good_contains "--direct --get-all-rules" "ipv4 filter mychain 3 -j ACCEPT" ++assert_good "--direct --query-rule ipv4 filter mychain 3 -j ACCEPT" ++assert_good "--direct --remove-rule ipv4 filter mychain 3 -j ACCEPT" ++assert_bad "--direct --query-rule ipv4 filter mychain 3 -j ACCEPT" ++assert_bad "--direct --add-rule ipv5 filter mychain 3 -j ACCEPT" # bad ipv ++assert_bad "--direct --add-rule ipv4 badtable mychain 3 -j ACCEPT" # bad table name ++ ++assert_good "--direct --add-rule ipv4 filter mychain 3 -s 192.168.1.1 -j ACCEPT" ++assert_good "--direct --add-rule ipv4 filter mychain 4 -s 192.168.1.2 -j ACCEPT" ++assert_good "--direct --add-rule ipv4 filter mychain 5 -s 192.168.1.3 -j ACCEPT" ++assert_good "--direct --add-rule ipv4 filter mychain 6 -s 192.168.1.4 -j ACCEPT" ++assert_good_contains "--direct --get-rules ipv4 filter mychain" "3 -s 192.168.1.1 -j ACCEPT" ++assert_good_contains "--direct --get-rules ipv4 filter mychain" "4 -s 192.168.1.2 -j ACCEPT" ++assert_good_contains "--direct --get-rules ipv4 filter mychain" "5 -s 192.168.1.3 -j ACCEPT" ++assert_good_contains "--direct --get-rules ipv4 filter mychain" "6 -s 192.168.1.4 -j ACCEPT" ++assert_good "--direct --remove-rules ipv4 filter mychain" ++assert_bad "--direct --query-rule ipv4 filter mychain 3 -s 192.168.1.1 -j ACCEPT" ++assert_bad "--direct --query-rule ipv4 filter mychain 4 -s 192.168.1.2 -j ACCEPT" ++assert_bad "--direct --query-rule ipv4 filter mychain 5 -s 192.168.1.3 -j ACCEPT" ++assert_bad "--direct --query-rule ipv4 filter mychain 6 -s 192.168.1.4 -j ACCEPT" ++ ++assert_bad "--direct --remove-chain ipv5 filter mychain" # bad ipv ++assert_bad "--direct --remove-chain ipv4 badtable mychain" # bad table name ++assert_good "--direct --remove-chain ipv4 filter mychain" ++assert_bad "--direct --query-chain ipv4 filter mychain" ++assert_good "--direct --remove-chain ipv4 filter dummy" # removing nonexisting chain is just warning ++ ++assert_bad "--direct --reload" # impossible combination ++assert_bad "--direct --list-all" # impossible combination ++assert_bad "--direct --get-services" # impossible combination ++assert_bad "--direct --get-default-zone" # impossible combination ++assert_bad "--direct --zone=home --list-services" # impossible combination ++assert_bad "--direct --permanent --list-all" # impossible combination ++assert_bad "--direct --passthrough --get-chains ipv4 filter" # impossible combination ++ ++# ... --permanent --direct ... ++assert_bad "--permanent --direct --add-passthrough ipv4" # missing argument ++assert_bad "--permanent --direct --add-passthrough ipv5 -nvL" # bad ipv ++assert_good "--permanent --direct --add-passthrough ipv4 -nvL" ++assert_good_contains "--permanent --direct --get-passthroughs ipv4" "-nvL" ++assert_good_contains "--permanent --direct --get-all-passthroughs" "ipv4 -nvL" ++assert_good "--permanent --direct --query-passthrough ipv4 -nvL" ++assert_good "--permanent --direct --remove-passthrough ipv4 -nvL" ++assert_bad "--permanent --direct --query-passthrough ipv4 -nvL" ++ ++# try some non-ascii magic ++mychain_p="žluťoučký" ++assert_good "--permanent --direct --add-chain ipv4 filter ${mychain_p}" ++assert_good_contains "--permanent --direct --get-chains ipv4 filter" "${mychain_p}" ++assert_good_contains "--permanent --direct --get-all-chains" "ipv4 filter ${mychain_p}" ++assert_good "--permanent --direct --query-chain ipv4 filter ${mychain_p}" ++assert_bad "--permanent --direct --add-chain ipv5 filter ${mychain_p}" # bad ipv ++assert_bad "--permanent --direct --add-chain ipv4 badtable ${mychain_p}" # bad table name ++ ++assert_good "--permanent --direct --add-rule ipv4 filter ${mychain_p} 3 -j ACCEPT" ++assert_good_contains "--permanent --direct --get-rules ipv4 filter ${mychain_p}" "ACCEPT" ++assert_good_contains "--permanent --direct --get-all-rules" "ipv4 filter ${mychain_p} 3 -j ACCEPT" ++assert_good "--permanent --direct --query-rule ipv4 filter ${mychain_p} 3 -j ACCEPT" ++assert_good "--permanent --direct --remove-rule ipv4 filter ${mychain_p} 3 -j ACCEPT" ++assert_bad "--permanent --direct --query-rule ipv4 filter ${mychain_p} 3 -j ACCEPT" ++assert_bad "--permanent --direct --add-rule ipv5 filter ${mychain_p} 3 -j ACCEPT" # bad ipv ++assert_bad "--permanent --direct --add-rule ipv4 badtable ${mychain_p} 3 -j ACCEPT" # bad table name ++ ++assert_good "--permanent --direct --add-rule ipv4 filter ${mychain_p} 3 -s 192.168.1.1 -j ACCEPT" ++assert_good "--permanent --direct --add-rule ipv4 filter ${mychain_p} 4 -s 192.168.1.2 -j ACCEPT" ++assert_good "--permanent --direct --add-rule ipv4 filter ${mychain_p} 5 -s 192.168.1.3 -j ACCEPT" ++assert_good "--permanent --direct --add-rule ipv4 filter ${mychain_p} 6 -s 192.168.1.4 -j ACCEPT" ++assert_good_contains "--permanent --direct --get-rules ipv4 filter ${mychain_p}" "3 -s 192.168.1.1 -j ACCEPT" ++assert_good_contains "--permanent --direct --get-rules ipv4 filter ${mychain_p}" "4 -s 192.168.1.2 -j ACCEPT" ++assert_good_contains "--permanent --direct --get-rules ipv4 filter ${mychain_p}" "5 -s 192.168.1.3 -j ACCEPT" ++assert_good_contains "--permanent --direct --get-rules ipv4 filter ${mychain_p}" "6 -s 192.168.1.4 -j ACCEPT" ++assert_good "--permanent --direct --remove-rules ipv4 filter ${mychain_p}" ++assert_bad "--permanent --direct --query-rule ipv4 filter ${mychain_p} 3 -s 192.168.1.1 -j ACCEPT" ++assert_bad "--permanent --direct --query-rule ipv4 filter ${mychain_p} 4 -s 192.168.1.2 -j ACCEPT" ++assert_bad "--permanent --direct --query-rule ipv4 filter ${mychain_p} 5 -s 192.168.1.3 -j ACCEPT" ++assert_bad "--permanent --direct --query-rule ipv4 filter ${mychain_p} 6 -s 192.168.1.4 -j ACCEPT" ++ ++assert_bad "--permanent --direct --remove-chain ipv5 filter ${mychain_p}" # bad ipv ++assert_good "--permanent --direct --remove-chain ipv4 filter ${mychain_p}" ++assert_bad "--permanent --direct --query-chain ipv4 filter ${mychain_p}" ++assert_good "--permanent --direct --remove-chain ipv4 filter dummy" # removing nonexisting chain is just warning ++ ++rule1="ipv4 nat OUTPUT 0 -s 1.2.3.4 -d 1.2.3.4 -p tcp --dport 80 -j REDIRECT --to-ports 81" ++rule2="ipv4 nat OUTPUT 0 -s 1.2.3.4 -d 1.2.3.4 -p tcp --dport 80 -j REDIRECT --to-ports 82" ++assert_good "--permanent --direct --add-rule ${rule1}" ++assert_good_contains "--permanent --direct --get-all-rules" "${rule1}" ++assert_good "--reload" ++assert_good_contains "--direct --get-all-rules" "${rule1}" ++assert_good "--permanent --direct --remove-rule ${rule1}" ++assert_good "--permanent --direct --add-rule ${rule2}" ++assert_good_contains "--permanent --direct --get-all-rules" "${rule2}" ++assert_good "--reload" ++assert_bad_contains "--direct --get-all-rules" "${rule1}" ++assert_good_contains "--direct --get-all-rules" "${rule2}" ++assert_good "--permanent --direct --remove-rule ${rule2}" ++assert_good "--reload" ++assert_bad_contains "--direct --get-all-rules" "${rule2}" ++ ++# lockdown ++ ++cmd="/usr/bin/command" ++ctxt="system_u:system_r:MadDaemon_t:s0" ++uid="6666" ++user="theboss" ++ ++assert_good "--add-lockdown-whitelist-command ${cmd}" ++assert_good "--query-lockdown-whitelist-command ${cmd}" ++assert_good_contains "--list-lockdown-whitelist-commands" "${cmd}" ++assert_good "--remove-lockdown-whitelist-command ${cmd}" ++assert_bad "--query-lockdown-whitelist-command ${cmd}" # already removed ++ ++assert_good "--add-lockdown-whitelist-context ${ctxt}" ++assert_good "--query-lockdown-whitelist-context ${ctxt}" ++assert_good_contains "--list-lockdown-whitelist-contexts" "${ctxt}" ++assert_good "--remove-lockdown-whitelist-context ${ctxt}" ++assert_bad "--query-lockdown-whitelist-context ${ctxt}" # already removed ++ ++assert_good "--add-lockdown-whitelist-uid ${uid}" ++assert_good "--query-lockdown-whitelist-uid ${uid}" ++assert_good_contains "--list-lockdown-whitelist-uids" "${uid}" ++assert_good "--remove-lockdown-whitelist-uid ${uid}" ++assert_bad "--query-lockdown-whitelist-uid ${uid}" # already removed ++assert_bad "--add-lockdown-whitelist-uid ${uid}x" # bad uid ++ ++assert_good "--add-lockdown-whitelist-user ${user}" ++assert_good "--query-lockdown-whitelist-user ${user}" ++assert_good_contains "--list-lockdown-whitelist-users" "${user}" ++assert_good "--remove-lockdown-whitelist-user ${user}" ++assert_bad "--query-lockdown-whitelist-user ${user}" # already removed ++ ++assert_good "--permanent --add-lockdown-whitelist-command ${cmd}" ++assert_good "--permanent --query-lockdown-whitelist-command ${cmd}" ++assert_good_contains "--permanent --list-lockdown-whitelist-commands" "${cmd}" ++assert_good "--permanent --remove-lockdown-whitelist-command ${cmd}" ++assert_bad "--permanent --query-lockdown-whitelist-command ${cmd}" # already removed ++ ++assert_good "--permanent --add-lockdown-whitelist-context ${ctxt}" ++assert_good "--permanent --query-lockdown-whitelist-context ${ctxt}" ++assert_good_contains "--permanent --list-lockdown-whitelist-contexts" "${ctxt}" ++assert_good "--permanent --remove-lockdown-whitelist-context ${ctxt}" ++assert_bad "--permanent --query-lockdown-whitelist-context ${ctxt}" # already removed ++ ++assert_good "--permanent --add-lockdown-whitelist-uid ${uid}" ++assert_good "--permanent --query-lockdown-whitelist-uid ${uid}" ++assert_good_contains "--permanent --list-lockdown-whitelist-uids" "${uid}" ++assert_good "--permanent --remove-lockdown-whitelist-uid ${uid}" ++assert_bad "--permanent --query-lockdown-whitelist-uid ${uid}" # already removed ++assert_bad "--permanent --add-lockdown-whitelist-uid ${uid}x" # bad uid ++ ++assert_good "--permanent --add-lockdown-whitelist-user ${user}" ++assert_good "--permanent --query-lockdown-whitelist-user ${user}" ++assert_good_contains "--permanent --list-lockdown-whitelist-users" "${user}" ++assert_good "--permanent --remove-lockdown-whitelist-user ${user}" ++assert_bad "--permanent --query-lockdown-whitelist-user ${user}" # already removed ++ ++ ++# rich rules ++ ++bad_rules=( ++ '' # empty ++ 'family="ipv6" accept' # no 'rule' ++ 'name="dns" accept' # no 'rule' ++ 'protocol value="ah" reject' # no 'rule' ++ 'rule protocol value="ah" reject type="icmp-host-prohibited"' # reject type needs specific family ++ 'rule family="ipv4" protocol value="ah" reject type="dummy"' # dummy reject type ++ 'rule' # no element ++ 'rule bad_element' # no unknown element ++ 'rule family="ipv5"' # bad family ++ 'rule name="dns" accept' # name outside of element ++ 'rule protocol="ah" accept' # bad protocol usage ++ 'rule protocol value="ah" accept drop' # accept && drop ++ 'rule service name="radius" port port="4011" reject' # service && port ++ 'rule service bad_attribute="dns"' # bad attribute ++ 'rule protocol value="mtp" log level="eror"' # bad log level ++ 'rule source address="1:2:3:4:6::" icmp-block name="redirect" log level="info" limit value="1/2m"' # bad limit ++ 'rule protocol value="esp"' # no action/log/audit ++ 'rule family="ipv4" masquerade drop' # masquerade & action ++ 'rule family="ipv4" destination address="192.168.1.0/24" masquerade' # masquerade & destination ++ 'rule family="ipv4" icmp-block name="redirect" accept' # icmp-block & action ++ 'rule forward-port port="2222" to-port="22" protocol="tcp" family="ipv4" accept' # forward-port & action ++) ++ ++for (( i=0;i<${#bad_rules[@]};i++)); do ++ rule=${bad_rules[${i}]} ++ assert_rich_bad "add" "${rule}" ++done ++ ++for (( i=0;i<${#bad_rules[@]};i++)); do ++ rule=${bad_rules[${i}]} ++ assert_rich_bad "permanent add" "${rule}" ++done ++ ++good_rules=( ++ 'rule service name="ftp" audit limit value="1/m" accept' ++ 'rule protocol value="ah" reject' ++ 'rule protocol value="esp" accept' ++ 'rule protocol value="sctp" log' ++ 'rule family="ipv4" source address="192.168.0.0/24" service name="tftp" log prefix="tftp" level="info" limit value="1/m" accept' ++# disable this test as the chenge is not backported yet 'rule family="ipv4" source not address="192.168.0.0/24" service name="dns" log prefix="dns" level="info" limit value="2/m" drop' ++ 'rule family="ipv6" source address="1:2:3:4:6::" service name="radius" log prefix="dns" level="info" limit value="3/m" reject type="icmp6-addr-unreachable" limit value="20/m"' ++ 'rule family="ipv6" source address="1:2:3:4:6::" port port="4011" protocol="tcp" log prefix="port 4011/tcp" level="info" limit value="4/m" drop' ++ 'rule family="ipv6" source address="1:2:3:4:6::" forward-port port="4011" protocol="tcp" to-port="4012" to-addr="1::2:3:4:7"' ++ 'rule family="ipv4" destination address="1.2.3.4" forward-port port="4011" protocol="tcp" to-port="4012" to-addr="9.8.7.6"' ++ 'rule family="ipv4" source address="192.168.0.0/24" icmp-block name="source-quench" log prefix="source-quench" level="info" limit value="4/m"' ++ 'rule family="ipv6" source address="1:2:3:4:6::" icmp-block name="redirect" log prefix="redirect" level="info" limit value="4/m"' ++ 'rule family="ipv4" source address="192.168.1.0/24" masquerade' ++ 'rule family="ipv6" masquerade' ++ 'rule forward-port port="2222" to-port="22" to-addr="192.168.100.2" protocol="tcp" family="ipv4" source address="192.168.2.100"') ++ ++for (( i=0;i<${#good_rules[@]};i++)); do ++ rule=${good_rules[${i}]} ++ assert_rich_good "add" "${rule}" ++ assert_rich_good "query" "${rule}" ++ assert_rich_good "remove" "${rule}" ++ assert_rich_bad "query" "${rule}" ++done ++ ++for (( i=0;i<${#good_rules[@]};i++)); do ++ rule=${good_rules[${i}]} ++ assert_rich_good "permanent add" "${rule}" ++ assert_rich_good "permanent query" "${rule}" ++ assert_rich_good "permanent remove" "${rule}" ++ assert_rich_bad "permanent query" "${rule}" ++done ++ ++echo "----------------------------------------------------------------------" ++if [[ "${failures}" -eq 0 ]]; then ++ echo "Everything's OK, you rock :-)" ++ exit 0 ++else ++ echo "FAILED (failures=${failures})" ++ exit 2 ++fi diff --git a/SOURCES/firewalld-0.3.9-RHBZ#994479.patch b/SOURCES/firewalld-0.3.9-RHBZ#994479.patch new file mode 100644 index 0000000..5faef9e --- /dev/null +++ b/SOURCES/firewalld-0.3.9-RHBZ#994479.patch @@ -0,0 +1,332 @@ +diff -up firewalld-0.3.9/config/Makefile.am.RHBZ#994479 firewalld-0.3.9/config/Makefile.am +--- firewalld-0.3.9/config/Makefile.am.RHBZ#994479 2013-12-03 14:57:26.000000000 +0100 ++++ firewalld-0.3.9/config/Makefile.am 2015-07-06 22:52:11.796675172 +0200 +@@ -21,6 +21,10 @@ gsettings_in_file = org.fedoraproject.Fi + org.fedoraproject.FirewallConfig.gschema.xml.in + gsettings_SCHEMAS = $(gsettings_in_file:.xml.in=.xml) + ++xmlschemadir = $(prefixlibdir)/xmlschema ++dist_xmlschema_DATA = xmlschema/icmptype.xsd xmlschema/service.xsd xmlschema/zone.xsd ++dist_xmlschema_SCRIPTS = xmlschema/check.sh ++ + BUILT_SOURCES = \ + $(desktop_DATA) \ + $(applet_desktop_DATA) \ +diff -up firewalld-0.3.9/config/xmlschema/check.sh.RHBZ#994479 firewalld-0.3.9/config/xmlschema/check.sh +--- firewalld-0.3.9/config/xmlschema/check.sh.RHBZ#994479 2015-07-06 22:53:44.286881231 +0200 ++++ firewalld-0.3.9/config/xmlschema/check.sh 2015-07-06 19:17:33.315427513 +0200 +@@ -0,0 +1,64 @@ ++#!/bin/bash ++ ++# requires libxml2 packages for xmllint ++XMLLINT=/usr/bin/xmllint ++PACKAGE=libxml2 ++ ++prog=$(basename $0) ++BASEDIR=$(realpath $(dirname $0)) ++ ++checkdir=$(pwd) ++while getopts "d:h" arg; do ++ case $arg in ++ d) ++ checkdir=$OPTARG ++ ;; ++ h) ++ cat < Check files in this directory ++ ++EOF ++ exit 0 ++ ;; ++ \?) ++ echo "Invalid option: -$OPTARG" >&2 ++ exit 1 ++ ;; ++ :) ++ echo "Option -$OPTARG requires an argument." >&2 ++ exit 1 ++ ;; ++ esac ++done ++ ++if [ ! -f "$XMLLINT" ]; then ++ echo "$XMLLINT is not installed, please install the $PACKAGE package." ++ exit -1 ++fi ++ ++if [ ! -d "$checkdir" ]; then ++ echo "Directory '${checkdir}' does not exist" ++ exit -2 ++fi ++ ++for keyword in zone service icmptype; do ++ if [ -d "${checkdir}/${keyword}s" ]; then ++ echo "Checking ${keyword}s" ++ cd "${checkdir}/${keyword}s" ++ ls -f *.xml 2>/dev/null | while read -r file; do ++ echo -n " " ++ $XMLLINT --noout --schema "$BASEDIR"/${keyword}.xsd "${file}" ++ done ++ else ++ echo "Directory '${checkdir}/${keyword}s' does not exist" ++ fi ++done +diff -up firewalld-0.3.9/config/xmlschema/icmptype.xsd.RHBZ#994479 firewalld-0.3.9/config/xmlschema/icmptype.xsd +--- firewalld-0.3.9/config/xmlschema/icmptype.xsd.RHBZ#994479 2015-07-06 22:53:52.718900017 +0200 ++++ firewalld-0.3.9/config/xmlschema/icmptype.xsd 2015-07-06 19:17:33.319427521 +0200 +@@ -0,0 +1,29 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -up firewalld-0.3.9/config/xmlschema/service.xsd.RHBZ#994479 firewalld-0.3.9/config/xmlschema/service.xsd +--- firewalld-0.3.9/config/xmlschema/service.xsd.RHBZ#994479 2015-07-06 22:53:58.213912258 +0200 ++++ firewalld-0.3.9/config/xmlschema/service.xsd 2015-07-06 19:17:33.319427521 +0200 +@@ -0,0 +1,53 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -up firewalld-0.3.9/config/xmlschema/zone.xsd.RHBZ#994479 firewalld-0.3.9/config/xmlschema/zone.xsd +--- firewalld-0.3.9/config/xmlschema/zone.xsd.RHBZ#994479 2015-07-06 22:54:05.453928390 +0200 ++++ firewalld-0.3.9/config/xmlschema/zone.xsd 2015-07-06 19:17:33.320427524 +0200 +@@ -0,0 +1,156 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/SPECS/firewalld.spec b/SPECS/firewalld.spec index 4d4fa4c..ba8b7d6 100644 --- a/SPECS/firewalld.spec +++ b/SPECS/firewalld.spec @@ -1,7 +1,7 @@ Summary: A firewall daemon with D-BUS interface providing a dynamic firewall Name: firewalld Version: 0.3.9 -Release: 11%{?dist} +Release: 14%{?dist} URL: http://fedorahosted.org/firewalld License: GPLv2+ Group: System Environment/Base @@ -52,6 +52,22 @@ Patch40: firewalld-0.3.9-RHBZ#993650_add.patch Patch41: firewalld-0.3.9-RHBZ#1127706_add.patch Patch42: firewalld-0.3.9-RHBZ#993650_add2.patch Patch43: firewalld-0.3.9-RHBZ#1057095_add.patch +Patch44: firewalld-0.3.9-RHBZ#994479.patch +Patch45: firewalld-0.3.9-RHBZ#1122739,1128563.patch +Patch46: firewalld-0.3.9-RHBZ#1142741.patch +Patch47: firewalld-0.3.9-RHBZ#1150656.patch +Patch48: firewalld-0.3.9-RHBZ#1150659.patch +Patch49: firewalld-0.3.9-RHBZ#1161745.patch +Patch50: firewalld-0.3.9-RHBZ#1164605.patch +Patch51: firewalld-0.3.9-RHBZ#1176813.patch +Patch52: firewalld-0.3.9-RHBZ#1182671.patch +Patch53: firewalld-0.3.9-RHBZ#1183008.patch +Patch54: firewalld-0.3.9-RHBZ#1183688.patch +Patch55: firewalld-0.3.9-RHBZ#1194382.patch +Patch56: firewalld-0.3.9-RHBZ#1206490.patch +Patch57: firewalld-0.3.9-RHBZ#1217678.patch +Patch58: firewalld-0.3.9-RHBZ#1261502.patch +Patch59: firewalld-0.3.9-RHBZ#1254531.patch BuildArch: noarch BuildRequires: desktop-file-utils @@ -150,6 +166,26 @@ firewalld. %patch41 -p1 -b .RHBZ#1127706_add %patch42 -p1 -b .RHBZ#993650_add2 %patch43 -p1 -b .RHBZ#1057095_add +%patch44 -p1 -b .RHBZ#994479 +chmod 0750 config/xmlschema/check.sh +%patch45 -p1 -b .RHBZ#1122739,1128563 +%patch46 -p1 -b .RHBZ#1142741 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 -b .RHBZ#1161745 +%patch50 -p1 -b .RHBZ#1164605 +%patch51 -p1 -b .RHBZ#1176813 +%patch52 -p1 -b .RHBZ#1182671 +%patch53 -p1 -b .RHBZ#1183008 +%patch54 -p1 -b .RHBZ#1183688 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 -b .RHBZ#1217678 +%patch58 -p1 -b .RHBZ#1261502 +chmod 0755 src/tests/firewall-cmd_test.sh +#-b .RHBZ#1254531 +%patch59 -p1 + %build %configure --enable-sysconfig @@ -218,9 +254,12 @@ fi %attr(0750,root,root) %dir %{_prefix}/lib/firewalld/icmptypes %attr(0750,root,root) %dir %{_prefix}/lib/firewalld/services %attr(0750,root,root) %dir %{_prefix}/lib/firewalld/zones +%attr(0750,root,root) %dir %{_prefix}/lib/firewalld/xmlschema %{_prefix}/lib/firewalld/icmptypes/*.xml %{_prefix}/lib/firewalld/services/*.xml %{_prefix}/lib/firewalld/zones/*.xml +%attr(0750,root,root) %{_prefix}/lib/firewalld/xmlschema/check.sh +%{_prefix}/lib/firewalld/xmlschema/*.xsd %attr(0750,root,root) %dir %{_sysconfdir}/firewalld %config(noreplace) %{_sysconfdir}/firewalld/firewalld.conf %config(noreplace) %{_sysconfdir}/firewalld/lockdown-whitelist.xml @@ -266,6 +305,32 @@ fi %{_mandir}/man1/firewall-config*.1* %changelog +* Tue Sep 15 2015 Thomas Woerner - 0.3.9-14 +- Fixed file mode of schema configuration file verifier check.sh als in files + (RHBZ#994479) + +* Fri Sep 11 2015 Thomas Woerner - 0.3.9-13 +- Fixed file mode of schema configuration file verifier check.sh (RHBZ#994479) +- Include upstream testsuite in SRPM package (RHBZ#1261502) +- Added missing ports to RH-Satellite-6 mservice (RHBZ#1254531) + +* Mon Jul 6 2015 Thomas Woerner - 0.3.9-12 +- New schema configuration file verifier (RHBZ#994479) +- More information about interface handling with and without NetworkManager + (RHBZ#1122739) (RHBZ#1128563) +- Apply all rich rules for non-default targets (RHBZ#1142741) +- New iscsi service (RHBZ#1150656) +- New rsync service (RHBZ#1150659) +- ipXtables: use -w or -w2 if supported (RHBZ#1161745) +- Do not use ipv6header for protocol matching. (RHBZ#1164605) +- Iptables does not like limit of 1/d (RHBZ#1176813) +- Fix readdition of removed permanent direct settings (RHBZ#1182671) +- Fix bugs found by upstream test suite (RHBZ#1183008) +- Fix polkit auth for query and get passthroughs methods (RHBZ#1183688) +- New vdsm service (RHBZ#1194382) +- New freeipa services (RHBZ#1206490) +- Add missing parts to firewall-offline-cmd man page (RHBZ#1217678) + * Tue Jan 13 2015 Thomas Woerner - 0.3.9-11 - added missing upstream commit 265bfe90 for (RHBZ#993650) - also add log message in the firewall-cmd output (RHBZ#1057095)