commit 6ce620f216df88e1523ecc76d18fd19c0287647f Author: CentOS Sources Date: Tue Apr 7 05:15:33 2020 -0400 import firewalld-0.7.0-5.el8_1.1 diff --git a/.firewalld.metadata b/.firewalld.metadata new file mode 100644 index 0000000..80ba36d --- /dev/null +++ b/.firewalld.metadata @@ -0,0 +1 @@ +0861cc649bffc66b18bb70fb7e33fe03fe31fe33 SOURCES/firewalld-0.7.0.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..58d2fd6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/firewalld-0.7.0.tar.gz diff --git a/SOURCES/0001-fix-src-test-Makefile-use-wildcard-in-variable-expan.patch b/SOURCES/0001-fix-src-test-Makefile-use-wildcard-in-variable-expan.patch new file mode 100644 index 0000000..a78097e --- /dev/null +++ b/SOURCES/0001-fix-src-test-Makefile-use-wildcard-in-variable-expan.patch @@ -0,0 +1,29 @@ +From 57ca11e82eeb4ac6aecefa19729ec7e19d21a4e1 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 13 Jun 2019 10:48:38 -0400 +Subject: [PATCH 01/20] fix: src/test/Makefile: use wildcard in variable + expansion + +It's more correct to use the wildcard function when setting a variable. + +(cherry picked from commit 40fc3b5fd327ec4a8bcbd3f6a2b34047ef16b732) +--- + src/tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am +index 9240484a3109..f1f83ec7eb52 100644 +--- a/src/tests/Makefile.am ++++ b/src/tests/Makefile.am +@@ -8,7 +8,7 @@ TESTSUITE_FILES = \ + EXTRA_DIST = \ + $(TESTSUITE) \ + $(TESTSUITE_FILES) \ +- $(srcdir)/python/*.py \ ++ $(wildcard $(srcdir)/python/*.py) \ + $(srcdir)/package.m4 + + $(srcdir)/package.m4: $(top_srcdir)/configure.ac $(top_srcdir)/firewalld.spec $(srcdir)/Makefile +-- +2.20.1 + diff --git a/SOURCES/0002-fix-CLI-show-service-includes-with-info-service.patch b/SOURCES/0002-fix-CLI-show-service-includes-with-info-service.patch new file mode 100644 index 0000000..d8ca6e7 --- /dev/null +++ b/SOURCES/0002-fix-CLI-show-service-includes-with-info-service.patch @@ -0,0 +1,87 @@ +From 86d498cfd51b8a89d90a639951ff392671a5364b Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 13 Jun 2019 12:08:52 -0400 +Subject: [PATCH 02/20] fix: CLI: show service includes with --info-service + +Fixes: rhbz 1720300 +(cherry picked from commit 36c49fc5a0ec531ad8268347f1f511e6740c9e0c) +--- + src/firewall/command.py | 2 ++ + src/tests/features/service_include.at | 29 ++++++++++++++++++++++++++- + 2 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/src/firewall/command.py b/src/firewall/command.py +index 1449b6dfc3ea..85e58d731a80 100644 +--- a/src/firewall/command.py ++++ b/src/firewall/command.py +@@ -448,6 +448,7 @@ class FirewallCommand(object): + description = settings.getDescription() + destinations = settings.getDestinations() + short_description = settings.getShort() ++ includes = settings.getIncludes() + self.print_msg(service) + if self.verbose: + self.print_msg(" summary: " + short_description) +@@ -462,6 +463,7 @@ class FirewallCommand(object): + self.print_msg(" destination: " + + " ".join(["%s:%s" % (k, v) + for k, v in destinations.items()])) ++ self.print_msg(" includes: " + " ".join(sorted(includes))) + + def print_icmptype_info(self, icmptype, settings): + destinations = settings.getDestinations() +diff --git a/src/tests/features/service_include.at b/src/tests/features/service_include.at +index 992c5ef0ba92..0bf59f63b81b 100644 +--- a/src/tests/features/service_include.at ++++ b/src/tests/features/service_include.at +@@ -1,5 +1,5 @@ + FWD_START_TEST([service include]) +-AT_KEYWORDS(service xml gh273) ++AT_KEYWORDS(service xml gh273 rhbz1720300) + + AT_CHECK([mkdir -p ./services]) + AT_CHECK([cat < ./services/my-service-with-include.xml +@@ -68,6 +68,24 @@ AT_CHECK([grep '' ./services/my-service-with-include.xml + FWD_CHECK([--permanent --service=my-service-with-include --get-includes], 0, [dnl + mdns recursive-service ssdp + ]) ++FWD_CHECK([--permanent --info-service=my-service-with-include | TRIM_WHITESPACE], 0, [m4_strip([dnl ++my-service-with-include ++ ports: 12345/tcp ++ protocols: ++ source-ports: ++ modules: ++ destination: ++ includes: mdns recursive-service ssdp ++])]) ++FWD_CHECK([--info-service=my-service-with-include | TRIM_WHITESPACE], 0, [m4_strip([dnl ++my-service-with-include ++ ports: 12345/tcp ++ protocols: ++ source-ports: ++ modules: ++ destination: ++ includes: mdns recursive-service ssdp ++])]) + + dnl firewall-offline-cmd + FWD_OFFLINE_CHECK([--service=my-service-with-include --query-include=recursive-service], 0, [ignore], [ignore]) +@@ -80,6 +98,15 @@ AT_CHECK([grep '' ./services/my-service-with-include.xml + FWD_OFFLINE_CHECK([--service=my-service-with-include --get-includes], 0, [dnl + mdns recursive-service ssdp + ]) ++FWD_OFFLINE_CHECK([--info-service=my-service-with-include | TRIM_WHITESPACE], 0, [m4_strip([dnl ++my-service-with-include ++ ports: 12345/tcp ++ protocols: ++ source-ports: ++ modules: ++ destination: ++ includes: mdns recursive-service ssdp ++])]) + + dnl negative test for including service that doesn't exist + FWD_CHECK([-q --permanent --zone=drop --add-interface=foobar0]) +-- +2.20.1 + diff --git a/SOURCES/0003-fix-tests-always-list-rules-using-macros.patch b/SOURCES/0003-fix-tests-always-list-rules-using-macros.patch new file mode 100644 index 0000000..94d942a --- /dev/null +++ b/SOURCES/0003-fix-tests-always-list-rules-using-macros.patch @@ -0,0 +1,162 @@ +From cc2b632a51ad32e7b3966f44057add92e45e60a5 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 14 Jun 2019 09:44:41 -0400 +Subject: [PATCH 03/20] fix: tests: always list rules using macros + +This is to make sure certain flags are used, e.g. "-w" for iptables. + +Fixes: rhbz 1720650 +(cherry picked from commit e527818500be462a724cd34c94948a2704560eb1) +--- + src/tests/features/rfc3964_ipv4.at | 4 +- + .../regression/icmp_block_in_forward_chain.at | 27 +++++-- + src/tests/regression/rhbz1514043.at | 80 +++++++++++++++++-- + 3 files changed, 98 insertions(+), 13 deletions(-) + +diff --git a/src/tests/features/rfc3964_ipv4.at b/src/tests/features/rfc3964_ipv4.at +index cce828c0b3de..baff411793b2 100644 +--- a/src/tests/features/rfc3964_ipv4.at ++++ b/src/tests/features/rfc3964_ipv4.at +@@ -93,8 +93,8 @@ NFT_LIST_RULES([inet], [filter_OUTPUT], 0, [dnl + } + ]) + +-m4_if(iptables, FIREWALL_BACKEND, [ +-NS_CHECK([ip6tables -w -n -t filter -L RFC3964_IPv4], 1, [ignore], [ignore]) ++IP6TABLES_LIST_RULES([filter], [RFC3964_IPv4], 0, [ignore], [dnl ++iptables: No chain/target/match by that name. + ]) + IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT +diff --git a/src/tests/regression/icmp_block_in_forward_chain.at b/src/tests/regression/icmp_block_in_forward_chain.at +index 769315d9534e..7580bc179470 100644 +--- a/src/tests/regression/icmp_block_in_forward_chain.at ++++ b/src/tests/regression/icmp_block_in_forward_chain.at +@@ -2,12 +2,27 @@ FWD_START_TEST([ICMP block present FORWARD chain]) + AT_KEYWORDS(icmp) + + FWD_CHECK([-q --zone=public --add-icmp-block=host-prohibited]) +-m4_if(iptables, FIREWALL_BACKEND, [ +- NS_CHECK([IPTABLES -L IN_public_deny | grep "host-prohibited"], 0, ignore) +- NS_CHECK([IPTABLES -L FWDI_public_deny | grep "host-prohibited"], 0, ignore) +-], [ +- NS_CHECK([nft list chain inet firewalld filter_IN_public_deny | grep "destination-unreachable" |grep "\(code 10\|host-prohibited\)"], 0, ignore) +- NS_CHECK([nft list chain inet firewalld filter_FWDI_public_deny | grep "destination-unreachable" |grep "\(code 10\|host-prohibited\)"], 0, ignore) ++ ++NFT_LIST_RULES([inet], [filter_IN_public_deny | sed -e 's/icmp code 10/icmp code host-prohibited/'], 0, [dnl ++ table inet firewalld { ++ chain filter_IN_public_deny { ++ icmp type destination-unreachable icmp code host-prohibited reject with icmp type admin-prohibited ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FWDI_public_deny | sed -e 's/icmp code 10/icmp code host-prohibited/'], 0, [dnl ++ table inet firewalld { ++ chain filter_FWDI_public_deny { ++ icmp type destination-unreachable icmp code host-prohibited reject with icmp type admin-prohibited ++ } ++ } ++]) ++ ++IPTABLES_LIST_RULES([filter], [IN_public_deny], 0, [dnl ++ REJECT icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 3 code 10 reject-with icmp-host-prohibited ++]) ++IPTABLES_LIST_RULES([filter], [FWDI_public_deny], 0, [dnl ++ REJECT icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 3 code 10 reject-with icmp-host-prohibited + ]) + + FWD_END_TEST +diff --git a/src/tests/regression/rhbz1514043.at b/src/tests/regression/rhbz1514043.at +index 88ce4934e5ea..241cf547f7f3 100644 +--- a/src/tests/regression/rhbz1514043.at ++++ b/src/tests/regression/rhbz1514043.at +@@ -7,11 +7,81 @@ FWD_RELOAD + FWD_CHECK([--zone=public --list-all | TRIM | grep ^services], 0, [dnl + services: cockpit dhcpv6-client samba ssh + ]) ++ + dnl check that log denied actually took effect +-m4_if(iptables, FIREWALL_BACKEND, [ +- NS_CHECK([IPTABLES -t filter -L | grep "FINAL_REJECT:"], 0, ignore) +-], [ +- NS_CHECK([nft list chain inet firewalld filter_INPUT | grep "FINAL_REJECT"], 0, ignore) +- NS_CHECK([nft list chain inet firewalld filter_FORWARD | grep "FINAL_REJECT"], 0, ignore) ++NFT_LIST_RULES([inet], [filter_INPUT], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT { ++ ct state established,related accept ++ ct status dnat accept ++ iifname "lo" accept ++ jump filter_INPUT_ZONES ++ ct state invalid log prefix "STATE_INVALID_DROP: " ++ ct state invalid drop ++ log prefix "FINAL_REJECT: " ++ reject with icmpx type admin-prohibited ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD { ++ ct state established,related accept ++ ct status dnat accept ++ iifname "lo" accept ++ ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } log prefix "RFC3964_IPv4_REJECT: " reject with icmpv6 type addr-unreachable ++ jump filter_FORWARD_IN_ZONES ++ jump filter_FORWARD_OUT_ZONES ++ ct state invalid log prefix "STATE_INVALID_DROP: " ++ ct state invalid drop ++ log prefix "FINAL_REJECT: " ++ reject with icmpx type admin-prohibited ++ } ++ } ++]) ++ ++IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ LOG all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID LOG flags 0 level 4 prefix "STATE_INVALID_DROP: " ++ DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID ++ LOG all -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "FINAL_REJECT: " ++ REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited + ]) ++IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_IN_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_OUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ LOG all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID LOG flags 0 level 4 prefix "STATE_INVALID_DROP: " ++ DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID ++ LOG all -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "FINAL_REJECT: " ++ REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ++]) ++IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl ++ ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all ::/0 ::/0 ++ INPUT_direct all ::/0 ::/0 ++ INPUT_ZONES all ::/0 ::/0 ++ LOG all ::/0 ::/0 ctstate INVALID LOG flags 0 level 4 prefix "STATE_INVALID_DROP: " ++ DROP all ::/0 ::/0 ctstate INVALID ++ LOG all ::/0 ::/0 LOG flags 0 level 4 prefix "FINAL_REJECT: " ++ REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited ++]) ++IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl ++ ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all ::/0 ::/0 ++ FORWARD_direct all ::/0 ::/0 ++ RFC3964_IPv4 all ::/0 ::/0 ++ FORWARD_IN_ZONES all ::/0 ::/0 ++ FORWARD_OUT_ZONES all ::/0 ::/0 ++ LOG all ::/0 ::/0 ctstate INVALID LOG flags 0 level 4 prefix "STATE_INVALID_DROP: " ++ DROP all ::/0 ::/0 ctstate INVALID ++ LOG all ::/0 ::/0 LOG flags 0 level 4 prefix "FINAL_REJECT: " ++ REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited ++]) ++ + FWD_END_TEST +-- +2.20.1 + diff --git a/SOURCES/0004-test-new-macro-PIPESTATUS0.patch b/SOURCES/0004-test-new-macro-PIPESTATUS0.patch new file mode 100644 index 0000000..513ad0a --- /dev/null +++ b/SOURCES/0004-test-new-macro-PIPESTATUS0.patch @@ -0,0 +1,35 @@ +From 818d297b17a55fc9c3b21784f45b23875501d654 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 17 Jun 2019 10:57:55 -0400 +Subject: [PATCH 04/20] test: new macro PIPESTATUS0 + +It's essentially a portable version of bash's PIPESTATUS[0]. It passes +down the return code of the first command in the pipeline. + +(cherry picked from commit 1c4bb9337f5d5c734a2a8bab10782423408d4026) +--- + src/tests/functions.at | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 800dd92c7826..932e288f1597 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -242,6 +242,14 @@ m4_define([NS_CHECK], [ + AT_CHECK([NS_CMD([$1])], [$2], [$3], [$4], [$5], [$6]) + ]) + ++dnl implement PIPESTATUS[0] in a portable way ++dnl ++m4_define([PIPESTATUS0], [dnl ++ sh <<-"HERE" ++ { { { { $1; echo $? >&3; } | $2 >&4; } 3>&1; } | { read RC; exit $RC; } } 4>&1 ++HERE ++]) ++ + m4_define([EBTABLES_LIST_RULES], [ + dnl ebtables commit 5f508b76a0ce change list output for inversion. + m4_define([EBTABLES_LIST_RULES_NORMALIZE], [[sed -e 's/\([-][-][-a-zA-Z0-9]\+\)[ ]\+[!]/! \1/g']]) +-- +2.20.1 + diff --git a/SOURCES/0005-test-use-PIPESTATUS0-in-LIST-macros.patch b/SOURCES/0005-test-use-PIPESTATUS0-in-LIST-macros.patch new file mode 100644 index 0000000..5c06865 --- /dev/null +++ b/SOURCES/0005-test-use-PIPESTATUS0-in-LIST-macros.patch @@ -0,0 +1,141 @@ +From 7bfd5446e2926f9a061d883c60c78c88532a34da Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 17 Jun 2019 11:00:01 -0400 +Subject: [PATCH 05/20] test: use PIPESTATUS0 in LIST macros + +This so we get the return code from the first command instead of all the +sed/filtering we do afterwards. + +Also moves the NORMALIZE functions into the top-level. Avoids +unnecessary define/undefine. + +(cherry picked from commit ae18f69bdf2ef664646751787dd7ab44988912f3) +--- + src/tests/functions.at | 67 +++++++++++++++++++++++++++++------------- + 1 file changed, 47 insertions(+), 20 deletions(-) + +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 932e288f1597..69f71c133d15 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -250,18 +250,29 @@ m4_define([PIPESTATUS0], [dnl + HERE + ]) + ++m4_define([EBTABLES_LIST_RULES_NORMALIZE], [dnl ++ TRIM_WHITESPACE | dnl ++ grep -v "^Bridge" | dnl ++ [sed -e 's/\([-][-][-a-zA-Z0-9]\+\)[ ]\+[!]/! \1/g'] dnl ++]) ++ + m4_define([EBTABLES_LIST_RULES], [ + dnl ebtables commit 5f508b76a0ce change list output for inversion. +- m4_define([EBTABLES_LIST_RULES_NORMALIZE], [[sed -e 's/\([-][-][-a-zA-Z0-9]\+\)[ ]\+[!]/! \1/g']]) + m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ +- NS_CHECK([ebtables --concurrent -t $1 -L $2 | TRIM_WHITESPACE | grep -v "^Bridge" | EBTABLES_LIST_RULES_NORMALIZE], [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) ++ NS_CHECK([PIPESTATUS0([ebtables --concurrent -t $1 -L $2], [EBTABLES_LIST_RULES_NORMALIZE])], ++ [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) + ]) +- m4_undefine([EBTABLES_LIST_RULES_NORMALIZE]) ++]) ++ ++m4_define([IPTABLES_LIST_RULES_NORMALIZE], [dnl ++ TRIM_WHITESPACE | dnl ++ tail -n +3 dnl + ]) + + m4_define([IPTABLES_LIST_RULES_ALWAYS], [ + m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ +- NS_CHECK([IPTABLES -w -n -t $1 -L $2 | TRIM_WHITESPACE | tail -n +3], [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) ++ NS_CHECK([PIPESTATUS0([IPTABLES -w -n -t $1 -L $2], [IPTABLES_LIST_RULES_NORMALIZE])], ++ [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) + ]) + ]) + +@@ -271,11 +282,17 @@ m4_define([IPTABLES_LIST_RULES], [ + ]) + ]) + ++m4_define([IP6TABLES_LIST_RULES_NORMALIZE], [dnl ++ TRIM_WHITESPACE | dnl ++ tail -n +3 dnl ++]) ++ + m4_define([IP6TABLES_LIST_RULES_ALWAYS], [ + m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ +- m4_if(yes, HOST_SUPPORTS_IP6TABLES, [ +- NS_CHECK([IP6TABLES -w -n -t $1 -L $2 | TRIM_WHITESPACE | tail -n +3], [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) +- ]) ++ m4_if(yes, HOST_SUPPORTS_IP6TABLES, [ ++ NS_CHECK([PIPESTATUS0([IP6TABLES -w -n -t $1 -L $2], [IP6TABLES_LIST_RULES_NORMALIZE])], ++ [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) ++ ]) + ]) + ]) + +@@ -285,20 +302,21 @@ m4_define([IP6TABLES_LIST_RULES], [ + ]) + ]) + +-m4_define([NFT_LIST_RULES_ALWAYS], [ ++m4_define([NFT_LIST_RULES_NORMALIZE], [dnl ++ TRIM_WHITESPACE | dnl + dnl nftables commit 6dd848339444 change list output to show "meta mark" + dnl instead of just "mark". +- m4_define([NFT_LIST_RULES_NORMALIZE], [dnl +- sed -e 's/meta mark/mark/g'dnl +- -e '/type.*hook.*priority.*policy.*/d'dnl +- dnl tranform ct state { established,related } to ct state established,related +- -e '/ct \(state\|status\)/{s/\(ct \(state\|status\)\) {/\1/g; s/ }//; s/\(@<:@a-z@:>@*\), /\1,/g;}' dnl +- ]) ++ sed -e 's/meta mark/mark/g'dnl ++ -e '/type.*hook.*priority.*policy.*/d'dnl ++ dnl tranform ct state { established,related } to ct state established,related ++ -e '/ct \(state\|status\)/{s/\(ct \(state\|status\)\) {/\1/g; s/ }//; s/\(@<:@a-z@:>@*\), /\1,/g;}' dnl ++]) + ++m4_define([NFT_LIST_RULES_ALWAYS], [ + m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ +- NS_CHECK([nft NFT_NUMERIC_ARGS list chain $1 firewalld $2 | TRIM_WHITESPACE | NFT_LIST_RULES_NORMALIZE], [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) ++ NS_CHECK([PIPESTATUS0([nft NFT_NUMERIC_ARGS list chain $1 firewalld $2], [NFT_LIST_RULES_NORMALIZE])], ++ [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) + ]) +- m4_undefine([NFT_LIST_RULES_NORMALIZE]) + ]) + + m4_define([NFT_LIST_RULES], [ +@@ -307,18 +325,27 @@ m4_define([NFT_LIST_RULES], [ + ]) + ]) + ++m4_define([IPSET_LIST_SET_NORMALIZE], [dnl ++ TRIM_WHITESPACE |dnl ++ grep -v "^\(Revision\|Header\|Size\|References\|Number\)" |dnl ++ awk 'NR <= 3; NR > 3 {print | "sort"}' dnl ++]) ++ + m4_define([IPSET_LIST_SET], [ + m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ +- NS_CHECK([ipset list $1 | TRIM_WHITESPACE |dnl +- grep -v "^\(Revision\|Header\|Size\|References\|Number\)" |dnl +- awk 'NR <= 3; NR > 3 {print | "sort"}'], ++ NS_CHECK([PIPESTATUS0([ipset list $1], [IPSET_LIST_SET_NORMALIZE])], + [$2], [m4_strip([$3])], [m4_strip([$4])], [$5], [$6]) + ]) + ]) + ++m4_define([NFT_LIST_SET_NORMALIZE], [dnl ++ TRIM_WHITESPACE dnl ++]) ++ + m4_define([NFT_LIST_SET_ALWAYS], [ + m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ +- NS_CHECK([nft NFT_NUMERIC_ARGS list set inet firewalld $1 | TRIM_WHITESPACE], [$2], [m4_strip([$3])], [m4_strip([$4])], [$5], [$6]) ++ NS_CHECK([PIPESTATUS0([nft NFT_NUMERIC_ARGS list set inet firewalld $1], [NFT_LIST_SET_NORMALIZE])], ++ [$2], [m4_strip([$3])], [m4_strip([$4])], [$5], [$6]) + ]) + ]) + +-- +2.20.1 + diff --git a/SOURCES/0006-fix-test-features-rfc3964_ipv4-use-return-code-not-o.patch b/SOURCES/0006-fix-test-features-rfc3964_ipv4-use-return-code-not-o.patch new file mode 100644 index 0000000..d59cfdd --- /dev/null +++ b/SOURCES/0006-fix-test-features-rfc3964_ipv4-use-return-code-not-o.patch @@ -0,0 +1,32 @@ +From 0f3ae3ae56b7a27ec3ff85646a87b6488b1f05d6 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 17 Jun 2019 11:01:27 -0400 +Subject: [PATCH 06/20] fix: test/features/rfc3964_ipv4: use return code not + output for negative test + +The output varies between -nft and -legacy iptables variants. + +Fixes: e527818500be ("fix: tests: always list rules using macros") +(cherry picked from commit 7149ff26c88a86c9a485f8e59d3ceb3eb4a292d4) +--- + src/tests/features/rfc3964_ipv4.at | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/tests/features/rfc3964_ipv4.at b/src/tests/features/rfc3964_ipv4.at +index baff411793b2..54f5f756270b 100644 +--- a/src/tests/features/rfc3964_ipv4.at ++++ b/src/tests/features/rfc3964_ipv4.at +@@ -93,9 +93,7 @@ NFT_LIST_RULES([inet], [filter_OUTPUT], 0, [dnl + } + ]) + +-IP6TABLES_LIST_RULES([filter], [RFC3964_IPv4], 0, [ignore], [dnl +-iptables: No chain/target/match by that name. +-]) ++IP6TABLES_LIST_RULES([filter], [RFC3964_IPv4], 1, [ignore], [ignore]) + IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT + ACCEPT all ::/0 ::/0 +-- +2.20.1 + diff --git a/SOURCES/0007-test-new-macro-CHECK_MODULE_PROTO_GRE.patch b/SOURCES/0007-test-new-macro-CHECK_MODULE_PROTO_GRE.patch new file mode 100644 index 0000000..e9d0edb --- /dev/null +++ b/SOURCES/0007-test-new-macro-CHECK_MODULE_PROTO_GRE.patch @@ -0,0 +1,28 @@ +From cedbd55380bfcb60bc600d8d8833a4d9abab1080 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 17 Jun 2019 14:30:34 -0400 +Subject: [PATCH 07/20] test: new macro CHECK_MODULE_PROTO_GRE + +(cherry picked from commit af89dacab41d6dc6a42e992aa74a2d6f4a420abc) +--- + src/tests/functions.at | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 69f71c133d15..7a0242cb33fb 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -444,6 +444,10 @@ m4_define([CHECK_NFT_CT_HELPER], [ + ]) + ]) + ++m4_define([CHECK_MODULE_PROTO_GRE], [ ++ AT_SKIP_IF([! NS_CMD([modinfo nf_conntrack_proto_gre])]) ++]) ++ + m4_define([HOST_SUPPORTS_NFT_FIB], m4_esyscmd([ + KERNEL_MAJOR=`uname -r | cut -d. -f1` + KERNEL_MINOR=`uname -r | cut -d. -f2` +-- +2.20.1 + diff --git a/SOURCES/0008-fix-test-regression-pr323-skip-if-GRE-module-doesn-t.patch b/SOURCES/0008-fix-test-regression-pr323-skip-if-GRE-module-doesn-t.patch new file mode 100644 index 0000000..a6eef65 --- /dev/null +++ b/SOURCES/0008-fix-test-regression-pr323-skip-if-GRE-module-doesn-t.patch @@ -0,0 +1,30 @@ +From c4601cf33ba1c21c3233a33f39dff286c04a1872 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 17 Jun 2019 14:31:15 -0400 +Subject: [PATCH 08/20] fix: test/regression/pr323: skip if GRE module doesn't + exist + +Newer kernels use a built-in so the module nf_conntrack_proto_gre +doesn't exist. + +(cherry picked from commit 6cda87d3a532c5ca6e8ef74c03f2e7a6bb45627a) +--- + src/tests/regression/pr323.at | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/tests/regression/pr323.at b/src/tests/regression/pr323.at +index 7fd719d0ada2..25b09930c34a 100644 +--- a/src/tests/regression/pr323.at ++++ b/src/tests/regression/pr323.at +@@ -1,6 +1,8 @@ + FWD_START_TEST([GRE proto helper]) + AT_KEYWORDS(helper gh323) + ++CHECK_MODULE_PROTO_GRE ++ + FWD_CHECK([-q --add-protocol=gre]) + FWD_CHECK([-q --remove-protocol=gre]) + +-- +2.20.1 + diff --git a/SOURCES/0009-test-service-coverage-for-import-from-file.patch b/SOURCES/0009-test-service-coverage-for-import-from-file.patch new file mode 100644 index 0000000..b6353b3 --- /dev/null +++ b/SOURCES/0009-test-service-coverage-for-import-from-file.patch @@ -0,0 +1,36 @@ +From e34b1005145d950382808b7f1d776511b2d710fa Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 3 Jul 2019 10:41:07 -0400 +Subject: [PATCH 09/20] test: service: coverage for import from file + +(cherry picked from commit 40d8d6a105a7212db138e3afacf0f471676a8b78) +--- + src/tests/firewall-cmd.at | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/tests/firewall-cmd.at b/src/tests/firewall-cmd.at +index 6444b4566af5..7bb13aee0221 100644 +--- a/src/tests/firewall-cmd.at ++++ b/src/tests/firewall-cmd.at +@@ -319,6 +319,18 @@ FWD_START_TEST([user services]) + FWD_CHECK([--permanent --zone=public --list-services | grep foobar], 0, ignore) + FWD_CHECK([--permanent --delete-service=foobar], 0, ignore) + FWD_CHECK([--permanent --zone=public --list-services | grep foobar], 1, ignore) ++ ++ AT_DATA([./foobar-to-be-renamed], [m4_strip([dnl ++ ++ ++ ++ ++ ++ ]) ++ FWD_CHECK([--permanent --new-service-from-file="./foobar-to-be-renamed" --name="foobar-from-file"]) ++ FWD_CHECK([--permanent --get-services | grep foobar-from-file], 0, [ignore]) ++]) ++ + FWD_END_TEST([-e '/ERROR: NAME_CONFLICT: new_service():/d' dnl + -e '/ERROR: INVALID_ADDR:/d']) + +-- +2.20.1 + diff --git a/SOURCES/0010-fix-dbus-fix-service-API-break.patch b/SOURCES/0010-fix-dbus-fix-service-API-break.patch new file mode 100644 index 0000000..6ae9743 --- /dev/null +++ b/SOURCES/0010-fix-dbus-fix-service-API-break.patch @@ -0,0 +1,238 @@ +From 905f7eb62dd31a58b86fbfa191b2ce2482361b0b Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 24 Jun 2019 10:36:40 -0400 +Subject: [PATCH 10/20] fix: dbus: fix service API break + +This fixes a dbus API break that occurred when introducing service +includes. The includes were added to the method's tuple, but doing so +changed the dbus signature and thus broke the API. This restores the old +signature. + +Move to using key,value based import/export and sanity checking. +Previously we were using a tuple with semi-undocumented positions. + +Fixes: 1fc208bf9317 ("feat: service includes") +Fixes: rhbz 1721414 +(cherry picked from commit 335a68c1bba5b1b1fbd430505a485a9eb035360c) +--- + doc/xml/firewalld.dbus.xml | 5 ++- + src/firewall/core/fw_config.py | 59 +++++++++++++++++++++++++++++++- + src/firewall/core/io/service.py | 35 ++++++++++++++++--- + src/firewall/server/firewalld.py | 13 ++++++- + 4 files changed, 103 insertions(+), 9 deletions(-) + +diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml +index 64d4d2b9c73b..cb4e1eac0fb9 100644 +--- a/doc/xml/firewalld.dbus.xml ++++ b/doc/xml/firewalld.dbus.xml +@@ -242,12 +242,12 @@ + + + +- getServiceSettings(s: service) → (sssa(ss)asa{ss}asa(ss)as) ++ getServiceSettings(s: service) → (sssa(ss)asa{ss}asa(ss)) + + + Return runtime settings of given service. + For getting permanent settings see org.fedoraproject.FirewallD1.config.service.Methods.getSettings. +- Settings are in format: version, name, description, array of ports (port, protocol), array of module names, dictionary of destinations, array of protocols, array of source-ports (port, protocol) and array of service includes. ++ Settings are in format: version, name, description, array of ports (port, protocol), array of module names, dictionary of destinations, array of protocols, array of source-ports (port, protocol). + + + +@@ -259,7 +259,6 @@ + destinations (a{ss}): dictionary of {IP family : IP address} where 'IP family' key can be either 'ipv4' or 'ipv6'. See destination tag in firewalld.service5. + protocols (as): array of protocols, see protocol tag in firewalld.service5. + source-ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. +- includes (as): array of service includes, see include tag in firewalld.service5. + + + +diff --git a/src/firewall/core/fw_config.py b/src/firewall/core/fw_config.py +index a759cfdf83b3..8f29f0c416d2 100644 +--- a/src/firewall/core/fw_config.py ++++ b/src/firewall/core/fw_config.py +@@ -545,9 +545,43 @@ class FirewallConfig(object): + return self._builtin_services[obj.name] + + def get_service_config(self, obj): ++ conf_dict = obj.export_config() ++ conf_list = [] ++ for i in range(8): # tuple based dbus API has 8 elements ++ if obj.IMPORT_EXPORT_STRUCTURE[i][0] not in conf_dict: ++ # old API needs the empty elements as well. Grab it from the ++ # object otherwise we don't know the type. ++ conf_list.append(copy.deepcopy(getattr(obj, obj.IMPORT_EXPORT_STRUCTURE[i][0]))) ++ else: ++ conf_list.append(conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]]) ++ return tuple(conf_list) ++ ++ def get_service_config_dict(self, obj): + return obj.export_config() + + def set_service_config(self, obj, conf): ++ conf_dict = {} ++ for i,value in enumerate(conf): ++ conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]] = value ++ ++ if obj.builtin: ++ x = copy.copy(obj) ++ x.cleanup() ++ x.import_config(conf_dict) ++ x.path = config.ETC_FIREWALLD_SERVICES ++ x.builtin = False ++ if obj.path != x.path: ++ x.default = False ++ self.add_service(x) ++ service_writer(x) ++ return x ++ else: ++ obj.cleanup() ++ obj.import_config(conf_dict) ++ service_writer(obj) ++ return obj ++ ++ def set_service_config_dict(self, obj, conf): + if obj.builtin: + x = copy.copy(obj) + x.import_config(conf) +@@ -568,6 +602,29 @@ class FirewallConfig(object): + raise FirewallError(errors.NAME_CONFLICT, + "new_service(): '%s'" % name) + ++ conf_dict = {} ++ for i,value in enumerate(conf): ++ conf_dict[Service.IMPORT_EXPORT_STRUCTURE[i][0]] = value ++ ++ x = Service() ++ x.check_name(name) ++ x.import_config(conf_dict) ++ x.name = name ++ x.filename = "%s.xml" % name ++ x.path = config.ETC_FIREWALLD_SERVICES ++ # It is not possible to add a new one with a name of a buitin ++ x.builtin = False ++ x.default = True ++ ++ service_writer(x) ++ self.add_service(x) ++ return x ++ ++ def new_service_dict(self, name, conf): ++ if name in self._services or name in self._builtin_services: ++ raise FirewallError(errors.NAME_CONFLICT, ++ "new_service(): '%s'" % name) ++ + x = Service() + x.check_name(name) + x.import_config(conf) +@@ -684,7 +741,7 @@ class FirewallConfig(object): + return new_service + + def _copy_service(self, obj, name): +- return self.new_service(name, obj.export_config()) ++ return self.new_service_dict(name, obj.export_config()) + + # zones + +diff --git a/src/firewall/core/io/service.py b/src/firewall/core/io/service.py +index 3479dab7f175..44dc0ff8a9b0 100644 +--- a/src/firewall/core/io/service.py ++++ b/src/firewall/core/io/service.py +@@ -25,6 +25,8 @@ import xml.sax as sax + import os + import io + import shutil ++import copy ++from collections import OrderedDict + + from firewall import config + from firewall.functions import u2b_if_py2 +@@ -47,7 +49,7 @@ class Service(IO_Object): + ( "source_ports", [ ( "", "" ), ], ), # a(ss) + ( "includes", [ "" ], ), # as + ) +- DBUS_SIGNATURE = '(sssa(ss)asa{ss}asa(ss)as)' ++ DBUS_SIGNATURE = '(sssa(ss)asa{ss}asa(ss))' + ADDITIONAL_ALNUM_CHARS = [ "_", "-" ] + PARSER_REQUIRED_ELEMENT_ATTRS = { + "short": None, +@@ -76,6 +78,34 @@ class Service(IO_Object): + self.source_ports = [ ] + self.includes = [ ] + ++ def import_config(self, conf): ++ self.check_config(conf) ++ ++ for key in conf: ++ if not hasattr(self, key): ++ raise FirewallError(errors.UNKNOWN_ERROR, "Internal error. '{}' is not a valid attribute".format(key)) ++ if isinstance(conf[key], list): ++ # maintain list order while removing duplicates ++ setattr(self, key, list(OrderedDict.fromkeys(copy.deepcopy(conf[key])))) ++ else: ++ setattr(self, key, copy.deepcopy(conf[key])) ++ ++ def export_config(self): ++ conf = {} ++ type_formats = dict([(x[0], x[1]) for x in self.IMPORT_EXPORT_STRUCTURE]) ++ for key in type_formats: ++ if getattr(self, key): ++ conf[key] = copy.deepcopy(getattr(self, key)) ++ return conf ++ ++ def check_config(self, conf): ++ type_formats = dict([(x[0], x[1]) for x in self.IMPORT_EXPORT_STRUCTURE]) ++ for key in conf: ++ if key not in [x for (x,y) in self.IMPORT_EXPORT_STRUCTURE]: ++ raise FirewallError(errors.INVALID_OPTION, "service option '{}' is not valid".format(key)) ++ self._check_config_structure(conf[key], type_formats[key]) ++ self._check_config(conf[key], key) ++ + def cleanup(self): + self.version = "" + self.short = "" +@@ -138,9 +168,6 @@ class Service(IO_Object): + if len(module) < 2: + raise FirewallError(errors.INVALID_MODULE, module) + +- elif item == "includes": +- pass +- + # PARSER + + class service_ContentHandler(IO_Object_ContentHandler): +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index bc04f2d0f4c3..233160b64b18 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -26,6 +26,7 @@ from gi.repository import GLib, GObject + import sys + sys.modules['gobject'] = GObject + ++import copy + import dbus + import dbus.service + import slip.dbus +@@ -921,7 +922,17 @@ class FirewallD(slip.dbus.service.Object): + # returns service settings for service + service = dbus_to_python(service, str) + log.debug1("getServiceSettings(%s)", service) +- return self.fw.service.get_service(service).export_config() ++ obj = self.fw.service.get_service(service) ++ conf_dict = obj.export_config() ++ conf_list = [] ++ for i in range(8): # tuple based dbus API has 8 elements ++ if obj.IMPORT_EXPORT_STRUCTURE[i][0] not in conf_dict: ++ # old API needs the empty elements as well. Grab it from the ++ # object otherwise we don't know the type. ++ conf_list.append(copy.deepcopy(getattr(obj, obj.IMPORT_EXPORT_STRUCTURE[i][0]))) ++ else: ++ conf_list.append(conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]]) ++ return tuple(conf_list) + + @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO) + @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='', +-- +2.20.1 + diff --git a/SOURCES/0011-fix-dbus-add-missing-APIs-for-service-includes.patch b/SOURCES/0011-fix-dbus-add-missing-APIs-for-service-includes.patch new file mode 100644 index 0000000..7b4c10b --- /dev/null +++ b/SOURCES/0011-fix-dbus-add-missing-APIs-for-service-includes.patch @@ -0,0 +1,83 @@ +From 464add2ad05781e72e54d05cc06150c21e1c282d Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Jul 2019 10:27:51 -0400 +Subject: [PATCH 11/20] fix: dbus: add missing APIs for service includes + +Fixes: 1fc208bf9317 ("feat: service includes") +(cherry picked from commit bcdc1e2bf1e71c32606fdaadabd9a913e2e1d651) +--- + src/firewall/server/config_service.py | 61 +++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/src/firewall/server/config_service.py b/src/firewall/server/config_service.py +index 47530d319bdb..05ded1c78da7 100644 +--- a/src/firewall/server/config_service.py ++++ b/src/firewall/server/config_service.py +@@ -652,3 +652,64 @@ class FirewallDConfigService(slip.dbus.service.Object): + settings = self.getSettings() + return (family in settings[5] and + address == settings[5][family]) ++ ++ # includes ++ ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, ++ out_signature='as') ++ @dbus_handle_exceptions ++ def getIncludes(self, sender=None): ++ log.debug1("%s.getIncludes()", self._log_prefix) ++ self.parent.accessCheck(sender) ++ settings = list(self.config.get_service_config(self.obj)) ++ return settings[8] ++ ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, ++ in_signature='as') ++ @dbus_handle_exceptions ++ def setIncludes(self, includes, sender=None): ++ includes = dbus_to_python(includes, list) ++ log.debug1("%s.setIncludes('%s')", self._log_prefix, includes) ++ self.parent.accessCheck(sender) ++ settings = list(self.config.get_service_config(self.obj)) ++ settings[8] = includes[:] ++ self.config.set_service_config(self.obj, tuple(settings)) ++ self.Updated(self.obj.name) ++ ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, ++ in_signature='s') ++ @dbus_handle_exceptions ++ def addInclude(self, include, sender=None): ++ include = dbus_to_python(include, str) ++ log.debug1("%s.addInclude('%s')", self._log_prefix, include) ++ self.parent.accessCheck(sender) ++ settings = list(self.config.get_service_config(self.obj)) ++ settings[8].append(include) ++ self.config.set_service_config(self.obj, tuple(settings)) ++ self.Updated(self.obj.name) ++ ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, ++ in_signature='s') ++ @dbus_handle_exceptions ++ def removeInclude(self, include, sender=None): ++ include = dbus_to_python(include, str) ++ log.debug1("%s.removeInclude('%s')", self._log_prefix, include) ++ self.parent.accessCheck(sender) ++ settings = list(self.config.get_service_config(self.obj)) ++ settings[8].remove(include) ++ self.config.set_service_config(self.obj, tuple(settings)) ++ self.Updated(self.obj.name) ++ ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, ++ in_signature='s', out_signature='b') ++ @dbus_handle_exceptions ++ def queryInclude(self, include, sender=None): ++ include = dbus_to_python(include, str) ++ log.debug1("%s.queryInclude('%s')", self._log_prefix, include) ++ settings = list(self.config.get_service_config(self.obj)) ++ try: ++ settings[8].index(include) ++ except ValueError: ++ return False ++ else: ++ return True +-- +2.20.1 + diff --git a/SOURCES/0012-fix-tests-functions-use-gdbus-instead-of-dbus-send.patch b/SOURCES/0012-fix-tests-functions-use-gdbus-instead-of-dbus-send.patch new file mode 100644 index 0000000..55abc97 --- /dev/null +++ b/SOURCES/0012-fix-tests-functions-use-gdbus-instead-of-dbus-send.patch @@ -0,0 +1,44 @@ +From 4d2a2b79aefac90d4656b0d9c3b58661d2b88a07 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 25 Jun 2019 14:04:34 -0400 +Subject: [PATCH 12/20] fix: tests/functions: use gdbus instead of dbus-send + +dbus-send doesn't support all the types and nested types that we need +for testing. + +(cherry picked from commit 15346d6ff16e75bbbd05e40ac2e8cbe051e08dd9) +--- + src/tests/functions.at | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 7a0242cb33fb..28af5a7fc532 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -355,10 +355,20 @@ m4_define([NFT_LIST_SET], [ + ]) + ]) + ++m4_define([DBUS_CHECK_NORMALIZE], [dnl ++ [sed -e 's/^({//' -e 's/},)$//' -e 's/>,/>\n/g'] | dnl truncate dictionary output ++ TRIM_WHITESPACE | dnl ++ sort dnl sort dictionaries by keys ++]) ++ + m4_define([DBUS_CHECK], [ +- NS_CHECK([dbus-send --system --print-reply --dest=org.fedoraproject.FirewallD1 dnl +- /org/fedoraproject/FirewallD1/$1 org.fedoraproject.FirewallD1.$2 $3], +- [$4], [$5], [$6], [$7], [$8]) ++ AT_SKIP_IF([! NS_CMD([which gdbus >/dev/null 2>&1])]) ++ NS_CHECK([PIPESTATUS0([gdbus call --system --dest=org.fedoraproject.FirewallD1 dnl ++ m4_ifblank([$1], [--object-path /org/fedoraproject/FirewallD1], ++ [--object-path /org/fedoraproject/FirewallD1/$1]) dnl ++ --method org.fedoraproject.FirewallD1.$2 $3], ++ [DBUS_CHECK_NORMALIZE])], ++ [$4], [m4_strip([$5])], [m4_strip([$6])], [$7], [$8]) + ]) + + m4_define([DBUS_GETALL_NORMALIZE], dnl +-- +2.20.1 + diff --git a/SOURCES/0013-test-functions-add-CHOMP-macro-for-shell-output.patch b/SOURCES/0013-test-functions-add-CHOMP-macro-for-shell-output.patch new file mode 100644 index 0000000..3facd15 --- /dev/null +++ b/SOURCES/0013-test-functions-add-CHOMP-macro-for-shell-output.patch @@ -0,0 +1,30 @@ +From d74f03af843c71872e60af4a59204a6cab4cd934 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 22 Jul 2019 14:48:19 -0400 +Subject: [PATCH 13/20] test: functions: add CHOMP macro for shell output + +chomps all trailing newlines by exploiting posix shell behavior for +variable expansion. + +(cherry picked from commit a8b90c38c19732f3dc9ca5cfedc10bb54c0d84bf) +--- + src/tests/functions.at | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 28af5a7fc532..8aeaf158a066 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -226,7 +226,8 @@ m4_define([FWD_GREP_LOG], [ + m4_define([TRIM], [[sed -e 's/^[ \t]*//' -e 's/[ \t]*$//']]) + m4_define([TRIMV], [[sed -e '/^[ \t]*$/d']]) + m4_define([TRIM_INTERNAL], [[sed -e 's/[ \t]\+/ /g']]) +-m4_define([TRIM_WHITESPACE], [TRIM | TRIMV | TRIM_INTERNAL]) ++m4_define([CHOMP], [printf "%s" "$(cat /dev/stdin)"]) ++m4_define([TRIM_WHITESPACE], [TRIM | TRIMV | TRIM_INTERNAL | { CHOMP; echo; }]) + + dnl m4sugar's m4_strip has a bug that causes it to print a space after + dnl newlines. So implement our own suck-less version. +-- +2.20.1 + diff --git a/SOURCES/0014-test-functions-add-macro-DBUS_INTROSPECT.patch b/SOURCES/0014-test-functions-add-macro-DBUS_INTROSPECT.patch new file mode 100644 index 0000000..c721850 --- /dev/null +++ b/SOURCES/0014-test-functions-add-macro-DBUS_INTROSPECT.patch @@ -0,0 +1,36 @@ +From aba9e384a4de8785717e569905a4459a2fc15b4d Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 5 Jul 2019 17:13:20 -0400 +Subject: [PATCH 14/20] test: functions: add macro DBUS_INTROSPECT + +We'll use this to introspect and verify the API. + +(cherry picked from commit 5f32c24dec88c60e4f43d27ea56ea208016c339b) +--- + src/tests/functions.at | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 8aeaf158a066..3771bb8bd5a7 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -356,6 +356,16 @@ m4_define([NFT_LIST_SET], [ + ]) + ]) + ++m4_define([DBUS_INTROSPECT], [ ++ AT_SKIP_IF([! NS_CMD([which gdbus >/dev/null 2>&1])]) ++ AT_SKIP_IF([! NS_CMD([which xmllint >/dev/null 2>&1])]) ++ NS_CHECK([PIPESTATUS0([gdbus introspect --xml --system --dest=org.fedoraproject.FirewallD1 dnl ++ m4_ifblank([$1], [--object-path /org/fedoraproject/FirewallD1], ++ [--object-path /org/fedoraproject/FirewallD1/$1])], dnl ++ [m4_ifnblank([$2], [xmllint --xpath '$2' - |]) TRIM_WHITESPACE])], ++ [$3], [m4_strip([$4])], [m4_strip([$5])], [$6], [$7]) ++]) ++ + m4_define([DBUS_CHECK_NORMALIZE], [dnl + [sed -e 's/^({//' -e 's/},)$//' -e 's/>,/>\n/g'] | dnl truncate dictionary output + TRIM_WHITESPACE | dnl +-- +2.20.1 + diff --git a/SOURCES/0015-test-dbus-service-API-coverage.patch b/SOURCES/0015-test-dbus-service-API-coverage.patch new file mode 100644 index 0000000..3e79c8d --- /dev/null +++ b/SOURCES/0015-test-dbus-service-API-coverage.patch @@ -0,0 +1,319 @@ +From 0d526d6f20695b48d374b1966038ac5c4397e17c Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 24 Jun 2019 10:20:23 -0400 +Subject: [PATCH 15/20] test: dbus: service API coverage + +(cherry picked from commit b0ecd9e3916a691fa7adefa258e7ab0df2e9e1ea) +--- + src/tests/dbus.at | 1 + + src/tests/dbus/service.at | 290 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 291 insertions(+) + create mode 100644 src/tests/dbus/service.at + +diff --git a/src/tests/dbus.at b/src/tests/dbus.at +index 4cb0568cbc9c..46fec2ff4024 100644 +--- a/src/tests/dbus.at ++++ b/src/tests/dbus.at +@@ -1,2 +1,3 @@ + AT_BANNER([dbus]) + m4_include([dbus/firewalld.conf.at]) ++m4_include([dbus/service.at]) +diff --git a/src/tests/dbus/service.at b/src/tests/dbus/service.at +new file mode 100644 +index 000000000000..579548d66509 +--- /dev/null ++++ b/src/tests/dbus/service.at +@@ -0,0 +1,290 @@ ++FWD_START_TEST([dbus api - services]) ++AT_KEYWORDS(dbus service rhbz1721414) ++ ++DBUS_INTROSPECT([config], [[//method[@name="addService"]]], 0, [dnl ++ ++ ++ ++ ++ ++]) ++DBUS_CHECK([config], [config.addService], ++ ["foobar" dnl name ++ '("1.0", dnl version ++ "foobar", dnl short ++ "foobar service is for foobar", dnl description ++ @<:@("1234", "udp"), ("22", "tcp"), ("1234", "udp")@:>@, dnl ports, deliberate duplicate ++ @<:@"ftp"@:>@, dnl modules ++ {"ipv4": "1.2.3.4"}, dnl destination ++ @<:@"icmp", "igmp"@:>@, dnl protocols ++ @<:@("4321", "tcp"), ("4321", "udp")@:>@ dnl source ports ++ )'dnl ++ ], 0, [stdout]) ++SERVICE_OBJ=[$(sed -e "s/.*config\/service\/\([^']\+\)['].*/\1/" ./stdout)] ++export SERVICE_OBJ ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getSettings"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.getSettings], [], 0, [dnl ++ [(('1.0', 'foobar', 'foobar service is for foobar', [('1234', 'udp'), ('22', 'tcp')], ['ftp'], {'ipv4': '1.2.3.4'}, ['icmp', 'igmp'], [('4321', 'tcp'), ('4321', 'udp')]),)] ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="update"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.update], ++ ['("1.1", dnl version ++ "foobar new", dnl short ++ "foobar new service is for foobar", dnl description ++ @<:@("12345", "udp"), ("2222", "tcp")@:>@, dnl ports ++ @<:@"ftp"@:>@, dnl modules ++ {}, dnl destination ++ @<:@"icmp"@:>@, dnl protocols ++ @<:@("4321", "tcp")@:>@ dnl source ports ++ )'dnl ++ ], 0, [ignore]) ++ ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.getSettings], [], 0, [dnl ++ [(('1.1', 'foobar new', 'foobar new service is for foobar', [('12345', 'udp'), ('2222', 'tcp')], ['ftp'], @a{ss} {}, ['icmp'], [('4321', 'tcp')]),)] ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="loadDefaults"]]], 0, [dnl ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="remove"]]], 0, [dnl ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="rename"]]], 0, [dnl ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getVersion"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setVersion"]]], 0, [dnl ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getShort"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setShort"]]], 0, [dnl ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getDescription"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setDescription"]]], 0, [dnl ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getPorts"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setPorts"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="addPort"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="removePort"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="queryPort"]]], 0, [dnl ++ ++ ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getSourcePorts"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setSourcePorts"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="addSourcePort"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="removeSourcePort"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="querySourcePort"]]], 0, [dnl ++ ++ ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getProtocols"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setProtocols"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="addProtocol"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="removeProtocol"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="queryProtocol"]]], 0, [dnl ++ ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getModules"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setModules"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="addModule"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="removeModule"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="queryModule"]]], 0, [dnl ++ ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getDestinations"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setDestinations"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setDestination"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getDestination"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="removeDestination"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="queryDestination"]]], 0, [dnl ++ ++ ++ ++ ++ ++]) ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getIncludes"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="setIncludes"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="addInclude"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="removeInclude"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="queryInclude"]]], 0, [dnl ++ ++ ++ ++ ++]) ++ ++FWD_RELOAD ++DBUS_INTROSPECT([], [[//method[@name="getServiceSettings"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_CHECK([], [getServiceSettings], ["foobar"], 0, [dnl ++ [(('1.1', 'foobar new', 'foobar new service is for foobar', [('12345', 'udp'), ('2222', 'tcp')], ['ftp'], @a{ss} {}, ['icmp'], [('4321', 'tcp')]),)] ++]) ++ ++FWD_END_TEST +-- +2.20.1 + diff --git a/SOURCES/0016-fix-dbus-new-dict-based-APIs-for-services.patch b/SOURCES/0016-fix-dbus-new-dict-based-APIs-for-services.patch new file mode 100644 index 0000000..b7b16e3 --- /dev/null +++ b/SOURCES/0016-fix-dbus-new-dict-based-APIs-for-services.patch @@ -0,0 +1,362 @@ +From 08101a69d8b06f176c6f5e975ddfc1a562864bd2 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 19 Jun 2019 17:52:55 -0400 +Subject: [PATCH 16/20] fix: dbus: new dict based APIs for services + +Since we can't change the dbus APIs, we need new ones that are more +flexible. This adds a few for manipulating services using a dictionary +of key,value pairs. All new code should use these new APIs. The old APIs +have been marked deprecated. + +Fixes: 1fc208bf9317 ("feat: service includes") +(cherry picked from commit bbadd3943dabcc11e864223503a46144b0c03007) +--- + doc/xml/firewalld.dbus.xml | 92 +++++++++++++++++++-------- + src/firewall/core/io/service.py | 19 +++--- + src/firewall/server/config.py | 18 +++++- + src/firewall/server/config_service.py | 24 ++++++- + src/firewall/server/firewalld.py | 13 +++- + 5 files changed, 123 insertions(+), 43 deletions(-) + +diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml +index cb4e1eac0fb9..4a81e8e61858 100644 +--- a/doc/xml/firewalld.dbus.xml ++++ b/doc/xml/firewalld.dbus.xml +@@ -241,13 +241,22 @@ + + + +- ++ ++ + getServiceSettings(s: service) → (sssa(ss)asa{ss}asa(ss)) ++ ++ ++ This function is deprecated, use org.fedoraproject.FirewallD1.Methods.getServiceSettings2 instead. ++ ++ ++ ++ ++ getServiceSettings2(s: service) → s{sv} + + + Return runtime settings of given service. +- For getting permanent settings see org.fedoraproject.FirewallD1.config.service.Methods.getSettings. +- Settings are in format: version, name, description, array of ports (port, protocol), array of module names, dictionary of destinations, array of protocols, array of source-ports (port, protocol). ++ For getting permanent settings see org.fedoraproject.FirewallD1.config.service.Methods.getSettings2. ++ Settings are a dictionary indexed by keywords. For the type of each value see below. If the value is empty it may be ommitted. + + + +@@ -258,12 +267,13 @@ + module names (as): array of kernel netfilter helpers, see module tag in firewalld.service5. + destinations (a{ss}): dictionary of {IP family : IP address} where 'IP family' key can be either 'ipv4' or 'ipv6'. See destination tag in firewalld.service5. + protocols (as): array of protocols, see protocol tag in firewalld.service5. +- source-ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. ++ source_ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. ++ includes (as): array of service includes, see include tag in firewalld.service5. + + +- +- Possible errors: INVALID_SERVICE +- ++ ++ Possible errors: INVALID_SERVICE ++ + + + +@@ -2293,12 +2303,20 @@ + + + ++ + addService(s: service, (sssa(ss)asa{ss}asa(ss)): settings) → o + + +- Add service with given settings into permanent configuration. +- Settings are in format: version, name, description, array of ports (port, protocol), array of module names, dictionary of destinations, array of protocols and array of source-ports (port, protocol). +- Returns object path of the new icmp type. ++ This function is deprecated, use org.fedoraproject.FirewallD1.config.Methods.addService2 instead. ++ ++ ++ ++ ++ addService2s: service, a{sv}: settings) → o ++ ++ ++ Add service with given settings into permanent configuration. ++ Settings are a dictionary indexed by keywords. For the type of each value see below. To zero a value pass an empty string or list. + + + +@@ -2308,13 +2326,14 @@ + ports (a(ss)): array of port and protocol pairs. See port tag in firewalld.service5. + module names (as): array of kernel netfilter helpers, see module tag in firewalld.service5. + destinations (a{ss}): dictionary of {IP family : IP address} where 'IP family' key can be either 'ipv4' or 'ipv6'. See destination tag in firewalld.service5. +- protocols (as): array of protocols. See protocol tag in firewalld.service5. +- source-ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. ++ protocols (as): array of protocols, see protocol tag in firewalld.service5. ++ source_ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. ++ includes (as): array of service includes, see include tag in firewalld.service5. + + +- +- Possible errors: NAME_CONFLICT, INVALID_NAME, INVALID_TYPE +- ++ ++ Possible errors: NAME_CONFLICT, INVALID_NAME, INVALID_TYPE ++ + + + +@@ -4500,12 +4519,21 @@ + + + ++ + getSettings() → (sssa(ss)asa{ss}asa(ss)) + + +- Return permanent settings of a service. +- For getting runtime settings see org.fedoraproject.FirewallD1.Methods.getServiceSettings. +- Settings are in format: version, name, description, array of ports (port, protocol), array of module names, dictionary of destinations, array of protocols and array of source-ports (port, protocol). ++ This function is deprecated, use org.fedoraproject.FirewallD1.config.service.Methods.getSettings2 instead. ++ ++ ++ ++ ++ getSettings2(s: service) → s{sv} ++ ++ ++ Return runtime settings of given service. ++ For getting runtime settings see org.fedoraproject.FirewallD1.Methods.getServiceSettings2. ++ Settings are a dictionary indexed by keywords. For the type of each value see below. If the value is empty it may be ommitted. + + + +@@ -4515,8 +4543,9 @@ + ports (a(ss)): array of port and protocol pairs. See port tag in firewalld.service5. + module names (as): array of kernel netfilter helpers, see module tag in firewalld.service5. + destinations (a{ss}): dictionary of {IP family : IP address} where 'IP family' key can be either 'ipv4' or 'ipv6'. See destination tag in firewalld.service5. +- protocols (as): array of protocols. See protocol tag in firewalld.service5. +- source-ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. ++ protocols (as): array of protocols, see protocol tag in firewalld.service5. ++ source_ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. ++ includes (as): array of service includes, see include tag in firewalld.service5. + + + +@@ -4774,11 +4803,20 @@ + + + ++ + update((sssa(ss)asa{ss}asa(ss)): settings) → Nothing + + +- Update settings of service to settings. +- Settings are in format: version, name, description, array of ports (port, protocol), array of module names, dictionary of destinations, array of protocols and array of source-ports (port, protocol). ++ This function is deprecated, use org.fedoraproject.FirewallD1.config.service.Methods.update2 instead. ++ ++ ++ ++ ++ update2a{sv}: settings) → Nothing ++ ++ ++ Update settings of service to settings. ++ Settings are a dictionary indexed by keywords. For the type of each value see below. To zero a value pass an empty string or list. + + + +@@ -4788,12 +4826,14 @@ + ports (a(ss)): array of port and protocol pairs. See port tag in firewalld.service5. + module names (as): array of kernel netfilter helpers, see module tag in firewalld.service5. + destinations (a{ss}): dictionary of {IP family : IP address} where 'IP family' key can be either 'ipv4' or 'ipv6'. See destination tag in firewalld.service5. +- protocols (as): array of protocols. See protocol tag in firewalld.service5. ++ protocols (as): array of protocols, see protocol tag in firewalld.service5. ++ source_ports (a(ss)): array of port and protocol pairs. See source-port tag in firewalld.service5. ++ includes (as): array of service includes, see include tag in firewalld.service5. + + +- +- Possible errors: INVALID_TYPE +- ++ ++ Possible errors: INVALID_TYPE ++ + + + +diff --git a/src/firewall/core/io/service.py b/src/firewall/core/io/service.py +index 44dc0ff8a9b0..8236d3078fbe 100644 +--- a/src/firewall/core/io/service.py ++++ b/src/firewall/core/io/service.py +@@ -39,17 +39,16 @@ from firewall.errors import FirewallError + + class Service(IO_Object): + IMPORT_EXPORT_STRUCTURE = ( +- ( "version", "" ), # s +- ( "short", "" ), # s +- ( "description", "" ), # s +- ( "ports", [ ( "", "" ), ], ), # a(ss) +- ( "modules", [ "", ], ), # as +- ( "destination", { "": "", }, ), # a{ss} +- ( "protocols", [ "", ], ), # as +- ( "source_ports", [ ( "", "" ), ], ), # a(ss) +- ( "includes", [ "" ], ), # as ++ ( "version", "" ), ++ ( "short", "" ), ++ ( "description", "" ), ++ ( "ports", [ ( "", "" ), ], ), ++ ( "modules", [ "", ], ), ++ ( "destination", { "": "", }, ), ++ ( "protocols", [ "", ], ), ++ ( "source_ports", [ ( "", "" ), ], ), ++ ( "includes", [ "" ], ), + ) +- DBUS_SIGNATURE = '(sssa(ss)asa{ss}asa(ss))' + ADDITIONAL_ALNUM_CHARS = [ "_", "-" ] + PARSER_REQUIRED_ELEMENT_ATTRS = { + "short": None, +diff --git a/src/firewall/server/config.py b/src/firewall/server/config.py +index 971dc7d4a14a..e03c4984e058 100644 +--- a/src/firewall/server/config.py ++++ b/src/firewall/server/config.py +@@ -41,7 +41,6 @@ from firewall.server.config_zone import FirewallDConfigZone + from firewall.server.config_ipset import FirewallDConfigIPSet + from firewall.server.config_helper import FirewallDConfigHelper + from firewall.core.io.zone import Zone +-from firewall.core.io.service import Service + from firewall.core.io.icmptype import IcmpType + from firewall.core.io.ipset import IPSet + from firewall.core.io.helper import Helper +@@ -1065,7 +1064,7 @@ class FirewallDConfig(slip.dbus.service.Object): + raise FirewallError(errors.INVALID_SERVICE, service) + + @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, +- in_signature='s'+Service.DBUS_SIGNATURE, ++ in_signature='s(sssa(ss)asa{ss}asa(ss))', + out_signature='o') + @dbus_handle_exceptions + def addService(self, service, settings, sender=None): +@@ -1079,6 +1078,21 @@ class FirewallDConfig(slip.dbus.service.Object): + config_service = self._addService(obj) + return config_service + ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG, ++ in_signature='sa{sv}', ++ out_signature='o') ++ @dbus_handle_exceptions ++ def addService2(self, service, settings, sender=None): ++ """add service with given name and settings ++ """ ++ service = dbus_to_python(service, str) ++ settings = dbus_to_python(settings) ++ log.debug1("config.addService2('%s')", service) ++ self.accessCheck(sender) ++ obj = self.config.new_service_dict(service, settings) ++ config_service = self._addService(obj) ++ return config_service ++ + @dbus.service.signal(config.dbus.DBUS_INTERFACE_CONFIG, signature='s') + @dbus_handle_exceptions + def ServiceAdded(self, service): +diff --git a/src/firewall/server/config_service.py b/src/firewall/server/config_service.py +index 05ded1c78da7..3236b3aee135 100644 +--- a/src/firewall/server/config_service.py ++++ b/src/firewall/server/config_service.py +@@ -32,7 +32,6 @@ from firewall import config + from firewall.dbus_utils import dbus_to_python, \ + dbus_introspection_prepare_properties, \ + dbus_introspection_add_properties +-from firewall.core.io.service import Service + from firewall.core.logger import log + from firewall.server.decorators import handle_exceptions, \ + dbus_handle_exceptions, dbus_service_method +@@ -173,7 +172,7 @@ class FirewallDConfigService(slip.dbus.service.Object): + # S E T T I N G S + + @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, +- out_signature=Service.DBUS_SIGNATURE) ++ out_signature='(sssa(ss)asa{ss}asa(ss))') + @dbus_handle_exceptions + def getSettings(self, sender=None): # pylint: disable=W0613 + """get settings for service +@@ -182,7 +181,16 @@ class FirewallDConfigService(slip.dbus.service.Object): + return self.config.get_service_config(self.obj) + + @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, +- in_signature=Service.DBUS_SIGNATURE) ++ out_signature='a{sv}') ++ @dbus_handle_exceptions ++ def getSettings2(self, sender=None): ++ """get settings for service ++ """ ++ log.debug1("%s.getSettings2()", self._log_prefix) ++ return self.config.get_service_config_dict(self.obj) ++ ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, ++ in_signature='(sssa(ss)asa{ss}asa(ss))') + @dbus_handle_exceptions + def update(self, settings, sender=None): + """update settings for service +@@ -193,6 +201,16 @@ class FirewallDConfigService(slip.dbus.service.Object): + self.obj = self.config.set_service_config(self.obj, settings) + self.Updated(self.obj.name) + ++ @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE, ++ in_signature='a{sv}') ++ @dbus_handle_exceptions ++ def update2(self, settings, sender=None): ++ settings = dbus_to_python(settings) ++ log.debug1("%s.update2('...')", self._log_prefix) ++ self.parent.accessCheck(sender) ++ self.obj = self.config.set_service_config_dict(self.obj, settings) ++ self.Updated(self.obj.name) ++ + @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_SERVICE) + @dbus_handle_exceptions + def loadDefaults(self, sender=None): +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index 233160b64b18..06c2834c602e 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -49,7 +49,6 @@ from firewall.dbus_utils import dbus_to_python, \ + from firewall.core.io.functions import check_config + from firewall.core.io.zone import Zone + from firewall.core.io.ipset import IPSet +-from firewall.core.io.service import Service + from firewall.core.io.icmptype import IcmpType + from firewall.core.io.helper import Helper + from firewall.core.fw_nm import nm_get_bus_name, nm_get_connection_of_interface, \ +@@ -916,7 +915,7 @@ class FirewallD(slip.dbus.service.Object): + + @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO) + @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s', +- out_signature=Service.DBUS_SIGNATURE) ++ out_signature='(sssa(ss)asa{ss}asa(ss))') + @dbus_handle_exceptions + def getServiceSettings(self, service, sender=None): # pylint: disable=W0613 + # returns service settings for service +@@ -934,6 +933,16 @@ class FirewallD(slip.dbus.service.Object): + conf_list.append(conf_dict[obj.IMPORT_EXPORT_STRUCTURE[i][0]]) + return tuple(conf_list) + ++ @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG_INFO) ++ @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='s', ++ out_signature='a{sv}') ++ @dbus_handle_exceptions ++ def getServiceSettings2(self, service, sender=None): # pylint: disable=W0613 ++ service = dbus_to_python(service, str) ++ log.debug1("getServiceSettings2(%s)", service) ++ obj = self.fw.service.get_service(service) ++ return obj.export_config() ++ + @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_INFO) + @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='', + out_signature='as') +-- +2.20.1 + diff --git a/SOURCES/0017-test-dbus-coverage-for-new-service-APIs.patch b/SOURCES/0017-test-dbus-coverage-for-new-service-APIs.patch new file mode 100644 index 0000000..a0afd2e --- /dev/null +++ b/SOURCES/0017-test-dbus-coverage-for-new-service-APIs.patch @@ -0,0 +1,186 @@ +From 99ecd06f1f6028bcf9bd7d4ece7f3ce8df39077b Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 25 Jun 2019 18:19:08 -0400 +Subject: [PATCH 17/20] test: dbus: coverage for new service APIs + +(cherry picked from commit 335f238481401e97f3a9bc6773295fe34c89962c) +--- + src/tests/dbus/service.at | 165 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 164 insertions(+), 1 deletion(-) + +diff --git a/src/tests/dbus/service.at b/src/tests/dbus/service.at +index 579548d66509..8ad9334aaa56 100644 +--- a/src/tests/dbus/service.at ++++ b/src/tests/dbus/service.at +@@ -287,4 +287,167 @@ DBUS_CHECK([], [getServiceSettings], ["foobar"], 0, [dnl + [(('1.1', 'foobar new', 'foobar new service is for foobar', [('12345', 'udp'), ('2222', 'tcp')], ['ftp'], @a{ss} {}, ['icmp'], [('4321', 'tcp')]),)] + ]) + +-FWD_END_TEST ++ ++dnl =============== ++dnl New APIs tests ++dnl =============== ++ ++dnl modify service with new API that was created with old API ++dnl Verify old APIs also reflect the change. ++DBUS_CHECK([config], [config.addService], ++ ["foobar-old" dnl name ++ '("1.0", dnl version ++ "foobar-old", dnl short ++ "foobar-old service is for foobar-old", dnl description ++ @<:@("1234", "udp"), ("22", "tcp"), ("1234", "udp")@:>@, dnl ports, deliberate duplicate ++ @<:@"ftp"@:>@, dnl modules ++ {}, dnl destination ++ @<:@@:>@, dnl protocols ++ @<:@("4321", "tcp"), ("4321", "udp")@:>@ dnl source ports ++ )'dnl ++ ], 0, [stdout]) ++SERVICE_OBJ=[$(sed -e "s/.*config\/service\/\([^']\+\)['].*/\1/" ./stdout)] ++export SERVICE_OBJ ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.update2], ++ ['{"version": <"1.1">, ++ "includes": <@<:@"https"@:>@>, ++ "protocols": <@<:@"icmp"@:>@> ++ }'dnl ++ ], 0, [ignore]) ++ ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.getSettings], [], 0, [dnl ++ [(('1.1', 'foobar-old', 'foobar-old service is for foobar-old', [('1234', 'udp'), ('22', 'tcp')], ['ftp'], @a{ss} {}, ['icmp'], [('4321', 'tcp'), ('4321', 'udp')]),)] ++]) ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.getSettings2], [], 0, [dnl ++ ['description': <'foobar-old service is for foobar-old'> ++ 'includes': <['https']> ++ 'modules': <['ftp']> ++ 'ports': <[('1234', 'udp'), ('22', 'tcp')]> ++ 'protocols': <['icmp']> ++ 'short': <'foobar-old'> ++ 'source_ports': <[('4321', 'tcp'), ('4321', 'udp')]> ++ 'version': <'1.1'>] ++]) ++ ++FWD_RELOAD ++DBUS_CHECK([], [getServiceSettings], ["foobar-old"], 0, [dnl ++ [(('1.1', 'foobar-old', 'foobar-old service is for foobar-old', [('1234', 'udp'), ('22', 'tcp')], ['ftp'], @a{ss} {}, ['icmp'], [('4321', 'tcp'), ('4321', 'udp')]),)] ++]) ++DBUS_CHECK([], [getServiceSettings2], ["foobar-old"], 0, [dnl ++ ['description': <'foobar-old service is for foobar-old'> ++ 'includes': <['https']> ++ 'modules': <['ftp']> ++ 'ports': <[('1234', 'udp'), ('22', 'tcp')]> ++ 'protocols': <['icmp']> ++ 'short': <'foobar-old'> ++ 'source_ports': <[('4321', 'tcp'), ('4321', 'udp')]> ++ 'version': <'1.1'>] ++]) ++ ++dnl add service with new API ++DBUS_INTROSPECT([config], [[//method[@name="addService2"]]], 0, [dnl ++ ++ ++ ++ ++ ++]) ++DBUS_CHECK([config], [config.addService2], ++ ["foobar-dict" dnl name ++ '{"version": <"1.0">, ++ "short": <"foobar-dict">, ++ "description": <"foobar-dict service is for foobar-dict">, ++ "ports": <@<:@("1234", "udp"), ("22", "tcp"), ("1234", "udp")@:>@>, ++ "modules": <@<:@"ftp"@:>@>, ++ "destination": <{"ipv6": "1234::4321"}>, ++ "protocols": <@<:@"icmp", "igmp"@:>@>, ++ "source_ports": <@<:@("4321", "tcp"), ("4321", "udp")@:>@>, ++ "includes": <@<:@"https", "samba"@:>@> ++ }'dnl ++ ], 0, [stdout]) ++SERVICE_OBJ=[$(sed -e "s/.*config\/service\/\([^']\+\)['].*/\1/" ./stdout)] ++export SERVICE_OBJ ++ ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="getSettings2"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.getSettings2], [], 0, [dnl ++ ['description': <'foobar-dict service is for foobar-dict'> ++ 'destination': <{'ipv6': '1234::4321'}> ++ 'includes': <['https', 'samba']> ++ 'modules': <['ftp']> ++ 'ports': <[('1234', 'udp'), ('22', 'tcp')]> ++ 'protocols': <['icmp', 'igmp']> ++ 'short': <'foobar-dict'> ++ 'source_ports': <[('4321', 'tcp'), ('4321', 'udp')]> ++ 'version': <'1.0'>] ++]) ++ ++dnl New API allows partial updates to service object ++DBUS_INTROSPECT([config/service/${SERVICE_OBJ}], [[//method[@name="update2"]]], 0, [dnl ++ ++ ++ ++]) ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.update2], ++ ['{"version": <"1.1">, ++ "includes": <@<:@"https", "samba", "http"@:>@> ++ }'dnl ++ ], 0, [ignore]) ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.getSettings2], [], 0, [dnl ++ ['description': <'foobar-dict service is for foobar-dict'> ++ 'destination': <{'ipv6': '1234::4321'}> ++ 'includes': <['https', 'samba', 'http']> ++ 'modules': <['ftp']> ++ 'ports': <[('1234', 'udp'), ('22', 'tcp')]> ++ 'protocols': <['icmp', 'igmp']> ++ 'short': <'foobar-dict'> ++ 'source_ports': <[('4321', 'tcp'), ('4321', 'udp')]> ++ 'version': <'1.1'>] ++]) ++ ++dnl To zero a field you have to set it with an empty value ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.update2], ++ ['{"version": <"1.2">, ++ "includes": <@as @<:@@:>@> ++ }'dnl ++ ], 0, [ignore]) ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.getSettings2], [], 0, [dnl ++ ['description': <'foobar-dict service is for foobar-dict'> ++ 'destination': <{'ipv6': '1234::4321'}> ++ 'modules': <['ftp']> ++ 'ports': <[('1234', 'udp'), ('22', 'tcp')]> ++ 'protocols': <['icmp', 'igmp']> ++ 'short': <'foobar-dict'> ++ 'source_ports': <[('4321', 'tcp'), ('4321', 'udp')]> ++ 'version': <'1.2'>] ++]) ++ ++FWD_RELOAD ++DBUS_INTROSPECT([], [[//method[@name="getServiceSettings2"]]], 0, [dnl ++ ++ ++ ++ ++]) ++DBUS_CHECK([], [getServiceSettings2], ["foobar-dict"], 0, [dnl ++ ['description': <'foobar-dict service is for foobar-dict'> ++ 'destination': <{'ipv6': '1234::4321'}> ++ 'modules': <['ftp']> ++ 'ports': <[('1234', 'udp'), ('22', 'tcp')]> ++ 'protocols': <['icmp', 'igmp']> ++ 'short': <'foobar-dict'> ++ 'source_ports': <[('4321', 'tcp'), ('4321', 'udp')]> ++ 'version': <'1.2'>] ++]) ++ ++dnl bogus arguments ++DBUS_CHECK([config/service/${SERVICE_OBJ}], [config.service.update2], ++ ['{"version": <"1.3">, ++ "thisdoesnotexist": <""> ++ }'dnl ++ ], 1, [ignore], [ignore]) ++ ++FWD_END_TEST([-e '/ERROR: INVALID_OPTION: service option/d']) +-- +2.20.1 + diff --git a/SOURCES/0018-fix-client-service-use-dict-based-dbus-APIs.patch b/SOURCES/0018-fix-client-service-use-dict-based-dbus-APIs.patch new file mode 100644 index 0000000..5986101 --- /dev/null +++ b/SOURCES/0018-fix-client-service-use-dict-based-dbus-APIs.patch @@ -0,0 +1,107 @@ +From f0e4beea7c96478661dd1e3088392400f7cec66e Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 26 Jun 2019 15:07:16 -0400 +Subject: [PATCH 18/20] fix: client: service: use dict based dbus APIs + +Fixes: 1fc208bf9317 ("feat: service includes") +(cherry picked from commit 632380e6efcdfd2282216002bd92f8f6d96467b9) +--- + src/firewall/client.py | 51 ++++++++++++++++++++++++++++++++++-------- + 1 file changed, 42 insertions(+), 9 deletions(-) + +diff --git a/src/firewall/client.py b/src/firewall/client.py +index 242c3a0ab0f4..3c4ea5c63559 100644 +--- a/src/firewall/client.py ++++ b/src/firewall/client.py +@@ -818,15 +818,46 @@ class FirewallClientConfigZone(object): + class FirewallClientServiceSettings(object): + @handle_exceptions + def __init__(self, settings=None): ++ self.settings = ["", "", "", [], [], {}, [], [], []] ++ self.settings_name = ["version", "short", "description", "ports", ++ "modules", "destination", "protocols", ++ "source_ports", "includes"] ++ self.settings_dbus_type = ["s", "s", "s", "(ss)", ++ "s", "ss", "s", ++ "(ss)", "s"] + if settings: +- self.settings = settings +- else: +- self.settings = ["", "", "", [], [], {}, [], [], []] ++ if type(settings) is list: ++ for i,v in enumerate(settings): ++ self.settings[i] = settings[i] ++ elif type(settings) is dict: ++ self.setSettingsDict(settings) + + @handle_exceptions + def __repr__(self): + return '%s(%r)' % (self.__class__, self.settings) + ++ @handle_exceptions ++ def getSettingsDict(self): ++ settings = {} ++ for key,value in zip(self.settings_name, self.settings): ++ settings[key] = value ++ return settings ++ @handle_exceptions ++ def setSettingsDict(self, settings): ++ for key in settings: ++ self.settings[self.settings_name.index(key)] = settings[key] ++ @handle_exceptions ++ def getSettingsDbusDict(self): ++ settings = {} ++ for key,value,sig in zip(self.settings_name, self.settings, self.settings_dbus_type): ++ if type(value) is list: ++ settings[key] = dbus.Array(value, signature=sig) ++ elif type(value) is dict: ++ settings[key] = dbus.Dictionary(value, signature=sig) ++ else: ++ settings[key] = value ++ return settings ++ + @handle_exceptions + def getVersion(self): + return self.settings[0] +@@ -1467,13 +1498,13 @@ class FirewallClientConfigService(object): + @slip.dbus.polkit.enable_proxy + @handle_exceptions + def getSettings(self): +- return FirewallClientServiceSettings(list(dbus_to_python(\ +- self.fw_service.getSettings()))) ++ return FirewallClientServiceSettings(dbus_to_python( ++ self.fw_service.getSettings2())) + + @slip.dbus.polkit.enable_proxy + @handle_exceptions + def update(self, settings): +- self.fw_service.update(tuple(settings.settings)) ++ self.fw_service.update2(settings.getSettingsDbusDict()) + + @slip.dbus.polkit.enable_proxy + @handle_exceptions +@@ -2431,7 +2462,9 @@ class FirewallClientConfig(object): + @handle_exceptions + def addService(self, name, settings): + if isinstance(settings, FirewallClientServiceSettings): +- path = self.fw_config.addService(name, tuple(settings.settings)) ++ path = self.fw_config.addService2(name, settings.getSettingsDbusDict()) ++ elif type(settings) is dict: ++ path = self.fw_config.addService2(name, settings) + else: + path = self.fw_config.addService(name, tuple(settings)) + return FirewallClientConfigService(self.bus, path) +@@ -2899,8 +2932,8 @@ class FirewallClient(object): + @slip.dbus.polkit.enable_proxy + @handle_exceptions + def getServiceSettings(self, service): +- return FirewallClientServiceSettings(list(dbus_to_python(\ +- self.fw.getServiceSettings(service)))) ++ return FirewallClientServiceSettings(dbus_to_python( ++ self.fw.getServiceSettings2(service))) + + @slip.dbus.polkit.enable_proxy + @handle_exceptions +-- +2.20.1 + diff --git a/SOURCES/0019-fix-firewall-offline-cmd-service-use-dict-based-APIs.patch b/SOURCES/0019-fix-firewall-offline-cmd-service-use-dict-based-APIs.patch new file mode 100644 index 0000000..fb1d7e0 --- /dev/null +++ b/SOURCES/0019-fix-firewall-offline-cmd-service-use-dict-based-APIs.patch @@ -0,0 +1,155 @@ +From 588b7960abb8a6191fb8e8e5974d52c961d3aa67 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 2 Jul 2019 15:53:29 -0400 +Subject: [PATCH 19/20] fix: firewall-offline-cmd: service: use dict based APIs + +Fixes: ce631f8515a6 ("feat: CLI: service includes") +(cherry picked from commit 91c1434de8617f547576355ce3028a1bd67f408f) +--- + src/firewall-offline-cmd.in | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +diff --git a/src/firewall-offline-cmd.in b/src/firewall-offline-cmd.in +index 1a8315f8e230..91736c1fafc5 100755 +--- a/src/firewall-offline-cmd.in ++++ b/src/firewall-offline-cmd.in +@@ -1245,8 +1245,8 @@ try: + cmd.print_and_exit(" ".join(services)) + + elif a.new_service: +- fw.config.new_service(a.new_service, +- FirewallClientServiceSettings().settings) ++ fw.config.new_service_dict(a.new_service, ++ FirewallClientServiceSettings().getSettingsDict()) + + elif a.new_service_from_file: + filename = os.path.basename(a.new_service_from_file) +@@ -1287,7 +1287,7 @@ try: + elif a.info_service: + service = fw.config.get_service(a.info_service) + settings = FirewallClientServiceSettings( +- list(fw.config.get_service_config(service))) ++ fw.config.get_service_config_dict(service)) + cmd.print_service_info(a.info_service, settings) + sys.exit(0) + +@@ -1402,17 +1402,17 @@ try: + elif a.service and options_service: + service = fw.config.get_service(a.service) + settings = FirewallClientServiceSettings( +- list(fw.config.get_service_config(service))) ++ fw.config.get_service_config_dict(service)) + + if a.add_port: + cmd.add_sequence(a.add_port, settings.addPort, + settings.queryPort, cmd.parse_port, "%s/%s") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.remove_port: + cmd.remove_sequence(a.remove_port, settings.removePort, + settings.queryPort, cmd.parse_port, "%s/%s") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.query_port: + cmd.query_sequence(a.query_port, settings.queryPort, +@@ -1425,12 +1425,12 @@ try: + elif a.add_protocol: + cmd.add_sequence(a.add_protocol, settings.addProtocol, + settings.queryProtocol, None, "'%s'") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.remove_protocol: + cmd.remove_sequence(a.remove_protocol, settings.removeProtocol, + settings.queryProtocol, None, "'%s'") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.query_protocol: + cmd.query_sequence(a.query_protocol, settings.queryProtocol, +@@ -1443,13 +1443,13 @@ try: + elif a.add_source_port: + cmd.add_sequence(a.add_source_port, settings.addSourcePort, + settings.querySourcePort, cmd.parse_port, "%s/%s") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.remove_source_port: + cmd.remove_sequence(a.remove_source_port, settings.removeSourcePort, + settings.querySourcePort, cmd.parse_port, + "%s/%s") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.query_source_port: + cmd.query_sequence(a.query_source_port, settings.querySourcePort, +@@ -1462,12 +1462,12 @@ try: + elif a.add_module: + cmd.add_sequence(a.add_module, settings.addModule, + settings.queryModule, None, "'%s'") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.remove_module: + cmd.remove_sequence(a.remove_module, settings.removeModule, + settings.queryModule, None, "'%s'") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.query_module: + cmd.query_sequence(a.query_module, settings.queryModule, +@@ -1481,7 +1481,7 @@ try: + cmd.add_sequence(a.set_destination, settings.setDestination, + settings.queryDestination, + cmd.parse_service_destination, "%s:%s") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.remove_destination: + # special case for removeDestination: Only ipv, no address +@@ -1496,7 +1496,7 @@ try: + code) + else: + settings.removeDestination(ipv) +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.query_destination: + cmd.query_sequence(a.query_destination, settings.queryDestination, +@@ -1509,12 +1509,12 @@ try: + elif a.add_include: + cmd.add_sequence(a.add_include, settings.addInclude, + settings.queryInclude, None, "'%s'") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.remove_include: + cmd.remove_sequence(a.remove_include, settings.removeInclude, + settings.queryInclude, None, "'%s'") +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.query_include: + cmd.query_sequence(a.query_include, settings.queryInclude, +@@ -1526,14 +1526,14 @@ try: + + elif a.set_description: + settings.setDescription(a.set_description) +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.get_description: + cmd.print_and_exit(settings.getDescription()) + + elif a.set_short: + settings.setShort(a.set_short) +- fw.config.set_service_config(service, settings.settings) ++ fw.config.set_service_config_dict(service, settings.getSettingsDict()) + + elif a.get_short: + cmd.print_and_exit(settings.getShort()) +-- +2.20.1 + diff --git a/SOURCES/0020-fix-direct-removeRules-was-mistakenly-removing-all-r.patch b/SOURCES/0020-fix-direct-removeRules-was-mistakenly-removing-all-r.patch new file mode 100644 index 0000000..e3eac4f --- /dev/null +++ b/SOURCES/0020-fix-direct-removeRules-was-mistakenly-removing-all-r.patch @@ -0,0 +1,34 @@ +From b91b7cbeeb62cb2ba316918acd0e60a53ed676aa Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 26 Jul 2019 13:32:44 -0400 +Subject: [PATCH 20/26] fix: direct: removeRules() was mistakenly removing all + rules + +Only remove the rules that match the specified criteria (ipv, table, +chain). + +Fixes: #385 +Fixes: rhbz 1723610 +(cherry picked from commit 174005b15059db054b2f8dcf3b35c23fcbaf44ec) +--- + src/firewall/server/config.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/firewall/server/config.py b/src/firewall/server/config.py +index e03c4984e058..b1b839da82ea 100644 +--- a/src/firewall/server/config.py ++++ b/src/firewall/server/config.py +@@ -1422,7 +1422,9 @@ class FirewallDConfig(slip.dbus.service.Object): + (ipv, table, chain, )) + self.accessCheck(sender) + settings = list(self.getSettings()) +- settings[1] = [] ++ for rule in settings[1]: ++ if (ipv, table, chain) == (rule[0], rule[1], rule[2]): ++ settings[1].remove(rule) + self.update(tuple(settings)) + + @dbus_service_method(config.dbus.DBUS_INTERFACE_CONFIG_DIRECT, +-- +2.20.1 + diff --git a/SOURCES/0021-test-coverage-for-rhbz-1723610-and-gh-385.patch b/SOURCES/0021-test-coverage-for-rhbz-1723610-and-gh-385.patch new file mode 100644 index 0000000..6ae5710 --- /dev/null +++ b/SOURCES/0021-test-coverage-for-rhbz-1723610-and-gh-385.patch @@ -0,0 +1,60 @@ +From 53a4e15b72087a84bc59b69936d6bdaa91fa15fd Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 26 Jul 2019 08:26:50 -0400 +Subject: [PATCH 21/26] test: coverage for rhbz 1723610 and gh #385 + +(cherry picked from commit 75fc4876dbfbdb1de09a67c48630fa8503ed152d) +--- + src/tests/regression.at | 1 + + src/tests/regression/rhbz1723610.at | 30 +++++++++++++++++++++++++++++ + 2 files changed, 31 insertions(+) + create mode 100644 src/tests/regression/rhbz1723610.at + +diff --git a/src/tests/regression.at b/src/tests/regression.at +index 3438c97f4633..919fc32f9bfb 100644 +--- a/src/tests/regression.at ++++ b/src/tests/regression.at +@@ -21,3 +21,4 @@ m4_include([regression/gh478.at]) + m4_include([regression/gh453.at]) + m4_include([regression/gh258.at]) + m4_include([regression/rhbz1715977.at]) ++m4_include([regression/rhbz1723610.at]) +diff --git a/src/tests/regression/rhbz1723610.at b/src/tests/regression/rhbz1723610.at +new file mode 100644 +index 000000000000..f020141e1808 +--- /dev/null ++++ b/src/tests/regression/rhbz1723610.at +@@ -0,0 +1,30 @@ ++FWD_START_TEST([direct remove-rules per family]) ++AT_KEYWORDS(direct rhbz1723610 gh385) ++ ++FWD_CHECK([-q --permanent --direct --add-rule ipv4 filter OUTPUT 0 -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT]) ++FWD_CHECK([--permanent --direct --get-all-rules], 0, [dnl ++ipv4 filter OUTPUT 0 -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT ++]) ++FWD_RELOAD ++FWD_CHECK([--direct --get-all-rules], 0, [dnl ++ipv4 filter OUTPUT 0 -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT ++]) ++ ++FWD_CHECK([-q --permanent --direct --remove-rules ipv6 filter input]) ++FWD_CHECK([-q --permanent --direct --remove-rules ipv4 filter INPUT]) ++FWD_CHECK([--permanent --direct --get-all-rules], 0, [dnl ++ipv4 filter OUTPUT 0 -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT ++]) ++FWD_RELOAD ++FWD_CHECK([--direct --get-all-rules], 0, [dnl ++ipv4 filter OUTPUT 0 -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT ++]) ++FWD_CHECK([-q --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT]) ++FWD_CHECK([-q --direct --add-rule ipv6 filter INPUT 0 -p tcp --dport 22 -j ACCEPT]) ++FWD_CHECK([-q --direct --remove-rules ipv4 filter OUTPUT]) ++FWD_CHECK([--direct --get-all-rules], 0, [dnl ++ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT ++ipv6 filter INPUT 0 -p tcp --dport 22 -j ACCEPT ++]) ++ ++FWD_END_TEST +-- +2.20.1 + diff --git a/SOURCES/0022-fix-tests-regression-rhbz1723610-make-output-reliabl.patch b/SOURCES/0022-fix-tests-regression-rhbz1723610-make-output-reliabl.patch new file mode 100644 index 0000000..703ddf2 --- /dev/null +++ b/SOURCES/0022-fix-tests-regression-rhbz1723610-make-output-reliabl.patch @@ -0,0 +1,32 @@ +From 395720e73e84b9b92bd92c5297faf7caa5d10242 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 26 Jul 2019 13:56:54 -0400 +Subject: [PATCH 22/26] fix: tests/regression/rhbz1723610: make output reliable + +The rule listing is unordered, so lets make it reliable. + +Fixes: 75fc4876dbfb ("test: coverage for rhbz 1723610 and gh #385") +(cherry picked from commit 645fc816c09d2d5f767fcecf4bea3d61219780e9) +--- + src/tests/regression/rhbz1723610.at | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/tests/regression/rhbz1723610.at b/src/tests/regression/rhbz1723610.at +index f020141e1808..3eccc0436ed7 100644 +--- a/src/tests/regression/rhbz1723610.at ++++ b/src/tests/regression/rhbz1723610.at +@@ -19,11 +19,9 @@ FWD_RELOAD + FWD_CHECK([--direct --get-all-rules], 0, [dnl + ipv4 filter OUTPUT 0 -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT + ]) +-FWD_CHECK([-q --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT]) + FWD_CHECK([-q --direct --add-rule ipv6 filter INPUT 0 -p tcp --dport 22 -j ACCEPT]) + FWD_CHECK([-q --direct --remove-rules ipv4 filter OUTPUT]) + FWD_CHECK([--direct --get-all-rules], 0, [dnl +-ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT + ipv6 filter INPUT 0 -p tcp --dport 22 -j ACCEPT + ]) + +-- +2.20.1 + diff --git a/SOURCES/0023-fix-tests-regression-rhbz1723610-avoid-calling-IPv6-.patch b/SOURCES/0023-fix-tests-regression-rhbz1723610-avoid-calling-IPv6-.patch new file mode 100644 index 0000000..631d6d9 --- /dev/null +++ b/SOURCES/0023-fix-tests-regression-rhbz1723610-avoid-calling-IPv6-.patch @@ -0,0 +1,35 @@ +From 05d7ecbd8d50e4b80c64443a8351bc943b4bf4a0 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 26 Jul 2019 14:17:28 -0400 +Subject: [PATCH 23/26] fix: tests/regression/rhbz1723610: avoid calling IPv6 + backend + +We support running without IPv6, so calling the backend in the test +case. + +Fixes: 75fc4876dbfb ("test: coverage for rhbz 1723610 and gh #385") +(cherry picked from commit 38978bfde28a3fea9fb4cc61d2bb30ee5474e341) +--- + src/tests/regression/rhbz1723610.at | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tests/regression/rhbz1723610.at b/src/tests/regression/rhbz1723610.at +index 3eccc0436ed7..35feed2bda9f 100644 +--- a/src/tests/regression/rhbz1723610.at ++++ b/src/tests/regression/rhbz1723610.at +@@ -19,10 +19,10 @@ FWD_RELOAD + FWD_CHECK([--direct --get-all-rules], 0, [dnl + ipv4 filter OUTPUT 0 -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT + ]) +-FWD_CHECK([-q --direct --add-rule ipv6 filter INPUT 0 -p tcp --dport 22 -j ACCEPT]) ++FWD_CHECK([-q --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT]) + FWD_CHECK([-q --direct --remove-rules ipv4 filter OUTPUT]) + FWD_CHECK([--direct --get-all-rules], 0, [dnl +-ipv6 filter INPUT 0 -p tcp --dport 22 -j ACCEPT ++ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT + ]) + + FWD_END_TEST +-- +2.20.1 + diff --git a/SOURCES/0024-fix-guarantee-zone-source-dispatch-is-sorted-by-zone.patch b/SOURCES/0024-fix-guarantee-zone-source-dispatch-is-sorted-by-zone.patch new file mode 100644 index 0000000..c30118d --- /dev/null +++ b/SOURCES/0024-fix-guarantee-zone-source-dispatch-is-sorted-by-zone.patch @@ -0,0 +1,871 @@ +From 9cecc7729a8d44fcdec9a4852545286cb7eb8fad Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 31 Jul 2019 13:57:10 -0400 +Subject: [PATCH 24/26] fix: guarantee zone source dispatch is sorted by zone + name + +Apparently users depend on firewalld sorting zone dispatch for sources +by the zone name. This is used to specify precedence for overlapping +address spaces. + +Since we have to track rule positions of source based dispatch we might +as well abuse this and combine the source/interface dispatch into a +single chain. + +Fixes: rhbz 1734765 +Fixes: 70993581d79b ("fix: do not allow zone drifting") +(cherry picked from commit afc35c20e58b00b81cd2e1f3e863b3b3bac37c77) +--- + src/firewall/core/ipXtables.py | 88 ++++++++--- + src/firewall/core/nftables.py | 71 +++++++-- + src/tests/firewall-cmd.at | 14 +- + src/tests/regression/gh258.at | 277 ++++++++++----------------------- + 4 files changed, 211 insertions(+), 239 deletions(-) + +diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py +index 9055e9566d15..2f4ec46d8339 100644 +--- a/src/firewall/core/ipXtables.py ++++ b/src/firewall/core/ipXtables.py +@@ -178,6 +178,7 @@ class ip4tables(object): + self.fill_exists() + self.available_tables = [] + self.rich_rule_priority_counts = {} ++ self.zone_source_index_cache = [] + self.our_chains = {} # chains created by firewalld + + def fill_exists(self): +@@ -289,6 +290,44 @@ class ip4tables(object): + chain = args[i+1] + return (table, chain) + ++ def _run_replace_zone_source(self, rule, zone_source_index_cache): ++ try: ++ i = rule.index("%%ZONE_SOURCE%%") ++ rule.pop(i) ++ zone = rule.pop(i) ++ if "-m" == rule[4]: # ipset/mac ++ zone_source = (zone, rule[7]) # (zone, address) ++ else: ++ zone_source = (zone, rule[5]) # (zone, address) ++ except ValueError: ++ try: ++ i = rule.index("%%ZONE_INTERFACE%%") ++ rule.pop(i) ++ zone_source = None ++ except ValueError: ++ return ++ ++ rule_add = True ++ if rule[0] in ["-D", "--delete"]: ++ rule_add = False ++ ++ if zone_source and not rule_add: ++ if zone_source in zone_source_index_cache: ++ zone_source_index_cache.remove(zone_source) ++ elif rule_add: ++ if zone_source: ++ # order source based dispatch by zone name ++ if zone_source not in zone_source_index_cache: ++ zone_source_index_cache.append(zone_source) ++ zone_source_index_cache.sort(key=lambda x: x[0]) ++ ++ index = zone_source_index_cache.index(zone_source) ++ else: ++ index = len(zone_source_index_cache) ++ ++ rule[0] = "-I" ++ rule.insert(2, "%d" % (index + 1)) ++ + def _set_rule_replace_rich_rule_priority(self, rule, rich_rule_priority_counts): + """ + Change something like +@@ -374,6 +413,7 @@ class ip4tables(object): + + table_rules = { } + rich_rule_priority_counts = copy.deepcopy(self.rich_rule_priority_counts) ++ zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache) + for _rule in rules: + rule = _rule[:] + +@@ -398,6 +438,7 @@ class ip4tables(object): + rule.pop(i) + + self._set_rule_replace_rich_rule_priority(rule, rich_rule_priority_counts) ++ self._run_replace_zone_source(rule, zone_source_index_cache) + + table = "filter" + # get table form rule +@@ -461,6 +502,7 @@ class ip4tables(object): + raise ValueError("'%s %s' failed: %s" % (self._restore_command, + " ".join(args), ret)) + self.rich_rule_priority_counts = rich_rule_priority_counts ++ self.zone_source_index_cache = zone_source_index_cache + return ret + + def set_rule(self, rule, log_denied): +@@ -485,9 +527,14 @@ class ip4tables(object): + rule.pop(i) + + rich_rule_priority_counts = copy.deepcopy(self.rich_rule_priority_counts) ++ zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache) + self._set_rule_replace_rich_rule_priority(rule, rich_rule_priority_counts) ++ self._run_replace_zone_source(rule, zone_source_index_cache) ++ + output = self.__run(rule) ++ + self.rich_rule_priority_counts = rich_rule_priority_counts ++ self.zone_source_index_cache = zone_source_index_cache + return output + + def get_available_tables(self, table=None): +@@ -539,6 +586,7 @@ class ip4tables(object): + + def build_flush_rules(self): + self.rich_rule_priority_counts = {} ++ self.zone_source_index_cache = [] + rules = [] + for table in BUILT_IN_CHAINS.keys(): + if not self.get_available_tables(table): +@@ -620,10 +668,8 @@ class ip4tables(object): + + if chain == "PREROUTING": + default_rules["raw"].append("-N %s_ZONES" % chain) +- default_rules["raw"].append("-N %s_ZONES_IFACES" % chain) + default_rules["raw"].append("-A %s -j %s_ZONES" % (chain, chain)) +- default_rules["raw"].append("-A %s_ZONES -g %s_ZONES_IFACES" % (chain, chain)) +- self.our_chains["raw"].update(set(["%s_ZONES" % chain, "%s_ZONES_IFACES" % chain])) ++ self.our_chains["raw"].update(set(["%s_ZONES" % chain])) + + if self.get_available_tables("mangle"): + default_rules["mangle"] = [ ] +@@ -635,10 +681,8 @@ class ip4tables(object): + + if chain == "PREROUTING": + default_rules["mangle"].append("-N %s_ZONES" % chain) +- default_rules["mangle"].append("-N %s_ZONES_IFACES" % chain) + default_rules["mangle"].append("-A %s -j %s_ZONES" % (chain, chain)) +- default_rules["mangle"].append("-A %s_ZONES -g %s_ZONES_IFACES" % (chain, chain)) +- self.our_chains["mangle"].update(set(["%s_ZONES" % chain, "%s_ZONES_IFACES" % chain])) ++ self.our_chains["mangle"].update(set(["%s_ZONES" % chain])) + + if self.get_available_tables("nat"): + default_rules["nat"] = [ ] +@@ -650,21 +694,17 @@ class ip4tables(object): + + if chain in [ "PREROUTING", "POSTROUTING" ]: + default_rules["nat"].append("-N %s_ZONES" % chain) +- default_rules["nat"].append("-N %s_ZONES_IFACES" % chain) + default_rules["nat"].append("-A %s -j %s_ZONES" % (chain, chain)) +- default_rules["nat"].append("-A %s_ZONES -g %s_ZONES_IFACES" % (chain, chain)) +- self.our_chains["nat"].update(set(["%s_ZONES" % chain, "%s_ZONES_IFACES" % chain])) ++ self.our_chains["nat"].update(set(["%s_ZONES" % chain])) + + default_rules["filter"] = [ + "-N INPUT_direct", + "-N INPUT_ZONES", +- "-N INPUT_ZONES_IFACES", + + "-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT", + "-A INPUT -i lo -j ACCEPT", + "-A INPUT -j INPUT_direct", + "-A INPUT -j INPUT_ZONES", +- "-A INPUT_ZONES -g INPUT_ZONES_IFACES", + ] + if log_denied != "off": + default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '") +@@ -677,16 +717,12 @@ class ip4tables(object): + "-N FORWARD_direct", + "-N FORWARD_IN_ZONES", + "-N FORWARD_OUT_ZONES", +- "-N FORWARD_IN_ZONES_IFACES", +- "-N FORWARD_OUT_ZONES_IFACES", + + "-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT", + "-A FORWARD -i lo -j ACCEPT", + "-A FORWARD -j FORWARD_direct", + "-A FORWARD -j FORWARD_IN_ZONES", + "-A FORWARD -j FORWARD_OUT_ZONES", +- "-A FORWARD_IN_ZONES -g FORWARD_IN_ZONES_IFACES", +- "-A FORWARD_OUT_ZONES -g FORWARD_OUT_ZONES_IFACES", + ] + if log_denied != "off": + default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '") +@@ -702,10 +738,9 @@ class ip4tables(object): + "-A OUTPUT -j OUTPUT_direct", + ] + +- self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES", "INPUT_ZONES_IFACES" ++ self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES", + "FORWARD_direct", "FORWARD_IN_ZONES", +- "FORWARD_IN_ZONES_IFACES" "FORWARD_OUT_ZONES", +- "FORWARD_OUT_ZONES_IFACES", "OUTPUT_direct"]) ++ "FORWARD_OUT_ZONES", "OUTPUT_direct"]) + + final_default_rules = [] + for table in default_rules: +@@ -748,11 +783,13 @@ class ip4tables(object): + action = "-g" + + if enable and not append: +- rule = [ "-I", "%s_ZONES_IFACES" % chain, "1" ] ++ rule = [ "-I", "%s_ZONES" % chain, "%%ZONE_INTERFACE%%" ] + elif enable: +- rule = [ "-A", "%s_ZONES_IFACES" % chain ] ++ rule = [ "-A", "%s_ZONES" % chain ] + else: +- rule = [ "-D", "%s_ZONES_IFACES" % chain ] ++ rule = [ "-D", "%s_ZONES" % chain ] ++ if not append: ++ rule += ["%%ZONE_INTERFACE%%"] + rule += [ "-t", table, opt, interface, action, target ] + return [rule] + +@@ -780,7 +817,8 @@ class ip4tables(object): + opt = "src" + flags = ",".join([opt] * self._fw.ipset.get_dimension(name)) + rule = [ add_del, +- "%s_ZONES" % chain, "-t", table, ++ "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ "-t", table, + "-m", "set", "--match-set", name, + flags, action, target ] + else: +@@ -789,12 +827,14 @@ class ip4tables(object): + if opt == "-d": + return "" + rule = [ add_del, +- "%s_ZONES" % chain, "-t", table, ++ "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ "-t", table, + "-m", "mac", "--mac-source", address.upper(), + action, target ] + else: + rule = [ add_del, +- "%s_ZONES" % chain, "-t", table, ++ "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ "-t", table, + opt, address, action, target ] + return [rule] + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index ba52a0e87493..c0b48f1501fd 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -157,6 +157,7 @@ class nftables(object): + self.rule_to_handle = {} + self.rule_ref_count = {} + self.rich_rule_priority_counts = {} ++ self.zone_source_index_cache = {} + self.used_families = ["inet", "ip", "ip6"] + + def fill_exists(self): +@@ -171,6 +172,48 @@ class nftables(object): + raise FirewallError(INVALID_RULE, "position/handle not allowed in rule") + return " ".join([str(x) for x in rule_key]) + ++ def _run_replace_zone_source(self, rule_add, rule, zone_source_index_cache): ++ try: ++ i = rule.index("%%ZONE_SOURCE%%") ++ rule.pop(i) ++ zone = rule.pop(i) ++ zone_source = (zone, rule[7]) # (zone, address) ++ except ValueError: ++ try: ++ i = rule.index("%%ZONE_INTERFACE%%") ++ rule.pop(i) ++ zone_source = None ++ except ValueError: ++ return ++ ++ family = rule[2] ++ ++ if zone_source and not rule_add: ++ if family in zone_source_index_cache and \ ++ zone_source in zone_source_index_cache[family]: ++ zone_source_index_cache[family].remove(zone_source) ++ elif rule_add: ++ if family not in zone_source_index_cache: ++ zone_source_index_cache[family] = [] ++ ++ if zone_source: ++ # order source based dispatch by zone name ++ if zone_source not in zone_source_index_cache[family]: ++ zone_source_index_cache[family].append(zone_source) ++ zone_source_index_cache[family].sort(key=lambda x: x[0]) ++ ++ index = zone_source_index_cache[family].index(zone_source) ++ else: ++ index = len(zone_source_index_cache[family]) ++ ++ if index == 0: ++ rule[0] = "insert" ++ else: ++ index -= 1 # point to the rule before insertion point ++ rule[0] = "add" ++ rule.insert(i, "index") ++ rule.insert(i+1, "%d" % index) ++ + def __run(self, args): + nft_opts = ["--echo", "--handle"] + _args = args[:] +@@ -257,6 +300,10 @@ class nftables(object): + _args.insert(i, "index") + _args.insert(i+1, "%d" % index) + ++ if rule_key: ++ zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache) ++ self._run_replace_zone_source(rule_add, _args, zone_source_index_cache) ++ + if not rule_key or (not rule_add and self.rule_ref_count[rule_key] == 0) \ + or ( rule_add and rule_key not in self.rule_ref_count): + +@@ -274,6 +321,7 @@ class nftables(object): + + if rule_key: + self.rich_rule_priority_counts = rich_rule_priority_counts ++ self.zone_source_index_cache = zone_source_index_cache + + # nft requires deleting rules by handle. So we must cache the rule + # handle when adding/inserting rules. +@@ -362,6 +410,7 @@ class nftables(object): + self.rule_to_handle = saved_rule_to_handle + self.rule_ref_count = saved_rule_ref_count + self.rich_rule_priority_counts = {} ++ self.zone_source_index_cache = {} + + rules = [] + for family in self.used_families: +@@ -440,9 +489,7 @@ class nftables(object): + + for chain in ["PREROUTING"]: + default_rules.append("add chain inet %s raw_%s_ZONES" % (TABLE_NAME, chain)) +- default_rules.append("add chain inet %s raw_%s_ZONES_IFACES" % (TABLE_NAME, chain)) + default_rules.append("add rule inet %s raw_%s jump raw_%s_ZONES" % (TABLE_NAME, chain, chain)) +- default_rules.append("add rule inet %s raw_%s_ZONES goto raw_%s_ZONES_IFACES" % (TABLE_NAME, chain, chain)) + + for chain in IPTABLES_TO_NFT_HOOK["mangle"].keys(): + default_rules.append("add chain inet %s mangle_%s '{ type filter hook %s priority %d ; }'" % +@@ -451,9 +498,7 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["mangle"][chain][1])) + + default_rules.append("add chain inet %s mangle_%s_ZONES" % (TABLE_NAME, chain)) +- default_rules.append("add chain inet %s mangle_%s_ZONES_IFACES" % (TABLE_NAME, chain)) + default_rules.append("add rule inet %s mangle_%s jump mangle_%s_ZONES" % (TABLE_NAME, chain, chain)) +- default_rules.append("add rule inet %s mangle_%s_ZONES goto mangle_%s_ZONES_IFACES" % (TABLE_NAME, chain, chain)) + + for family in ["ip", "ip6"]: + for chain in IPTABLES_TO_NFT_HOOK["nat"].keys(): +@@ -463,9 +508,7 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["nat"][chain][1])) + + default_rules.append("add chain %s %s nat_%s_ZONES" % (family, TABLE_NAME, chain)) +- default_rules.append("add chain %s %s nat_%s_ZONES_IFACES" % (family, TABLE_NAME, chain)) + default_rules.append("add rule %s %s nat_%s jump nat_%s_ZONES" % (family, TABLE_NAME, chain, chain)) +- default_rules.append("add rule %s %s nat_%s_ZONES goto nat_%s_ZONES_IFACES" % (family, TABLE_NAME, chain, chain)) + + for chain in IPTABLES_TO_NFT_HOOK["filter"].keys(): + default_rules.append("add chain inet %s filter_%s '{ type filter hook %s priority %d ; }'" % +@@ -475,12 +518,10 @@ class nftables(object): + + # filter, INPUT + default_rules.append("add chain inet %s filter_%s_ZONES" % (TABLE_NAME, "INPUT")) +- default_rules.append("add chain inet %s filter_%s_ZONES_IFACES" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct status dnat accept" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s jump filter_%s_ZONES" % (TABLE_NAME, "INPUT", "INPUT")) +- default_rules.append("add rule inet %s filter_%s_ZONES goto filter_%s_ZONES_IFACES" % (TABLE_NAME, "INPUT", "INPUT")) + if log_denied != "off": + default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "INPUT")) +@@ -490,16 +531,12 @@ class nftables(object): + + # filter, FORWARD + default_rules.append("add chain inet %s filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD")) +- default_rules.append("add chain inet %s filter_%s_IN_ZONES_IFACES" % (TABLE_NAME, "FORWARD")) + default_rules.append("add chain inet %s filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD")) +- default_rules.append("add chain inet %s filter_%s_OUT_ZONES_IFACES" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct status dnat accept" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s jump filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD")) + default_rules.append("add rule inet %s filter_%s jump filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD")) +- default_rules.append("add rule inet %s filter_%s_IN_ZONES goto filter_%s_IN_ZONES_IFACES" % (TABLE_NAME, "FORWARD", "FORWARD")) +- default_rules.append("add rule inet %s filter_%s_OUT_ZONES goto filter_%s_OUT_ZONES_IFACES" % (TABLE_NAME, "FORWARD", "FORWARD")) + if log_denied != "off": + default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "FORWARD")) +@@ -554,11 +591,14 @@ class nftables(object): + action = "goto" + + if enable and not append: +- rule = ["insert", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)] ++ rule = ["insert", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain), ++ "%%ZONE_INTERFACE%%"] + elif enable: +- rule = ["add", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)] ++ rule = ["add", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain)] + else: +- rule = ["delete", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)] ++ rule = ["delete", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain)] ++ if not append: ++ rule += ["%%ZONE_INTERFACE%%"] + if interface == "*": + rule += [action, "%s_%s" % (table, target)] + else: +@@ -609,6 +649,7 @@ class nftables(object): + + rule = [add_del, "rule", family, "%s" % TABLE_NAME, + "%s_%s_ZONES" % (table, chain), ++ "%%ZONE_SOURCE%%", zone, + rule_family, opt, address, action, "%s_%s" % (table, target)] + return [rule] + +diff --git a/src/tests/firewall-cmd.at b/src/tests/firewall-cmd.at +index 7bb13aee0221..53f2eb2c7c88 100644 +--- a/src/tests/firewall-cmd.at ++++ b/src/tests/firewall-cmd.at +@@ -148,14 +148,14 @@ FWD_START_TEST([zone interfaces]) + FWD_CHECK([--zone=trusted --add-interface=+], 0, ignore) + FWD_CHECK([--add-interface=foobar+++], 0, ignore) + FWD_CHECK([--add-interface=foobar+], 0, ignore) +- NFT_LIST_RULES([inet], [filter_INPUT_ZONES_IFACES], 0, [dnl ++ NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl + table inet firewalld { +- chain filter_INPUT_ZONES_IFACES { +- iifname "foobar*" goto filter_IN_public +- iifname "foobar++*" goto filter_IN_public +- goto filter_IN_trusted +- goto filter_IN_public +- } ++ chain filter_INPUT_ZONES { ++ iifname "foobar*" goto filter_IN_public ++ iifname "foobar++*" goto filter_IN_public ++ goto filter_IN_trusted ++ goto filter_IN_public ++ } + } + ]) + FWD_CHECK([--zone=trusted --remove-interface=+], 0, ignore) +diff --git a/src/tests/regression/gh258.at b/src/tests/regression/gh258.at +index ba76946f0333..1896a9bfc61c 100644 +--- a/src/tests/regression/gh258.at ++++ b/src/tests/regression/gh258.at +@@ -9,7 +9,6 @@ FWD_CHECK([--zone=work --add-interface=dummy0], 0, ignore) + FWD_CHECK([--zone=public --add-interface=dummy1], 0, ignore) + + dnl verify layout of zone dispatch +-m4_if(nftables, FIREWALL_BACKEND, [ + NFT_LIST_RULES([inet], [filter_INPUT], 0, [dnl + table inet firewalld { + chain filter_INPUT { +@@ -27,13 +26,6 @@ NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl + chain filter_INPUT_ZONES { + ip6 saddr dead:beef::/54 goto filter_IN_public + ip saddr 1.2.3.0/24 goto filter_IN_work +- goto filter_INPUT_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([inet], [filter_INPUT_ZONES_IFACES], 0, [dnl +- table inet firewalld { +- chain filter_INPUT_ZONES_IFACES { + iifname "dummy1" goto filter_IN_public + iifname "dummy0" goto filter_IN_work + goto filter_IN_public +@@ -59,13 +51,6 @@ NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES], 0, [dnl + chain filter_FORWARD_IN_ZONES { + ip6 saddr dead:beef::/54 goto filter_FWDI_public + ip saddr 1.2.3.0/24 goto filter_FWDI_work +- goto filter_FORWARD_IN_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES_IFACES], 0, [dnl +- table inet firewalld { +- chain filter_FORWARD_IN_ZONES_IFACES { + iifname "dummy1" goto filter_FWDI_public + iifname "dummy0" goto filter_FWDI_work + goto filter_FWDI_public +@@ -77,13 +62,6 @@ NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES], 0, [dnl + chain filter_FORWARD_OUT_ZONES { + ip6 daddr dead:beef::/54 goto filter_FWDO_public + ip daddr 1.2.3.0/24 goto filter_FWDO_work +- goto filter_FORWARD_OUT_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES_IFACES], 0, [dnl +- table inet firewalld { +- chain filter_FORWARD_OUT_ZONES_IFACES { + oifname "dummy1" goto filter_FWDO_public + oifname "dummy0" goto filter_FWDO_work + goto filter_FWDO_public +@@ -106,13 +84,6 @@ NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES], 0, [dnl + chain raw_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto raw_PRE_public + ip saddr 1.2.3.0/24 goto raw_PRE_work +- goto raw_PREROUTING_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES_IFACES], 0, [dnl +- table inet firewalld { +- chain raw_PREROUTING_ZONES_IFACES { + iifname "dummy1" goto raw_PRE_public + iifname "dummy0" goto raw_PRE_work + goto raw_PRE_public +@@ -131,13 +102,6 @@ NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES], 0, [dnl + chain mangle_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto mangle_PRE_public + ip saddr 1.2.3.0/24 goto mangle_PRE_work +- goto mangle_PREROUTING_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES_IFACES], 0, [dnl +- table inet firewalld { +- chain mangle_PREROUTING_ZONES_IFACES { + iifname "dummy1" goto mangle_PRE_public + iifname "dummy0" goto mangle_PRE_work + goto mangle_PRE_public +@@ -155,13 +119,6 @@ NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES], 0, [dnl + table ip firewalld { + chain nat_PREROUTING_ZONES { + ip saddr 1.2.3.0/24 goto nat_PRE_work +- goto nat_PREROUTING_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES_IFACES], 0, [dnl +- table ip firewalld { +- chain nat_PREROUTING_ZONES_IFACES { + iifname "dummy1" goto nat_PRE_public + iifname "dummy0" goto nat_PRE_work + goto nat_PRE_public +@@ -179,13 +136,6 @@ NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl + table ip firewalld { + chain nat_POSTROUTING_ZONES { + ip daddr 1.2.3.0/24 goto nat_POST_work +- goto nat_POSTROUTING_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_IFACES], 0, [dnl +- table ip firewalld { +- chain nat_POSTROUTING_ZONES_IFACES { + oifname "dummy1" goto nat_POST_public + oifname "dummy0" goto nat_POST_work + goto nat_POST_public +@@ -203,13 +153,6 @@ NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES], 0, [dnl + table ip6 firewalld { + chain nat_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto nat_PRE_public +- goto nat_PREROUTING_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES_IFACES], 0, [dnl +- table ip6 firewalld { +- chain nat_PREROUTING_ZONES_IFACES { + iifname "dummy1" goto nat_PRE_public + iifname "dummy0" goto nat_PRE_work + goto nat_PRE_public +@@ -227,20 +170,12 @@ NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl + table ip6 firewalld { + chain nat_POSTROUTING_ZONES { + ip6 daddr dead:beef::/54 goto nat_POST_public +- goto nat_POSTROUTING_ZONES_IFACES +- } +- } +-]) +-NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_IFACES], 0, [dnl +- table ip firewalld { +- chain nat_POSTROUTING_ZONES_IFACES { + oifname "dummy1" goto nat_POST_public + oifname "dummy0" goto nat_POST_work + goto nat_POST_public + } + } + ]) +-], [ + + IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl + ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT +@@ -250,15 +185,12 @@ IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl + DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID + REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited + ]) +-IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, [dnl +- IN_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@ +- INPUT_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([filter], [INPUT_ZONES_IFACES], 0, [dnl +- IN_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- IN_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- IN_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) + IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT + ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 +@@ -268,77 +200,58 @@ IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID + REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited + ]) +-IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, [dnl +- FWDI_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@ +- FORWARD_IN_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_IFACES], 0, [dnl +- FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- FWDI_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, [dnl +- FWDO_work all -- 0.0.0.0/0 1.2.3.0/24 @<:@goto@:>@ +- FORWARD_OUT_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_IFACES], 0, [dnl +- FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- FWDO_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) ++IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, ++ [[FWDI_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDI_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, ++ [[FWDO_work all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDO_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) + IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl + PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) +-IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, [dnl +- PRE_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@ +- PREROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES_IFACES], 0, [dnl +- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) ++IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, ++ [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) + IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl + PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) +-IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, [dnl +- PRE_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@ +- PREROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES_IFACES], 0, [dnl +- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) ++IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, ++ [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) + IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl + PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) +-IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, [dnl +- PRE_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@ +- PREROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES_IFACES], 0, [dnl +- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) ++IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, ++ [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) + IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl + POSTROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 + POSTROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) +-IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, [dnl +- POST_work all -- 0.0.0.0/0 1.2.3.0/24 @<:@goto@:>@ +- POSTROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +-IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES_IFACES], 0, [dnl +- POST_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- POST_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +- POST_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@ +-]) +- ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_work all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) + + IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl + ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT +@@ -348,15 +261,12 @@ IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl + DROP all ::/0 ::/0 ctstate INVALID + REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited + ]) +-IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, [dnl +- IN_public all dead:beef::/54 ::/0 @<:@goto@:>@ +- INPUT_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([filter], [INPUT_ZONES_IFACES], 0, [dnl +- IN_public all ::/0 ::/0 @<:@goto@:>@ +- IN_work all ::/0 ::/0 @<:@goto@:>@ +- IN_public all ::/0 ::/0 @<:@goto@:>@ +-]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_public all dead:beef::/54 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++ IN_work all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++]]) + IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT + ACCEPT all ::/0 ::/0 +@@ -367,24 +277,18 @@ IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + DROP all ::/0 ::/0 ctstate INVALID + REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited + ]) +-IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, [dnl +- FWDI_public all dead:beef::/54 ::/0 @<:@goto@:>@ +- FORWARD_IN_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_IFACES], 0, [dnl +- FWDI_public all ::/0 ::/0 @<:@goto@:>@ +- FWDI_work all ::/0 ::/0 @<:@goto@:>@ +- FWDI_public all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, [dnl +- FWDO_public all ::/0 dead:beef::/54 @<:@goto@:>@ +- FORWARD_OUT_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_IFACES], 0, [dnl +- FWDO_public all ::/0 ::/0 @<:@goto@:>@ +- FWDO_work all ::/0 ::/0 @<:@goto@:>@ +- FWDO_public all ::/0 ::/0 @<:@goto@:>@ +-]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, ++ [[FWDI_public all dead:beef::/54 ::/0 [goto] ++ FWDI_public all ::/0 ::/0 [goto] ++ FWDI_work all ::/0 ::/0 [goto] ++ FWDI_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, ++ [[FWDO_public all ::/0 dead:beef::/54 [goto] ++ FWDO_public all ::/0 ::/0 [goto] ++ FWDO_work all ::/0 ::/0 [goto] ++ FWDO_public all ::/0 ::/0 [goto] ++]]) + IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl + ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 134 + ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 135 +@@ -392,54 +296,41 @@ IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl + PREROUTING_direct all ::/0 ::/0 + PREROUTING_ZONES all ::/0 ::/0 + ]) +-IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, [dnl +- PRE_public all dead:beef::/54 ::/0 @<:@goto@:>@ +- PREROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES_IFACES], 0, [dnl +- PRE_public all ::/0 ::/0 @<:@goto@:>@ +- PRE_work all ::/0 ::/0 @<:@goto@:>@ +- PRE_public all ::/0 ::/0 @<:@goto@:>@ +-]) ++IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_work all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) + IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl + PREROUTING_direct all ::/0 ::/0 + PREROUTING_ZONES all ::/0 ::/0 + ]) +-IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, [dnl +- PRE_public all dead:beef::/54 ::/0 @<:@goto@:>@ +- PREROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES_IFACES], 0, [dnl +- PRE_public all ::/0 ::/0 @<:@goto@:>@ +- PRE_work all ::/0 ::/0 @<:@goto@:>@ +- PRE_public all ::/0 ::/0 @<:@goto@:>@ +-]) ++IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_work all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) + IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl + PREROUTING_direct all ::/0 ::/0 + PREROUTING_ZONES all ::/0 ::/0 + ]) +-IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, [dnl +- PRE_public all dead:beef::/54 ::/0 @<:@goto@:>@ +- PREROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES_IFACES], 0, [dnl +- PRE_public all ::/0 ::/0 @<:@goto@:>@ +- PRE_work all ::/0 ::/0 @<:@goto@:>@ +- PRE_public all ::/0 ::/0 @<:@goto@:>@ +-]) ++IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_work all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) + IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl + POSTROUTING_direct all ::/0 ::/0 + POSTROUTING_ZONES all ::/0 ::/0 + ]) +-IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, [dnl +- POST_public all ::/0 dead:beef::/54 @<:@goto@:>@ +- POSTROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@ +-]) +-IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES_IFACES], 0, [dnl +- POST_public all ::/0 ::/0 @<:@goto@:>@ +- POST_work all ::/0 ::/0 @<:@goto@:>@ +- POST_public all ::/0 ::/0 @<:@goto@:>@ +-]) +-]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_public all ::/0 dead:beef::/54 [goto] ++ POST_public all ::/0 ::/0 [goto] ++ POST_work all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++]]) + + FWD_END_TEST +-- +2.20.1 + diff --git a/SOURCES/0025-test-verify-source-based-zone-dispatch-ordered-by-zo.patch b/SOURCES/0025-test-verify-source-based-zone-dispatch-ordered-by-zo.patch new file mode 100644 index 0000000..62e4168 --- /dev/null +++ b/SOURCES/0025-test-verify-source-based-zone-dispatch-ordered-by-zo.patch @@ -0,0 +1,184 @@ +From 4fc4e688596dc030955fc18f3207b75c8de06452 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 31 Jul 2019 08:53:51 -0400 +Subject: [PATCH 25/26] test: verify source-based zone dispatch ordered by zone + name + +coverage for rhbz 1734765 + +(cherry picked from commit 25032eb3a60706f22e1b2c0f34d2be8d0b82c89f) +--- + src/tests/regression.at | 1 + + src/tests/regression/rhbz1734765.at | 151 ++++++++++++++++++++++++++++ + 2 files changed, 152 insertions(+) + create mode 100644 src/tests/regression/rhbz1734765.at + +diff --git a/src/tests/regression.at b/src/tests/regression.at +index 919fc32f9bfb..6f57a1122925 100644 +--- a/src/tests/regression.at ++++ b/src/tests/regression.at +@@ -22,3 +22,4 @@ m4_include([regression/gh453.at]) + m4_include([regression/gh258.at]) + m4_include([regression/rhbz1715977.at]) + m4_include([regression/rhbz1723610.at]) ++m4_include([regression/rhbz1734765.at]) +diff --git a/src/tests/regression/rhbz1734765.at b/src/tests/regression/rhbz1734765.at +new file mode 100644 +index 000000000000..3d54ceb6628f +--- /dev/null ++++ b/src/tests/regression/rhbz1734765.at +@@ -0,0 +1,151 @@ ++FWD_START_TEST([zone sources ordered by name]) ++AT_KEYWORDS(zone rhbz1734765 rhbz1421222 gh166) ++dnl ++dnl Users depend on firewalld ordering source-based zone dispatch by zone name. ++dnl ++ ++FWD_CHECK([-q --permanent --new-zone=foobar_00]) ++FWD_CHECK([-q --permanent --new-zone=foobar_05]) ++FWD_CHECK([-q --permanent --new-zone=foobar_02]) ++FWD_CHECK([-q --permanent --new-zone=foobar_03]) ++FWD_CHECK([-q --permanent --new-zone=foobar_01]) ++FWD_CHECK([-q --permanent --new-zone=foobar_04]) ++FWD_CHECK([-q --permanent --new-zone=foobar_010]) ++ ++FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="10.1.1.1" --add-source="1234:5678::1:1:1"]) ++FWD_CHECK([-q --permanent --zone=foobar_01 --add-source="10.1.1.0/24" --add-source="1234:5678::1:1:0/112"]) ++FWD_CHECK([-q --permanent --zone=foobar_02 --add-source="10.1.0.0/16" --add-source="1234:5678::1:0:0/96"]) ++FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="10.2.2.0/24" --add-source="1234:5678::2:2:0/112"]) ++FWD_CHECK([-q --permanent --zone=foobar_04 --add-source="10.2.0.0/16" --add-source="1234:5678::2:0:0/96"]) ++FWD_CHECK([-q --permanent --zone=foobar_05 --add-source="10.0.0.0/8" --add-source="1234:5678::0:0:0/80"]) ++ ++FWD_CHECK([-q --permanent --zone=internal --add-interface=foobar0]) ++FWD_CHECK([-q --permanent --zone=trusted --add-interface=foobar1]) ++ ++FWD_RELOAD ++ ++FWD_CHECK([-q --zone=foobar_010 --add-source="10.10.10.10" --add-source="1234:5678::10:10:10"]) ++FWD_CHECK([-q --zone=public --add-source="20.20.20.20" --add-source="1234:5678::20:20:20"]) ++FWD_CHECK([-q --zone=foobar_010 --add-interface=foobar2]) ++ ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES { ++ ip saddr 10.1.1.1 goto filter_IN_foobar_00 ++ ip6 saddr 1234:5678::1:1:1 goto filter_IN_foobar_00 ++ ip saddr 10.1.1.0/24 goto filter_IN_foobar_01 ++ ip6 saddr 1234:5678::1:1:0/112 goto filter_IN_foobar_01 ++ ip saddr 10.10.10.10 goto filter_IN_foobar_010 ++ ip6 saddr 1234:5678::10:10:10 goto filter_IN_foobar_010 ++ ip saddr 10.1.0.0/16 goto filter_IN_foobar_02 ++ ip6 saddr 1234:5678::1:0:0/96 goto filter_IN_foobar_02 ++ ip saddr 10.2.2.0/24 goto filter_IN_foobar_03 ++ ip6 saddr 1234:5678::2:2:0/112 goto filter_IN_foobar_03 ++ ip saddr 10.2.0.0/16 goto filter_IN_foobar_04 ++ ip6 saddr 1234:5678::2:0:0/96 goto filter_IN_foobar_04 ++ ip saddr 10.0.0.0/8 goto filter_IN_foobar_05 ++ ip6 saddr 1234:5678::/80 goto filter_IN_foobar_05 ++ ip saddr 20.20.20.20 goto filter_IN_public ++ ip6 saddr 1234:5678::20:20:20 goto filter_IN_public ++ iifname "foobar2" goto filter_IN_foobar_010 ++ iifname "foobar1" goto filter_IN_trusted ++ iifname "foobar0" goto filter_IN_internal ++ goto filter_IN_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES { ++ ip daddr 10.1.1.1 goto nat_POST_foobar_00 ++ ip daddr 10.1.1.0/24 goto nat_POST_foobar_01 ++ ip daddr 10.10.10.10 goto nat_POST_foobar_010 ++ ip daddr 10.1.0.0/16 goto nat_POST_foobar_02 ++ ip daddr 10.2.2.0/24 goto nat_POST_foobar_03 ++ ip daddr 10.2.0.0/16 goto nat_POST_foobar_04 ++ ip daddr 10.0.0.0/8 goto nat_POST_foobar_05 ++ ip daddr 20.20.20.20 goto nat_POST_public ++ oifname "foobar2" goto nat_POST_foobar_010 ++ oifname "foobar1" goto nat_POST_trusted ++ oifname "foobar0" goto nat_POST_internal ++ goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES { ++ ip6 daddr 1234:5678::1:1:1 goto nat_POST_foobar_00 ++ ip6 daddr 1234:5678::1:1:0/112 goto nat_POST_foobar_01 ++ ip6 daddr 1234:5678::10:10:10 goto nat_POST_foobar_010 ++ ip6 daddr 1234:5678::1:0:0/96 goto nat_POST_foobar_02 ++ ip6 daddr 1234:5678::2:2:0/112 goto nat_POST_foobar_03 ++ ip6 daddr 1234:5678::2:0:0/96 goto nat_POST_foobar_04 ++ ip6 daddr 1234:5678::/80 goto nat_POST_foobar_05 ++ ip6 daddr 1234:5678::20:20:20 goto nat_POST_public ++ oifname "foobar2" goto nat_POST_foobar_010 ++ oifname "foobar1" goto nat_POST_trusted ++ oifname "foobar0" goto nat_POST_internal ++ goto nat_POST_public ++ } ++ } ++]) ++ ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_foobar_00 all -- 10.1.1.1 0.0.0.0/0 [goto] ++ IN_foobar_01 all -- 10.1.1.0/24 0.0.0.0/0 [goto] ++ IN_foobar_010 all -- 10.10.10.10 0.0.0.0/0 [goto] ++ IN_foobar_02 all -- 10.1.0.0/16 0.0.0.0/0 [goto] ++ IN_foobar_03 all -- 10.2.2.0/24 0.0.0.0/0 [goto] ++ IN_foobar_04 all -- 10.2.0.0/16 0.0.0.0/0 [goto] ++ IN_foobar_05 all -- 10.0.0.0/8 0.0.0.0/0 [goto] ++ IN_public all -- 20.20.20.20 0.0.0.0/0 [goto] ++ IN_foobar_010 all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_internal all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_foobar_00 all 1234:5678::1:1:1 ::/0 [goto] ++ IN_foobar_01 all 1234:5678::1:1:0/112 ::/0 [goto] ++ IN_foobar_010 all 1234:5678::10:10:10 ::/0 [goto] ++ IN_foobar_02 all 1234:5678::1:0:0/96 ::/0 [goto] ++ IN_foobar_03 all 1234:5678::2:2:0/112 ::/0 [goto] ++ IN_foobar_04 all 1234:5678::2:0:0/96 ::/0 [goto] ++ IN_foobar_05 all 1234:5678::/80 ::/0 [goto] ++ IN_public all 1234:5678::20:20:20 ::/0 [goto] ++ IN_foobar_010 all ::/0 ::/0 [goto] ++ IN_trusted all ::/0 ::/0 [goto] ++ IN_internal all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_foobar_00 all -- 0.0.0.0/0 10.1.1.1 [goto] ++ POST_foobar_01 all -- 0.0.0.0/0 10.1.1.0/24 [goto] ++ POST_foobar_010 all -- 0.0.0.0/0 10.10.10.10 [goto] ++ POST_foobar_02 all -- 0.0.0.0/0 10.1.0.0/16 [goto] ++ POST_foobar_03 all -- 0.0.0.0/0 10.2.2.0/24 [goto] ++ POST_foobar_04 all -- 0.0.0.0/0 10.2.0.0/16 [goto] ++ POST_foobar_05 all -- 0.0.0.0/0 10.0.0.0/8 [goto] ++ POST_public all -- 0.0.0.0/0 20.20.20.20 [goto] ++ POST_foobar_010 all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_internal all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_foobar_00 all ::/0 1234:5678::1:1:1 [goto] ++ POST_foobar_01 all ::/0 1234:5678::1:1:0/112 [goto] ++ POST_foobar_010 all ::/0 1234:5678::10:10:10 [goto] ++ POST_foobar_02 all ::/0 1234:5678::1:0:0/96 [goto] ++ POST_foobar_03 all ::/0 1234:5678::2:2:0/112 [goto] ++ POST_foobar_04 all ::/0 1234:5678::2:0:0/96 [goto] ++ POST_foobar_05 all ::/0 1234:5678::/80 [goto] ++ POST_public all ::/0 1234:5678::20:20:20 [goto] ++ POST_foobar_010 all ::/0 ::/0 [goto] ++ POST_trusted all ::/0 ::/0 [goto] ++ POST_internal all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++]]) ++ ++FWD_END_TEST +-- +2.20.1 + diff --git a/SOURCES/0026-fix-test-regression-rhbz1734765-guard-IPv6-usage.patch b/SOURCES/0026-fix-test-regression-rhbz1734765-guard-IPv6-usage.patch new file mode 100644 index 0000000..5e0c4bd --- /dev/null +++ b/SOURCES/0026-fix-test-regression-rhbz1734765-guard-IPv6-usage.patch @@ -0,0 +1,59 @@ +From c094e3d548374e7b63ce72b2a1deebcde718a567 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 5 Aug 2019 16:06:07 -0400 +Subject: [PATCH 26/26] fix: test: regression/rhbz1734765: guard IPv6 usage + +Fixes: 25032eb3a607 ("test: verify source-based zone dispatch ordered by zone name") +(cherry picked from commit f4411b95e127fea7a7ed87cd2b01e59c2ce333c5) +--- + src/tests/regression/rhbz1734765.at | 28 ++++++++++++++++++++-------- + 1 file changed, 20 insertions(+), 8 deletions(-) + +diff --git a/src/tests/regression/rhbz1734765.at b/src/tests/regression/rhbz1734765.at +index 3d54ceb6628f..d2158e34b547 100644 +--- a/src/tests/regression/rhbz1734765.at ++++ b/src/tests/regression/rhbz1734765.at +@@ -12,20 +12,32 @@ FWD_CHECK([-q --permanent --new-zone=foobar_01]) + FWD_CHECK([-q --permanent --new-zone=foobar_04]) + FWD_CHECK([-q --permanent --new-zone=foobar_010]) + +-FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="10.1.1.1" --add-source="1234:5678::1:1:1"]) +-FWD_CHECK([-q --permanent --zone=foobar_01 --add-source="10.1.1.0/24" --add-source="1234:5678::1:1:0/112"]) +-FWD_CHECK([-q --permanent --zone=foobar_02 --add-source="10.1.0.0/16" --add-source="1234:5678::1:0:0/96"]) +-FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="10.2.2.0/24" --add-source="1234:5678::2:2:0/112"]) +-FWD_CHECK([-q --permanent --zone=foobar_04 --add-source="10.2.0.0/16" --add-source="1234:5678::2:0:0/96"]) +-FWD_CHECK([-q --permanent --zone=foobar_05 --add-source="10.0.0.0/8" --add-source="1234:5678::0:0:0/80"]) ++FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="10.1.1.1"]) ++FWD_CHECK([-q --permanent --zone=foobar_01 --add-source="10.1.1.0/24"]) ++FWD_CHECK([-q --permanent --zone=foobar_02 --add-source="10.1.0.0/16"]) ++FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="10.2.2.0/24"]) ++FWD_CHECK([-q --permanent --zone=foobar_04 --add-source="10.2.0.0/16"]) ++FWD_CHECK([-q --permanent --zone=foobar_05 --add-source="10.0.0.0/8"]) ++IF_IPV6_SUPPORTED([ ++FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="1234:5678::1:1:1"]) ++FWD_CHECK([-q --permanent --zone=foobar_01 --add-source="1234:5678::1:1:0/112"]) ++FWD_CHECK([-q --permanent --zone=foobar_02 --add-source="1234:5678::1:0:0/96"]) ++FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="1234:5678::2:2:0/112"]) ++FWD_CHECK([-q --permanent --zone=foobar_04 --add-source="1234:5678::2:0:0/96"]) ++FWD_CHECK([-q --permanent --zone=foobar_05 --add-source="1234:5678::0:0:0/80"]) ++]) + + FWD_CHECK([-q --permanent --zone=internal --add-interface=foobar0]) + FWD_CHECK([-q --permanent --zone=trusted --add-interface=foobar1]) + + FWD_RELOAD + +-FWD_CHECK([-q --zone=foobar_010 --add-source="10.10.10.10" --add-source="1234:5678::10:10:10"]) +-FWD_CHECK([-q --zone=public --add-source="20.20.20.20" --add-source="1234:5678::20:20:20"]) ++FWD_CHECK([-q --zone=foobar_010 --add-source="10.10.10.10"]) ++FWD_CHECK([-q --zone=public --add-source="20.20.20.20"]) ++IF_IPV6_SUPPORTED([ ++FWD_CHECK([-q --zone=foobar_010 --add-source="1234:5678::10:10:10"]) ++FWD_CHECK([-q --zone=public --add-source="1234:5678::20:20:20"]) ++]) + FWD_CHECK([-q --zone=foobar_010 --add-interface=foobar2]) + + NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl +-- +2.20.1 + diff --git a/SOURCES/0027-fix-nftables-fix-zone-dispatch-using-ipset-sources-i.patch b/SOURCES/0027-fix-nftables-fix-zone-dispatch-using-ipset-sources-i.patch new file mode 100644 index 0000000..9ed9aa5 --- /dev/null +++ b/SOURCES/0027-fix-nftables-fix-zone-dispatch-using-ipset-sources-i.patch @@ -0,0 +1,41 @@ +From ec38f84551e7488ca42ce06d028138d40539e47c Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 8 Aug 2019 13:40:01 -0400 +Subject: [PATCH 27/28] fix: nftables: fix zone dispatch using ipset sources in + nat chains + +If using an ipset as a zone source the rules for doing a goto to the +zone's rules were omitted. This means the zone's rules for nat +postrouting/prerouting were not having any effect. Affected features; +masquerade, forward-ports + +(cherry picked from commit b363548f2ab0983d7b88dd82620c0c545e2cef39) +--- + src/firewall/core/nftables.py | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index c0b48f1501fd..33a170a76a98 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -610,10 +610,15 @@ class nftables(object): + # nat tables needs to use ip/ip6 family + if table == "nat" and family == "inet": + rules = [] +- if check_address("ipv4", address) or check_mac(address): ++ if address.startswith("ipset:"): ++ ipset_family = self._set_get_family(address[len("ipset:"):]) ++ else: ++ ipset_family = None ++ ++ if check_address("ipv4", address) or check_mac(address) or ipset_family == "ip": + rules.extend(self.build_zone_source_address_rules(enable, zone, + address, table, chain, "ip")) +- if check_address("ipv6", address) or check_mac(address): ++ if check_address("ipv6", address) or check_mac(address) or ipset_family == "ip6": + rules.extend(self.build_zone_source_address_rules(enable, zone, + address, table, chain, "ip6")) + return rules +-- +2.20.1 + diff --git a/SOURCES/0028-test-regression-rhbz1734765-add-coverage-for-rhbz-17.patch b/SOURCES/0028-test-regression-rhbz1734765-add-coverage-for-rhbz-17.patch new file mode 100644 index 0000000..b24e586 --- /dev/null +++ b/SOURCES/0028-test-regression-rhbz1734765-add-coverage-for-rhbz-17.patch @@ -0,0 +1,147 @@ +From 197b393ddab8d144d869a8a4f024e6ba1e92d941 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 7 Aug 2019 08:41:11 -0400 +Subject: [PATCH 28/28] test: regression/rhbz1734765: add coverage for rhbz + 1738545 + +(cherry picked from commit 20cd5c7d29c586fa55e76d6f21adfee6a7ca34bb) +--- + src/tests/regression/rhbz1734765.at | 46 +++++++++++++++++++++++++---- + 1 file changed, 41 insertions(+), 5 deletions(-) + +diff --git a/src/tests/regression/rhbz1734765.at b/src/tests/regression/rhbz1734765.at +index d2158e34b547..168be70a2900 100644 +--- a/src/tests/regression/rhbz1734765.at ++++ b/src/tests/regression/rhbz1734765.at +@@ -1,5 +1,5 @@ + FWD_START_TEST([zone sources ordered by name]) +-AT_KEYWORDS(zone rhbz1734765 rhbz1421222 gh166) ++AT_KEYWORDS(zone rhbz1734765 rhbz1421222 gh166 rhbz1738545) + dnl + dnl Users depend on firewalld ordering source-based zone dispatch by zone name. + dnl +@@ -11,20 +11,28 @@ FWD_CHECK([-q --permanent --new-zone=foobar_03]) + FWD_CHECK([-q --permanent --new-zone=foobar_01]) + FWD_CHECK([-q --permanent --new-zone=foobar_04]) + FWD_CHECK([-q --permanent --new-zone=foobar_010]) ++FWD_CHECK([-q --permanent --new-zone=foobar_011]) ++FWD_CHECK([-q --permanent --new-zone=foobar_012]) + +-FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="10.1.1.1"]) ++FWD_CHECK([-q --permanent --new-ipset 'ipsetv4' --type hash:ip]) ++FWD_CHECK([-q --permanent --new-ipset 'ipsetv6' --type hash:ip --family=inet6]) ++FWD_CHECK([-q --permanent --ipset ipsetv4 --add-entry '192.0.2.12']) ++FWD_CHECK([-q --permanent --ipset ipsetv6 --add-entry '::2']) ++ ++FWD_CHECK([-q --permanent --zone=foobar_011 --add-source ipset:ipsetv4]) + FWD_CHECK([-q --permanent --zone=foobar_01 --add-source="10.1.1.0/24"]) + FWD_CHECK([-q --permanent --zone=foobar_02 --add-source="10.1.0.0/16"]) +-FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="10.2.2.0/24"]) + FWD_CHECK([-q --permanent --zone=foobar_04 --add-source="10.2.0.0/16"]) ++FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="10.1.1.1"]) ++FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="10.2.2.0/24"]) + FWD_CHECK([-q --permanent --zone=foobar_05 --add-source="10.0.0.0/8"]) + IF_IPV6_SUPPORTED([ +-FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="1234:5678::1:1:1"]) + FWD_CHECK([-q --permanent --zone=foobar_01 --add-source="1234:5678::1:1:0/112"]) + FWD_CHECK([-q --permanent --zone=foobar_02 --add-source="1234:5678::1:0:0/96"]) +-FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="1234:5678::2:2:0/112"]) + FWD_CHECK([-q --permanent --zone=foobar_04 --add-source="1234:5678::2:0:0/96"]) ++FWD_CHECK([-q --permanent --zone=foobar_03 --add-source="1234:5678::2:2:0/112"]) + FWD_CHECK([-q --permanent --zone=foobar_05 --add-source="1234:5678::0:0:0/80"]) ++FWD_CHECK([-q --permanent --zone=foobar_00 --add-source="1234:5678::1:1:1"]) + ]) + + FWD_CHECK([-q --permanent --zone=internal --add-interface=foobar0]) +@@ -32,11 +40,31 @@ FWD_CHECK([-q --permanent --zone=trusted --add-interface=foobar1]) + + FWD_RELOAD + ++NFT_LIST_SET([ipsetv4], 0, [dnl ++ table inet firewalld { ++ set ipsetv4 { ++ type ipv4_addr ++ flags interval ++ elements = { 192.0.2.12 } ++ } ++ } ++]) ++NFT_LIST_SET([ipsetv6], 0, [dnl ++ table inet firewalld { ++ set ipsetv6 { ++ type ipv6_addr ++ flags interval ++ elements = { ::2 } ++ } ++ } ++]) ++ + FWD_CHECK([-q --zone=foobar_010 --add-source="10.10.10.10"]) + FWD_CHECK([-q --zone=public --add-source="20.20.20.20"]) + IF_IPV6_SUPPORTED([ + FWD_CHECK([-q --zone=foobar_010 --add-source="1234:5678::10:10:10"]) + FWD_CHECK([-q --zone=public --add-source="1234:5678::20:20:20"]) ++FWD_CHECK([-q --zone=foobar_012 --add-source ipset:ipsetv6]) + ]) + FWD_CHECK([-q --zone=foobar_010 --add-interface=foobar2]) + +@@ -49,6 +77,8 @@ NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl + ip6 saddr 1234:5678::1:1:0/112 goto filter_IN_foobar_01 + ip saddr 10.10.10.10 goto filter_IN_foobar_010 + ip6 saddr 1234:5678::10:10:10 goto filter_IN_foobar_010 ++ ip saddr @ipsetv4 goto filter_IN_foobar_011 ++ ip6 saddr @ipsetv6 goto filter_IN_foobar_012 + ip saddr 10.1.0.0/16 goto filter_IN_foobar_02 + ip6 saddr 1234:5678::1:0:0/96 goto filter_IN_foobar_02 + ip saddr 10.2.2.0/24 goto filter_IN_foobar_03 +@@ -72,6 +102,7 @@ NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl + ip daddr 10.1.1.1 goto nat_POST_foobar_00 + ip daddr 10.1.1.0/24 goto nat_POST_foobar_01 + ip daddr 10.10.10.10 goto nat_POST_foobar_010 ++ ip daddr @ipsetv4 goto nat_POST_foobar_011 + ip daddr 10.1.0.0/16 goto nat_POST_foobar_02 + ip daddr 10.2.2.0/24 goto nat_POST_foobar_03 + ip daddr 10.2.0.0/16 goto nat_POST_foobar_04 +@@ -90,6 +121,7 @@ NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl + ip6 daddr 1234:5678::1:1:1 goto nat_POST_foobar_00 + ip6 daddr 1234:5678::1:1:0/112 goto nat_POST_foobar_01 + ip6 daddr 1234:5678::10:10:10 goto nat_POST_foobar_010 ++ ip6 daddr @ipsetv6 goto nat_POST_foobar_012 + ip6 daddr 1234:5678::1:0:0/96 goto nat_POST_foobar_02 + ip6 daddr 1234:5678::2:2:0/112 goto nat_POST_foobar_03 + ip6 daddr 1234:5678::2:0:0/96 goto nat_POST_foobar_04 +@@ -107,6 +139,7 @@ IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, + [[IN_foobar_00 all -- 10.1.1.1 0.0.0.0/0 [goto] + IN_foobar_01 all -- 10.1.1.0/24 0.0.0.0/0 [goto] + IN_foobar_010 all -- 10.10.10.10 0.0.0.0/0 [goto] ++ IN_foobar_011 all -- 0.0.0.0/0 0.0.0.0/0 [goto] match-set ipsetv4 src + IN_foobar_02 all -- 10.1.0.0/16 0.0.0.0/0 [goto] + IN_foobar_03 all -- 10.2.2.0/24 0.0.0.0/0 [goto] + IN_foobar_04 all -- 10.2.0.0/16 0.0.0.0/0 [goto] +@@ -121,6 +154,7 @@ IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, + [[IN_foobar_00 all 1234:5678::1:1:1 ::/0 [goto] + IN_foobar_01 all 1234:5678::1:1:0/112 ::/0 [goto] + IN_foobar_010 all 1234:5678::10:10:10 ::/0 [goto] ++ IN_foobar_012 all ::/0 ::/0 [goto] match-set ipsetv6 src + IN_foobar_02 all 1234:5678::1:0:0/96 ::/0 [goto] + IN_foobar_03 all 1234:5678::2:2:0/112 ::/0 [goto] + IN_foobar_04 all 1234:5678::2:0:0/96 ::/0 [goto] +@@ -135,6 +169,7 @@ IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, + [[POST_foobar_00 all -- 0.0.0.0/0 10.1.1.1 [goto] + POST_foobar_01 all -- 0.0.0.0/0 10.1.1.0/24 [goto] + POST_foobar_010 all -- 0.0.0.0/0 10.10.10.10 [goto] ++ POST_foobar_011 all -- 0.0.0.0/0 0.0.0.0/0 [goto] match-set ipsetv4 dst + POST_foobar_02 all -- 0.0.0.0/0 10.1.0.0/16 [goto] + POST_foobar_03 all -- 0.0.0.0/0 10.2.2.0/24 [goto] + POST_foobar_04 all -- 0.0.0.0/0 10.2.0.0/16 [goto] +@@ -149,6 +184,7 @@ IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, + [[POST_foobar_00 all ::/0 1234:5678::1:1:1 [goto] + POST_foobar_01 all ::/0 1234:5678::1:1:0/112 [goto] + POST_foobar_010 all ::/0 1234:5678::10:10:10 [goto] ++ POST_foobar_012 all ::/0 ::/0 [goto] match-set ipsetv6 dst + POST_foobar_02 all ::/0 1234:5678::1:0:0/96 [goto] + POST_foobar_03 all ::/0 1234:5678::2:2:0/112 [goto] + POST_foobar_04 all ::/0 1234:5678::2:0:0/96 [goto] +-- +2.20.1 + diff --git a/SOURCES/0030-feat-AllowZoneDrifting-config-option.patch b/SOURCES/0030-feat-AllowZoneDrifting-config-option.patch new file mode 100644 index 0000000..ce1f3a7 --- /dev/null +++ b/SOURCES/0030-feat-AllowZoneDrifting-config-option.patch @@ -0,0 +1,284 @@ +From 3fbf366505d866c042e9dbc29a3fb6f30aff5459 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 14:13:36 -0500 +Subject: [PATCH 30/35] feat: AllowZoneDrifting config option + +Older versions of firewalld had undocumented behavior known as "zone +drifting". This allowed packets to ingress multiple zones - this is a +violation of zone based firewalls. However, some users rely on this +behavior to have a "catch-all" zone, e.g. the default zone. You can +enable this if you desire such behavior. It's disabled by default for +security reasons. + +Note: If "yes" packets will only drift from source based zones to +interface based zones (including the default zone). Packets never drift +from interface based zones to other interfaces based zones (including +the default zone). + +(cherry picked from commit afadd377b09dc62b340d24bcf891d31f040d1a18) +(cherry picked from commit cb71601436854404b59e53fbdf3eaea1dec9bd80) +--- + config/firewalld.conf | 12 ++++++++++++ + doc/xml/firewalld.conf.xml | 19 +++++++++++++++++++ + doc/xml/firewalld.dbus.xml | 16 ++++++++++++++++ + src/firewall/config/__init__.py.in | 1 + + src/firewall/core/fw.py | 14 ++++++++++++++ + src/firewall/core/io/firewalld_conf.py | 13 +++++++++++-- + src/firewall/server/config.py | 20 +++++++++++++++++--- + src/tests/dbus/firewalld.conf.at | 2 ++ + 8 files changed, 92 insertions(+), 5 deletions(-) + +diff --git a/config/firewalld.conf b/config/firewalld.conf +index 423b7ea0733a..ebf8021226b7 100644 +--- a/config/firewalld.conf ++++ b/config/firewalld.conf +@@ -71,3 +71,15 @@ FlushAllOnReload=yes + # internet. + # Defaults to "yes". + RFC3964_IPv4=yes ++ ++# AllowZoneDrifting ++# Older versions of firewalld had undocumented behavior known as "zone ++# drifting". This allowed packets to ingress multiple zones - this is a ++# violation of zone based firewalls. However, some users rely on this behavior ++# to have a "catch-all" zone, e.g. the default zone. You can enable this if you ++# desire such behavior. It's disabled by default for security reasons. ++# Note: If "yes" packets will only drift from source based zones to interface ++# based zones (including the default zone). Packets never drift from interface ++# based zones to other interfaces based zones (including the default zone). ++# Possible values; "yes", "no". Defaults to "no". ++AllowZoneDrifting=no +diff --git a/doc/xml/firewalld.conf.xml b/doc/xml/firewalld.conf.xml +index 1e229ed1d8b6..8108066e88bf 100644 +--- a/doc/xml/firewalld.conf.xml ++++ b/doc/xml/firewalld.conf.xml +@@ -183,6 +183,25 @@ + + + ++ ++ ++ ++ ++ Older versions of firewalld had undocumented behavior known ++ as "zone drifting". This allowed packets to ingress multiple ++ zones - this is a violation of zone based firewalls. However, ++ some users rely on this behavior to have a "catch-all" zone, ++ e.g. the default zone. You can enable this if you desire such ++ behavior. It's disabled by default for security reasons. ++ Note: If "yes" packets will only drift from source based zones ++ to interface based zones (including the default zone). Packets ++ never drift from interface based zones to other interfaces ++ based zones (including the default zone). ++ Valid values; "yes", "no". Defaults to "no". ++ ++ ++ ++ + + + +diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml +index 4a81e8e61858..f72bad526d65 100644 +--- a/doc/xml/firewalld.dbus.xml ++++ b/doc/xml/firewalld.dbus.xml +@@ -2577,6 +2577,22 @@ + + Properties + ++ ++ AllowZoneDrifting - s - (rw) ++ ++ Older versions of firewalld had undocumented behavior known ++ as "zone drifting". This allowed packets to ingress multiple ++ zones - this is a violation of zone based firewalls. However, ++ some users rely on this behavior to have a "catch-all" zone, ++ e.g. the default zone. You can enable this if you desire such ++ behavior. It's disabled by default for security reasons. ++ Note: If "yes" packets will only drift from source based zones ++ to interface based zones (including the default zone). Packets ++ never drift from interface based zones to other interfaces ++ based zones (including the default zone). ++ Valid values; "yes", "no". Defaults to "no". ++ ++ + + AutomaticHelpers - s - (rw) + +diff --git a/src/firewall/config/__init__.py.in b/src/firewall/config/__init__.py.in +index 5bb318c5b269..c009d93e4164 100644 +--- a/src/firewall/config/__init__.py.in ++++ b/src/firewall/config/__init__.py.in +@@ -132,3 +132,4 @@ FALLBACK_AUTOMATIC_HELPERS = "system" + FALLBACK_FIREWALL_BACKEND = "nftables" + FALLBACK_FLUSH_ALL_ON_RELOAD = True + FALLBACK_RFC3964_IPV4 = True ++FALLBACK_ALLOW_ZONE_DRIFTING = False +diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py +index a09c022a2baf..07bc9f375771 100644 +--- a/src/firewall/core/fw.py ++++ b/src/firewall/core/fw.py +@@ -127,6 +127,7 @@ class Firewall(object): + self.nf_conntrack_helper_setting = 0 + self.nf_conntrack_helpers = { } + self.nf_nat_helpers = { } ++ self._allow_zone_drifting = config.FALLBACK_ALLOW_ZONE_DRIFTING + + def individual_calls(self): + return self._individual_calls +@@ -324,6 +325,19 @@ class Firewall(object): + log.debug1("RFC3964_IPv4 is set to '%s'", + self._rfc3964_ipv4) + ++ if self._firewalld_conf.get("AllowZoneDrifting"): ++ value = self._firewalld_conf.get("AllowZoneDrifting") ++ if value.lower() in [ "no", "false" ]: ++ self._allow_zone_drifting = False ++ else: ++ self._allow_zone_drifting = True ++ log.warning("AllowZoneDrifting is enabled. This is considered " ++ "an insecure configuration option. It will be " ++ "removed in a future release. Please consider " ++ "disabling it now.") ++ log.debug1("AllowZoneDrifting is set to '%s'", ++ self._allow_zone_drifting) ++ + self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf)) + + self._select_firewall_backend(self._firewall_backend) +diff --git a/src/firewall/core/io/firewalld_conf.py b/src/firewall/core/io/firewalld_conf.py +index c7a7ba283e0e..aec62e3a753c 100644 +--- a/src/firewall/core/io/firewalld_conf.py ++++ b/src/firewall/core/io/firewalld_conf.py +@@ -28,10 +28,10 @@ from firewall import config + from firewall.core.logger import log + from firewall.functions import b2u, u2b, PY2 + +-valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown", ++valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown", + "IPv6_rpfilter", "IndividualCalls", "LogDenied", + "AutomaticHelpers", "FirewallBackend", "FlushAllOnReload", +- "RFC3964_IPv4" ] ++ "RFC3964_IPv4", "AllowZoneDrifting" ] + + class firewalld_conf(object): + def __init__(self, filename): +@@ -83,6 +83,7 @@ class firewalld_conf(object): + self.set("FirewallBackend", config.FALLBACK_FIREWALL_BACKEND) + self.set("FlushAllOnReload", "yes" if config.FALLBACK_FLUSH_ALL_ON_RELOAD else "no") + self.set("RFC3964_IPv4", "yes" if config.FALLBACK_RFC3964_IPV4 else "no") ++ self.set("AllowZoneDrifting", "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no") + raise + + for line in f: +@@ -202,6 +203,14 @@ class firewalld_conf(object): + config.FALLBACK_RFC3964_IPV4) + self.set("RFC3964_IPv4", str(config.FALLBACK_RFC3964_IPV4)) + ++ value = self.get("AllowZoneDrifting") ++ if not value or value.lower() not in [ "yes", "true", "no", "false" ]: ++ if value is not None: ++ log.warning("AllowZoneDrifting '%s' is not valid, using default " ++ "value %s", value if value else '', ++ config.FALLBACK_ALLOW_ZONE_DRIFTING) ++ self.set("AllowZoneDrifting", str(config.FALLBACK_ALLOW_ZONE_DRIFTING)) ++ + # save to self.filename if there are key/value changes + def write(self): + if len(self._config) < 1: +diff --git a/src/firewall/server/config.py b/src/firewall/server/config.py +index b1b839da82ea..4315c6ac1589 100644 +--- a/src/firewall/server/config.py ++++ b/src/firewall/server/config.py +@@ -107,6 +107,7 @@ class FirewallDConfig(slip.dbus.service.Object): + "FirewallBackend": "readwrite", + "FlushAllOnReload": "readwrite", + "RFC3964_IPv4": "readwrite", ++ "AllowZoneDrifting": "readwrite", + }) + + @handle_exceptions +@@ -487,7 +488,8 @@ class FirewallDConfig(slip.dbus.service.Object): + if prop not in [ "DefaultZone", "MinimalMark", "CleanupOnExit", + "Lockdown", "IPv6_rpfilter", "IndividualCalls", + "LogDenied", "AutomaticHelpers", "FirewallBackend", +- "FlushAllOnReload", "RFC3964_IPv4" ]: ++ "FlushAllOnReload", "RFC3964_IPv4", ++ "AllowZoneDrifting" ]: + raise dbus.exceptions.DBusException( + "org.freedesktop.DBus.Error.InvalidArgs: " + "Property '%s' does not exist" % prop) +@@ -540,6 +542,10 @@ class FirewallDConfig(slip.dbus.service.Object): + if value is None: + value = "yes" if config.FALLBACK_RFC3964_IPV4 else "no" + return dbus.String(value) ++ elif prop == "AllowZoneDrifting": ++ if value is None: ++ value = "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no" ++ return dbus.String(value) + + @dbus_handle_exceptions + def _get_dbus_property(self, prop): +@@ -565,6 +571,8 @@ class FirewallDConfig(slip.dbus.service.Object): + return dbus.String(self._get_property(prop)) + elif prop == "RFC3964_IPv4": + return dbus.String(self._get_property(prop)) ++ elif prop == "AllowZoneDrifting": ++ return dbus.String(self._get_property(prop)) + else: + raise dbus.exceptions.DBusException( + "org.freedesktop.DBus.Error.InvalidArgs: " +@@ -605,7 +613,8 @@ class FirewallDConfig(slip.dbus.service.Object): + for x in [ "DefaultZone", "MinimalMark", "CleanupOnExit", + "Lockdown", "IPv6_rpfilter", "IndividualCalls", + "LogDenied", "AutomaticHelpers", "FirewallBackend", +- "FlushAllOnReload", "RFC3964_IPv4" ]: ++ "FlushAllOnReload", "RFC3964_IPv4", ++ "AllowZoneDrifting" ]: + ret[x] = self._get_property(x) + elif interface_name in [ config.dbus.DBUS_INTERFACE_CONFIG_DIRECT, + config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]: +@@ -633,7 +642,7 @@ class FirewallDConfig(slip.dbus.service.Object): + "IPv6_rpfilter", "IndividualCalls", + "LogDenied", "AutomaticHelpers", + "FirewallBackend", "FlushAllOnReload", +- "RFC3964_IPv4" ]: ++ "RFC3964_IPv4", "AllowZoneDrifting" ]: + if property_name == "MinimalMark": + try: + int(new_value) +@@ -677,6 +686,11 @@ class FirewallDConfig(slip.dbus.service.Object): + raise FirewallError(errors.INVALID_VALUE, + "'%s' for %s" % \ + (new_value, property_name)) ++ if property_name == "AllowZoneDrifting": ++ if new_value.lower() not in ["yes", "true", "no", "false"]: ++ raise FirewallError(errors.INVALID_VALUE, ++ "'%s' for %s" % \ ++ (new_value, property_name)) + + self.config.get_firewalld_conf().set(property_name, new_value) + self.config.get_firewalld_conf().write() +diff --git a/src/tests/dbus/firewalld.conf.at b/src/tests/dbus/firewalld.conf.at +index 45559311eabb..65ac702f4713 100644 +--- a/src/tests/dbus/firewalld.conf.at ++++ b/src/tests/dbus/firewalld.conf.at +@@ -3,6 +3,7 @@ AT_KEYWORDS(dbus) + + dnl Verify defaults over dbus. Should be inline with default firewalld.conf. + DBUS_GETALL([config], [config], 0, [dnl ++string "AllowZoneDrifting" : variant string "no" + string "AutomaticHelpers" : variant string "system" + string "CleanupOnExit" : variant string "no" + string "DefaultZone" : variant string "public" +@@ -36,6 +37,7 @@ _helper([FirewallBackend], [string:"iptables"], [variant string "iptables"]) + _helper([FlushAllOnReload], [string:"no"], [variant string "no"]) + _helper([CleanupOnExit], [string:"yes"], [variant string "yes"]) + _helper([RFC3964_IPv4], [string:"no"], [variant string "no"]) ++_helper([AllowZoneDrifting], [string:"yes"], [variant string "yes"]) + dnl Note: DefaultZone is RO + m4_undefine([_helper]) + +-- +2.23.0 + diff --git a/SOURCES/0031-feat-nftables-support-AllowZoneDrifting-yes.patch b/SOURCES/0031-feat-nftables-support-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..84a953b --- /dev/null +++ b/SOURCES/0031-feat-nftables-support-AllowZoneDrifting-yes.patch @@ -0,0 +1,124 @@ +From 3c2ca67f86de7cd490ae25333e330b4aea0447f1 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 14:37:31 -0500 +Subject: [PATCH 31/35] feat: nftables: support AllowZoneDrifting=yes + +(cherry picked from commit 517a061c5886f2ebfb4aa7d73804aa7f3c5a3004) +(cherry picked from commit d15fb2911a89477f26a800d498fa47d7c2e5ec5f) +--- + src/firewall/core/nftables.py | 44 +++++++++++++++++++++++------------ + 1 file changed, 29 insertions(+), 15 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index 33a170a76a98..79799388a923 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -204,8 +204,11 @@ class nftables(object): + + index = zone_source_index_cache[family].index(zone_source) + else: +- index = len(zone_source_index_cache[family]) +- ++ if self._fw._allow_zone_drifting: ++ index = 0 ++ else: ++ index = len(zone_source_index_cache[family]) ++ + if index == 0: + rule[0] = "insert" + else: +@@ -488,8 +491,9 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["raw"][chain][1])) + + for chain in ["PREROUTING"]: +- default_rules.append("add chain inet %s raw_%s_ZONES" % (TABLE_NAME, chain)) +- default_rules.append("add rule inet %s raw_%s jump raw_%s_ZONES" % (TABLE_NAME, chain, chain)) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s raw_%s_%s" % (TABLE_NAME, chain, dispatch_suffix)) ++ default_rules.append("add rule inet %s raw_%s jump raw_%s_%s" % (TABLE_NAME, chain, chain, dispatch_suffix)) + + for chain in IPTABLES_TO_NFT_HOOK["mangle"].keys(): + default_rules.append("add chain inet %s mangle_%s '{ type filter hook %s priority %d ; }'" % +@@ -497,8 +501,9 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["mangle"][chain][0], + IPTABLES_TO_NFT_HOOK["mangle"][chain][1])) + +- default_rules.append("add chain inet %s mangle_%s_ZONES" % (TABLE_NAME, chain)) +- default_rules.append("add rule inet %s mangle_%s jump mangle_%s_ZONES" % (TABLE_NAME, chain, chain)) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s mangle_%s_%s" % (TABLE_NAME, chain, dispatch_suffix)) ++ default_rules.append("add rule inet %s mangle_%s jump mangle_%s_%s" % (TABLE_NAME, chain, chain, dispatch_suffix)) + + for family in ["ip", "ip6"]: + for chain in IPTABLES_TO_NFT_HOOK["nat"].keys(): +@@ -507,8 +512,9 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["nat"][chain][0], + IPTABLES_TO_NFT_HOOK["nat"][chain][1])) + +- default_rules.append("add chain %s %s nat_%s_ZONES" % (family, TABLE_NAME, chain)) +- default_rules.append("add rule %s %s nat_%s jump nat_%s_ZONES" % (family, TABLE_NAME, chain, chain)) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain %s %s nat_%s_%s" % (family, TABLE_NAME, chain, dispatch_suffix)) ++ default_rules.append("add rule %s %s nat_%s jump nat_%s_%s" % (family, TABLE_NAME, chain, chain, dispatch_suffix)) + + for chain in IPTABLES_TO_NFT_HOOK["filter"].keys(): + default_rules.append("add chain inet %s filter_%s '{ type filter hook %s priority %d ; }'" % +@@ -517,11 +523,12 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["filter"][chain][1])) + + # filter, INPUT +- default_rules.append("add chain inet %s filter_%s_ZONES" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct status dnat accept" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "INPUT")) +- default_rules.append("add rule inet %s filter_%s jump filter_%s_ZONES" % (TABLE_NAME, "INPUT", "INPUT")) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s filter_%s_%s" % (TABLE_NAME, "INPUT", dispatch_suffix)) ++ default_rules.append("add rule inet %s filter_%s jump filter_%s_%s" % (TABLE_NAME, "INPUT", "INPUT", dispatch_suffix)) + if log_denied != "off": + default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "INPUT")) +@@ -530,13 +537,15 @@ class nftables(object): + default_rules.append("add rule inet %s filter_%s reject with icmpx type admin-prohibited" % (TABLE_NAME, "INPUT")) + + # filter, FORWARD +- default_rules.append("add chain inet %s filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD")) +- default_rules.append("add chain inet %s filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct status dnat accept" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "FORWARD")) +- default_rules.append("add rule inet %s filter_%s jump filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD")) +- default_rules.append("add rule inet %s filter_%s jump filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD")) ++ for direction in ["IN", "OUT"]: ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", direction, dispatch_suffix)) ++ default_rules.append("add chain inet %s filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", direction, dispatch_suffix)) ++ default_rules.append("add rule inet %s filter_%s jump filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", "FORWARD", direction, dispatch_suffix)) ++ default_rules.append("add rule inet %s filter_%s jump filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", "FORWARD", direction, dispatch_suffix)) + if log_denied != "off": + default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "FORWARD")) +@@ -634,6 +643,11 @@ class nftables(object): + "OUTPUT": "daddr", + }[chain] + ++ if self._fw._allow_zone_drifting: ++ zone_dispatch_chain = "%s_%s_ZONES_SOURCE" % (table, chain) ++ else: ++ zone_dispatch_chain = "%s_%s_ZONES" % (table, chain) ++ + target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone) + action = "goto" + +@@ -653,7 +667,7 @@ class nftables(object): + rule_family = "ip6" + + rule = [add_del, "rule", family, "%s" % TABLE_NAME, +- "%s_%s_ZONES" % (table, chain), ++ zone_dispatch_chain, + "%%ZONE_SOURCE%%", zone, + rule_family, opt, address, action, "%s_%s" % (table, target)] + return [rule] +-- +2.23.0 + diff --git a/SOURCES/0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch b/SOURCES/0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..083ef4e --- /dev/null +++ b/SOURCES/0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch @@ -0,0 +1,178 @@ +From 8342a2b3fdea4f78e5c8f842550e87857ccaa277 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 16:16:59 -0500 +Subject: [PATCH 32/35] feat: ipXtables: support AllowZoneDrifting=yes + +(cherry picked from commit 1f7b5ffcd40daf2a7f2ef1ec0cccb95080e74fb6) +(cherry picked from commit 0435bc024cf9ecf5aad7d3c37f7ef55396de73a4) +--- + src/firewall/core/ipXtables.py | 93 +++++++++++++++++++--------------- + 1 file changed, 51 insertions(+), 42 deletions(-) + +diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py +index 2f4ec46d8339..c9c1acc44a4c 100644 +--- a/src/firewall/core/ipXtables.py ++++ b/src/firewall/core/ipXtables.py +@@ -323,8 +323,11 @@ class ip4tables(object): + + index = zone_source_index_cache.index(zone_source) + else: +- index = len(zone_source_index_cache) +- ++ if self._fw._allow_zone_drifting: ++ index = 0 ++ else: ++ index = len(zone_source_index_cache) ++ + rule[0] = "-I" + rule.insert(2, "%d" % (index + 1)) + +@@ -667,9 +670,10 @@ class ip4tables(object): + self.our_chains["raw"].add("%s_direct" % chain) + + if chain == "PREROUTING": +- default_rules["raw"].append("-N %s_ZONES" % chain) +- default_rules["raw"].append("-A %s -j %s_ZONES" % (chain, chain)) +- self.our_chains["raw"].update(set(["%s_ZONES" % chain])) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["raw"].append("-N %s_%s" % (chain, dispatch_suffix)) ++ default_rules["raw"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix)) ++ self.our_chains["raw"].update(set(["%s_%s" % (chain, dispatch_suffix)])) + + if self.get_available_tables("mangle"): + default_rules["mangle"] = [ ] +@@ -680,9 +684,10 @@ class ip4tables(object): + self.our_chains["mangle"].add("%s_direct" % chain) + + if chain == "PREROUTING": +- default_rules["mangle"].append("-N %s_ZONES" % chain) +- default_rules["mangle"].append("-A %s -j %s_ZONES" % (chain, chain)) +- self.our_chains["mangle"].update(set(["%s_ZONES" % chain])) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["mangle"].append("-N %s_%s" % (chain, dispatch_suffix)) ++ default_rules["mangle"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix)) ++ self.our_chains["mangle"].update(set(["%s_%s" % (chain, dispatch_suffix)])) + + if self.get_available_tables("nat"): + default_rules["nat"] = [ ] +@@ -693,19 +698,22 @@ class ip4tables(object): + self.our_chains["nat"].add("%s_direct" % chain) + + if chain in [ "PREROUTING", "POSTROUTING" ]: +- default_rules["nat"].append("-N %s_ZONES" % chain) +- default_rules["nat"].append("-A %s -j %s_ZONES" % (chain, chain)) +- self.our_chains["nat"].update(set(["%s_ZONES" % chain])) +- +- default_rules["filter"] = [ +- "-N INPUT_direct", +- "-N INPUT_ZONES", +- +- "-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT", +- "-A INPUT -i lo -j ACCEPT", +- "-A INPUT -j INPUT_direct", +- "-A INPUT -j INPUT_ZONES", +- ] ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["nat"].append("-N %s_%s" % (chain, dispatch_suffix)) ++ default_rules["nat"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix)) ++ self.our_chains["nat"].update(set(["%s_%s" % (chain, dispatch_suffix)])) ++ ++ default_rules["filter"] = [] ++ self.our_chains["filter"] = set() ++ default_rules["filter"].append("-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT") ++ default_rules["filter"].append("-A INPUT -i lo -j ACCEPT") ++ default_rules["filter"].append("-N INPUT_direct") ++ default_rules["filter"].append("-A INPUT -j INPUT_direct") ++ self.our_chains["filter"].update(set("INPUT_direct")) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["filter"].append("-N INPUT_%s" % (dispatch_suffix)) ++ default_rules["filter"].append("-A INPUT -j INPUT_%s" % (dispatch_suffix)) ++ self.our_chains["filter"].update(set("INPUT_%s" % (dispatch_suffix))) + if log_denied != "off": + default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '") + default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID -j DROP") +@@ -713,17 +721,16 @@ class ip4tables(object): + default_rules["filter"].append("-A INPUT %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: '") + default_rules["filter"].append("-A INPUT -j %%REJECT%%") + +- default_rules["filter"] += [ +- "-N FORWARD_direct", +- "-N FORWARD_IN_ZONES", +- "-N FORWARD_OUT_ZONES", +- +- "-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT", +- "-A FORWARD -i lo -j ACCEPT", +- "-A FORWARD -j FORWARD_direct", +- "-A FORWARD -j FORWARD_IN_ZONES", +- "-A FORWARD -j FORWARD_OUT_ZONES", +- ] ++ default_rules["filter"].append("-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT") ++ default_rules["filter"].append("-A FORWARD -i lo -j ACCEPT") ++ default_rules["filter"].append("-N FORWARD_direct") ++ default_rules["filter"].append("-A FORWARD -j FORWARD_direct") ++ self.our_chains["filter"].update(set("FORWARD_direct")) ++ for direction in ["IN", "OUT"]: ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["filter"].append("-N FORWARD_%s_%s" % (direction, dispatch_suffix)) ++ default_rules["filter"].append("-A FORWARD -j FORWARD_%s_%s" % (direction, dispatch_suffix)) ++ self.our_chains["filter"].update(set("FORWARD_%s_%s" % (direction, dispatch_suffix))) + if log_denied != "off": + default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '") + default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID -j DROP") +@@ -737,10 +744,7 @@ class ip4tables(object): + "-A OUTPUT -o lo -j ACCEPT", + "-A OUTPUT -j OUTPUT_direct", + ] +- +- self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES", +- "FORWARD_direct", "FORWARD_IN_ZONES", +- "FORWARD_OUT_ZONES", "OUTPUT_direct"]) ++ self.our_chains["filter"].update(set("OUTPUT_direct")) + + final_default_rules = [] + for table in default_rules: +@@ -806,6 +810,11 @@ class ip4tables(object): + "OUTPUT": "-d", + }[chain] + ++ if self._fw._allow_zone_drifting: ++ zone_dispatch_chain = "%s_ZONES_SOURCE" % (chain) ++ else: ++ zone_dispatch_chain = "%s_ZONES" % (chain) ++ + target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone) + action = "-g" + +@@ -816,8 +825,8 @@ class ip4tables(object): + else: + opt = "src" + flags = ",".join([opt] * self._fw.ipset.get_dimension(name)) +- rule = [ add_del, +- "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ rule = [ add_del, zone_dispatch_chain, ++ "%%ZONE_SOURCE%%", zone, + "-t", table, + "-m", "set", "--match-set", name, + flags, action, target ] +@@ -826,14 +835,14 @@ class ip4tables(object): + # outgoing can not be set + if opt == "-d": + return "" +- rule = [ add_del, +- "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ rule = [ add_del, zone_dispatch_chain, ++ "%%ZONE_SOURCE%%", zone, + "-t", table, + "-m", "mac", "--mac-source", address.upper(), + action, target ] + else: +- rule = [ add_del, +- "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ rule = [ add_del, zone_dispatch_chain, ++ "%%ZONE_SOURCE%%", zone, + "-t", table, + opt, address, action, target ] + return [rule] +-- +2.23.0 + diff --git a/SOURCES/0033-test-verify-AllowZoneDrifting-yes.patch b/SOURCES/0033-test-verify-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..8f860ad --- /dev/null +++ b/SOURCES/0033-test-verify-AllowZoneDrifting-yes.patch @@ -0,0 +1,939 @@ +From d5fb90bf13f46432292eeeb1fe48727f52333348 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 16:49:14 -0500 +Subject: [PATCH 33/35] test: verify AllowZoneDrifting=yes + +Verify the zone dispatch layout. + +(cherry picked from commit bca4e6af91fc4c6a55f7c2bce9e4fe7bcee526a1) +(cherry picked from commit f60b13d837d2726175d1dae213777dde8025e7ec) +--- + src/tests/regression/gh258.at | 536 +++++++++++++++++++++++++--- + src/tests/regression/rhbz1734765.at | 180 +++++++++- + 2 files changed, 671 insertions(+), 45 deletions(-) + +diff --git a/src/tests/regression/gh258.at b/src/tests/regression/gh258.at +index 1896a9bfc61c..01b717483d77 100644 +--- a/src/tests/regression/gh258.at ++++ b/src/tests/regression/gh258.at +@@ -1,12 +1,15 @@ + FWD_START_TEST([zone dispatch layout]) +-AT_KEYWORDS(zone gh258 gh441 rhbz1713823) ++AT_KEYWORDS(zone gh258 gh441 rhbz1713823 rhbz1772208 rhbz1796055) + +-FWD_CHECK([--zone=work --add-source="1.2.3.0/24"], 0, ignore) ++FWD_CHECK([--permanent --zone=trusted --add-source="1.2.3.0/24"], 0, ignore) + IF_IPV6_SUPPORTED([ +-FWD_CHECK([--zone=public --add-source="dead:beef::/54"], 0, ignore) ++FWD_CHECK([--permanent --zone=public --add-source="dead:beef::/54"], 0, ignore) + ]) +-FWD_CHECK([--zone=work --add-interface=dummy0], 0, ignore) +-FWD_CHECK([--zone=public --add-interface=dummy1], 0, ignore) ++FWD_CHECK([--permanent --zone=trusted --add-interface=dummy0], 0, ignore) ++FWD_CHECK([--permanent --zone=public --add-interface=dummy1], 0, ignore) ++ ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD + + dnl verify layout of zone dispatch + NFT_LIST_RULES([inet], [filter_INPUT], 0, [dnl +@@ -25,9 +28,9 @@ NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl + table inet firewalld { + chain filter_INPUT_ZONES { + ip6 saddr dead:beef::/54 goto filter_IN_public +- ip saddr 1.2.3.0/24 goto filter_IN_work ++ ip saddr 1.2.3.0/24 goto filter_IN_trusted ++ iifname "dummy0" goto filter_IN_trusted + iifname "dummy1" goto filter_IN_public +- iifname "dummy0" goto filter_IN_work + goto filter_IN_public + } + } +@@ -50,9 +53,9 @@ NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES], 0, [dnl + table inet firewalld { + chain filter_FORWARD_IN_ZONES { + ip6 saddr dead:beef::/54 goto filter_FWDI_public +- ip saddr 1.2.3.0/24 goto filter_FWDI_work ++ ip saddr 1.2.3.0/24 goto filter_FWDI_trusted ++ iifname "dummy0" goto filter_FWDI_trusted + iifname "dummy1" goto filter_FWDI_public +- iifname "dummy0" goto filter_FWDI_work + goto filter_FWDI_public + } + } +@@ -61,9 +64,9 @@ NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES], 0, [dnl + table inet firewalld { + chain filter_FORWARD_OUT_ZONES { + ip6 daddr dead:beef::/54 goto filter_FWDO_public +- ip daddr 1.2.3.0/24 goto filter_FWDO_work ++ ip daddr 1.2.3.0/24 goto filter_FWDO_trusted ++ oifname "dummy0" goto filter_FWDO_trusted + oifname "dummy1" goto filter_FWDO_public +- oifname "dummy0" goto filter_FWDO_work + goto filter_FWDO_public + } + } +@@ -83,9 +86,9 @@ NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES], 0, [dnl + table inet firewalld { + chain raw_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto raw_PRE_public +- ip saddr 1.2.3.0/24 goto raw_PRE_work ++ ip saddr 1.2.3.0/24 goto raw_PRE_trusted ++ iifname "dummy0" goto raw_PRE_trusted + iifname "dummy1" goto raw_PRE_public +- iifname "dummy0" goto raw_PRE_work + goto raw_PRE_public + } + } +@@ -101,9 +104,9 @@ NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES], 0, [dnl + table inet firewalld { + chain mangle_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto mangle_PRE_public +- ip saddr 1.2.3.0/24 goto mangle_PRE_work ++ ip saddr 1.2.3.0/24 goto mangle_PRE_trusted ++ iifname "dummy0" goto mangle_PRE_trusted + iifname "dummy1" goto mangle_PRE_public +- iifname "dummy0" goto mangle_PRE_work + goto mangle_PRE_public + } + } +@@ -118,9 +121,9 @@ NFT_LIST_RULES([ip], [nat_PREROUTING], 0, [dnl + NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES], 0, [dnl + table ip firewalld { + chain nat_PREROUTING_ZONES { +- ip saddr 1.2.3.0/24 goto nat_PRE_work ++ ip saddr 1.2.3.0/24 goto nat_PRE_trusted ++ iifname "dummy0" goto nat_PRE_trusted + iifname "dummy1" goto nat_PRE_public +- iifname "dummy0" goto nat_PRE_work + goto nat_PRE_public + } + } +@@ -135,9 +138,9 @@ NFT_LIST_RULES([ip], [nat_POSTROUTING], 0, [dnl + NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl + table ip firewalld { + chain nat_POSTROUTING_ZONES { +- ip daddr 1.2.3.0/24 goto nat_POST_work ++ ip daddr 1.2.3.0/24 goto nat_POST_trusted ++ oifname "dummy0" goto nat_POST_trusted + oifname "dummy1" goto nat_POST_public +- oifname "dummy0" goto nat_POST_work + goto nat_POST_public + } + } +@@ -153,8 +156,8 @@ NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES], 0, [dnl + table ip6 firewalld { + chain nat_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto nat_PRE_public ++ iifname "dummy0" goto nat_PRE_trusted + iifname "dummy1" goto nat_PRE_public +- iifname "dummy0" goto nat_PRE_work + goto nat_PRE_public + } + } +@@ -170,8 +173,8 @@ NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl + table ip6 firewalld { + chain nat_POSTROUTING_ZONES { + ip6 daddr dead:beef::/54 goto nat_POST_public ++ oifname "dummy0" goto nat_POST_trusted + oifname "dummy1" goto nat_POST_public +- oifname "dummy0" goto nat_POST_work + goto nat_POST_public + } + } +@@ -186,9 +189,9 @@ IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl + REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited + ]) + IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, +- [[IN_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[IN_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ IN_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- IN_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl +@@ -201,15 +204,15 @@ IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited + ]) + IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, +- [[FWDI_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[FWDI_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ FWDI_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- FWDI_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, +- [[FWDO_work all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ [[FWDO_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ FWDO_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- FWDO_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl +@@ -217,9 +220,9 @@ IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, +- [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl +@@ -227,9 +230,9 @@ IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, +- [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl +@@ -237,9 +240,9 @@ IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, +- [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl +@@ -247,9 +250,9 @@ IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl + POSTROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, +- [[POST_work all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ [[POST_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ POST_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- POST_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + +@@ -263,8 +266,8 @@ IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl + ]) + IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, + [[IN_public all dead:beef::/54 ::/0 [goto] ++ IN_trusted all ::/0 ::/0 [goto] + IN_public all ::/0 ::/0 [goto] +- IN_work all ::/0 ::/0 [goto] + IN_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl +@@ -279,14 +282,14 @@ IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + ]) + IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, + [[FWDI_public all dead:beef::/54 ::/0 [goto] ++ FWDI_trusted all ::/0 ::/0 [goto] + FWDI_public all ::/0 ::/0 [goto] +- FWDI_work all ::/0 ::/0 [goto] + FWDI_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, + [[FWDO_public all ::/0 dead:beef::/54 [goto] ++ FWDO_trusted all ::/0 ::/0 [goto] + FWDO_public all ::/0 ::/0 [goto] +- FWDO_work all ::/0 ::/0 [goto] + FWDO_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl +@@ -298,8 +301,8 @@ IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, + [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_trusted all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] +- PRE_work all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl +@@ -308,8 +311,8 @@ IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, + [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_trusted all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] +- PRE_work all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl +@@ -318,8 +321,8 @@ IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, + [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_trusted all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] +- PRE_work all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl +@@ -328,9 +331,456 @@ IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, + [[POST_public all ::/0 dead:beef::/54 [goto] ++ POST_trusted all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++]]) ++ ++dnl ########################################################################## ++dnl ########################################################################## ++dnl We also support zone drifting in which source based zones fall through to ++dnl interface based zones (including default zone). ++dnl ########################################################################## ++dnl ########################################################################## ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=yes/' ./firewalld.conf]) ++FWD_RELOAD ++ ++NFT_LIST_RULES([inet], [filter_INPUT], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT { ++ ct state established,related accept ++ ct status dnat accept ++ iifname "lo" accept ++ jump filter_INPUT_ZONES_SOURCE ++ jump filter_INPUT_ZONES ++ ct state invalid drop ++ reject with icmpx type admin-prohibited ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto filter_IN_public ++ ip saddr 1.2.3.0/24 goto filter_IN_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES { ++ iifname "dummy0" goto filter_IN_trusted ++ iifname "dummy1" goto filter_IN_public ++ goto filter_IN_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD { ++ ct state established,related accept ++ ct status dnat accept ++ iifname "lo" accept ++ ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 type addr-unreachable ++ jump filter_FORWARD_IN_ZONES_SOURCE ++ jump filter_FORWARD_IN_ZONES ++ jump filter_FORWARD_OUT_ZONES_SOURCE ++ jump filter_FORWARD_OUT_ZONES ++ ct state invalid drop ++ reject with icmpx type admin-prohibited ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_IN_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto filter_FWDI_public ++ ip saddr 1.2.3.0/24 goto filter_FWDI_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_IN_ZONES { ++ iifname "dummy0" goto filter_FWDI_trusted ++ iifname "dummy1" goto filter_FWDI_public ++ goto filter_FWDI_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_OUT_ZONES_SOURCE { ++ ip6 daddr dead:beef::/54 goto filter_FWDO_public ++ ip daddr 1.2.3.0/24 goto filter_FWDO_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_OUT_ZONES { ++ oifname "dummy0" goto filter_FWDO_trusted ++ oifname "dummy1" goto filter_FWDO_public ++ goto filter_FWDO_public ++ } ++ } ++]) ++m4_if(yes, HOST_SUPPORTS_NFT_FIB, [dnl ++ NFT_LIST_RULES([inet], [raw_PREROUTING], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING { ++ icmpv6 type { nd-router-advert, nd-neighbor-solicit } accept ++ meta nfproto ipv6 fib saddr . iif oif missing drop ++ jump raw_PREROUTING_ZONES_SOURCE ++ jump raw_PREROUTING_ZONES ++ } ++ } ++ ]) ++], [ ++ NFT_LIST_RULES([inet], [raw_PREROUTING], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING { ++ jump raw_PREROUTING_ZONES_SOURCE ++ jump raw_PREROUTING_ZONES ++ } ++ } ++ ]) ++]) ++NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto raw_PRE_public ++ ip saddr 1.2.3.0/24 goto raw_PRE_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING_ZONES { ++ iifname "dummy0" goto raw_PRE_trusted ++ iifname "dummy1" goto raw_PRE_public ++ goto raw_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [mangle_PREROUTING], 0, [dnl ++ table inet firewalld { ++ chain mangle_PREROUTING { ++ jump mangle_PREROUTING_ZONES_SOURCE ++ jump mangle_PREROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain mangle_PREROUTING_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto mangle_PRE_public ++ ip saddr 1.2.3.0/24 goto mangle_PRE_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES], 0, [dnl ++ table inet firewalld { ++ chain mangle_PREROUTING_ZONES { ++ iifname "dummy0" goto mangle_PRE_trusted ++ iifname "dummy1" goto mangle_PRE_public ++ goto mangle_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_PREROUTING], 0, [dnl ++ table ip firewalld { ++ chain nat_PREROUTING { ++ jump nat_PREROUTING_ZONES_SOURCE ++ jump nat_PREROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table ip firewalld { ++ chain nat_PREROUTING_ZONES_SOURCE { ++ ip saddr 1.2.3.0/24 goto nat_PRE_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES], 0, [dnl ++ table ip firewalld { ++ chain nat_PREROUTING_ZONES { ++ iifname "dummy0" goto nat_PRE_trusted ++ iifname "dummy1" goto nat_PRE_public ++ goto nat_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING { ++ jump nat_POSTROUTING_ZONES_SOURCE ++ jump nat_POSTROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip daddr 1.2.3.0/24 goto nat_POST_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "dummy0" goto nat_POST_trusted ++ oifname "dummy1" goto nat_POST_public ++ goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_PREROUTING], 0, [dnl ++ table ip6 firewalld { ++ chain nat_PREROUTING { ++ jump nat_PREROUTING_ZONES_SOURCE ++ jump nat_PREROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table ip6 firewalld { ++ chain nat_PREROUTING_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto nat_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES], 0, [dnl ++ table ip6 firewalld { ++ chain nat_PREROUTING_ZONES { ++ iifname "dummy0" goto nat_PRE_trusted ++ iifname "dummy1" goto nat_PRE_public ++ goto nat_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING { ++ jump nat_POSTROUTING_ZONES_SOURCE ++ jump nat_POSTROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip6 daddr dead:beef::/54 goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "dummy0" goto nat_POST_trusted ++ oifname "dummy1" goto nat_POST_public ++ goto nat_POST_public ++ } ++ } ++]) ++ ++IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID ++ REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ++]) ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_IN_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_IN_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_OUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_OUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID ++ REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ++]) ++IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_SOURCE], 0, ++ [[FWDI_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, ++ [[FWDI_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_SOURCE], 0, ++ [[FWDO_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, ++ [[FWDO_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl ++ PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl ++ PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl ++ PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl ++ POSTROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ POSTROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ POSTROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++ ++IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl ++ ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all ::/0 ::/0 ++ INPUT_direct all ::/0 ::/0 ++ INPUT_ZONES_SOURCE all ::/0 ::/0 ++ INPUT_ZONES all ::/0 ::/0 ++ DROP all ::/0 ::/0 ctstate INVALID ++ REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited ++]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_trusted all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl ++ ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all ::/0 ::/0 ++ FORWARD_direct all ::/0 ::/0 ++ RFC3964_IPv4 all ::/0 ::/0 ++ FORWARD_IN_ZONES_SOURCE all ::/0 ::/0 ++ FORWARD_IN_ZONES all ::/0 ::/0 ++ FORWARD_OUT_ZONES_SOURCE all ::/0 ::/0 ++ FORWARD_OUT_ZONES all ::/0 ::/0 ++ DROP all ::/0 ::/0 ctstate INVALID ++ REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited ++]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_SOURCE], 0, ++ [[FWDI_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, ++ [[FWDI_trusted all ::/0 ::/0 [goto] ++ FWDI_public all ::/0 ::/0 [goto] ++ FWDI_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_SOURCE], 0, ++ [[FWDO_public all ::/0 dead:beef::/54 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, ++ [[FWDO_trusted all ::/0 ::/0 [goto] ++ FWDO_public all ::/0 ::/0 [goto] ++ FWDO_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl ++ ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 134 ++ ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 135 ++ DROP all ::/0 ::/0 rpfilter invert ++ PREROUTING_direct all ::/0 ::/0 ++ PREROUTING_ZONES_SOURCE all ::/0 ::/0 ++ PREROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl ++ PREROUTING_direct all ::/0 ::/0 ++ PREROUTING_ZONES_SOURCE all ::/0 ::/0 ++ PREROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl ++ PREROUTING_direct all ::/0 ::/0 ++ PREROUTING_ZONES_SOURCE all ::/0 ::/0 ++ PREROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl ++ POSTROUTING_direct all ::/0 ::/0 ++ POSTROUTING_ZONES_SOURCE all ::/0 ::/0 ++ POSTROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_public all ::/0 dead:beef::/54 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_trusted all ::/0 ::/0 [goto] + POST_public all ::/0 ::/0 [goto] +- POST_work all ::/0 ::/0 [goto] + POST_public all ::/0 ::/0 [goto] + ]]) + +-FWD_END_TEST ++FWD_END_TEST([-e '/WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now./d']) +diff --git a/src/tests/regression/rhbz1734765.at b/src/tests/regression/rhbz1734765.at +index 168be70a2900..3751e60204e4 100644 +--- a/src/tests/regression/rhbz1734765.at ++++ b/src/tests/regression/rhbz1734765.at +@@ -1,9 +1,12 @@ + FWD_START_TEST([zone sources ordered by name]) +-AT_KEYWORDS(zone rhbz1734765 rhbz1421222 gh166 rhbz1738545) ++AT_KEYWORDS(zone rhbz1734765 rhbz1421222 gh166 rhbz1738545 rhbz1772208 rhbz1796055) + dnl + dnl Users depend on firewalld ordering source-based zone dispatch by zone name. + dnl + ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD ++ + FWD_CHECK([-q --permanent --new-zone=foobar_00]) + FWD_CHECK([-q --permanent --new-zone=foobar_05]) + FWD_CHECK([-q --permanent --new-zone=foobar_02]) +@@ -196,4 +199,177 @@ IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, + POST_public all ::/0 ::/0 [goto] + ]]) + +-FWD_END_TEST ++dnl ########################################################################## ++dnl ########################################################################## ++dnl We also support zone drifting in which source based zones fall through to ++dnl interface based zones (including default zone). So make sure the zones are ++dnl sorted by name in this mode. ++dnl ########################################################################## ++dnl ########################################################################## ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=yes/' ./firewalld.conf]) ++FWD_RELOAD ++ ++FWD_CHECK([-q --zone=foobar_010 --add-source="10.10.10.10"]) ++FWD_CHECK([-q --zone=public --add-source="20.20.20.20"]) ++IF_IPV6_SUPPORTED([ ++FWD_CHECK([-q --zone=foobar_010 --add-source="1234:5678::10:10:10"]) ++FWD_CHECK([-q --zone=public --add-source="1234:5678::20:20:20"]) ++FWD_CHECK([-q --zone=foobar_012 --add-source ipset:ipsetv6]) ++]) ++FWD_CHECK([-q --zone=foobar_010 --add-interface=foobar2]) ++ ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES_SOURCE { ++ ip saddr 10.1.1.1 goto filter_IN_foobar_00 ++ ip6 saddr 1234:5678::1:1:1 goto filter_IN_foobar_00 ++ ip saddr 10.1.1.0/24 goto filter_IN_foobar_01 ++ ip6 saddr 1234:5678::1:1:0/112 goto filter_IN_foobar_01 ++ ip saddr 10.10.10.10 goto filter_IN_foobar_010 ++ ip6 saddr 1234:5678::10:10:10 goto filter_IN_foobar_010 ++ ip saddr @ipsetv4 goto filter_IN_foobar_011 ++ ip6 saddr @ipsetv6 goto filter_IN_foobar_012 ++ ip saddr 10.1.0.0/16 goto filter_IN_foobar_02 ++ ip6 saddr 1234:5678::1:0:0/96 goto filter_IN_foobar_02 ++ ip saddr 10.2.2.0/24 goto filter_IN_foobar_03 ++ ip6 saddr 1234:5678::2:2:0/112 goto filter_IN_foobar_03 ++ ip saddr 10.2.0.0/16 goto filter_IN_foobar_04 ++ ip6 saddr 1234:5678::2:0:0/96 goto filter_IN_foobar_04 ++ ip saddr 10.0.0.0/8 goto filter_IN_foobar_05 ++ ip6 saddr 1234:5678::/80 goto filter_IN_foobar_05 ++ ip saddr 20.20.20.20 goto filter_IN_public ++ ip6 saddr 1234:5678::20:20:20 goto filter_IN_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES { ++ iifname "foobar2" goto filter_IN_foobar_010 ++ iifname "foobar1" goto filter_IN_trusted ++ iifname "foobar0" goto filter_IN_internal ++ goto filter_IN_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip daddr 10.1.1.1 goto nat_POST_foobar_00 ++ ip daddr 10.1.1.0/24 goto nat_POST_foobar_01 ++ ip daddr 10.10.10.10 goto nat_POST_foobar_010 ++ ip daddr @ipsetv4 goto nat_POST_foobar_011 ++ ip daddr 10.1.0.0/16 goto nat_POST_foobar_02 ++ ip daddr 10.2.2.0/24 goto nat_POST_foobar_03 ++ ip daddr 10.2.0.0/16 goto nat_POST_foobar_04 ++ ip daddr 10.0.0.0/8 goto nat_POST_foobar_05 ++ ip daddr 20.20.20.20 goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "foobar2" goto nat_POST_foobar_010 ++ oifname "foobar1" goto nat_POST_trusted ++ oifname "foobar0" goto nat_POST_internal ++ goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip6 daddr 1234:5678::1:1:1 goto nat_POST_foobar_00 ++ ip6 daddr 1234:5678::1:1:0/112 goto nat_POST_foobar_01 ++ ip6 daddr 1234:5678::10:10:10 goto nat_POST_foobar_010 ++ ip6 daddr @ipsetv6 goto nat_POST_foobar_012 ++ ip6 daddr 1234:5678::1:0:0/96 goto nat_POST_foobar_02 ++ ip6 daddr 1234:5678::2:2:0/112 goto nat_POST_foobar_03 ++ ip6 daddr 1234:5678::2:0:0/96 goto nat_POST_foobar_04 ++ ip6 daddr 1234:5678::/80 goto nat_POST_foobar_05 ++ ip6 daddr 1234:5678::20:20:20 goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "foobar2" goto nat_POST_foobar_010 ++ oifname "foobar1" goto nat_POST_trusted ++ oifname "foobar0" goto nat_POST_internal ++ goto nat_POST_public ++ } ++ } ++]) ++ ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_foobar_00 all -- 10.1.1.1 0.0.0.0/0 [goto] ++ IN_foobar_01 all -- 10.1.1.0/24 0.0.0.0/0 [goto] ++ IN_foobar_010 all -- 10.10.10.10 0.0.0.0/0 [goto] ++ IN_foobar_011 all -- 0.0.0.0/0 0.0.0.0/0 [goto] match-set ipsetv4 src ++ IN_foobar_02 all -- 10.1.0.0/16 0.0.0.0/0 [goto] ++ IN_foobar_03 all -- 10.2.2.0/24 0.0.0.0/0 [goto] ++ IN_foobar_04 all -- 10.2.0.0/16 0.0.0.0/0 [goto] ++ IN_foobar_05 all -- 10.0.0.0/8 0.0.0.0/0 [goto] ++ IN_public all -- 20.20.20.20 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_foobar_010 all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_internal all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_foobar_00 all 1234:5678::1:1:1 ::/0 [goto] ++ IN_foobar_01 all 1234:5678::1:1:0/112 ::/0 [goto] ++ IN_foobar_010 all 1234:5678::10:10:10 ::/0 [goto] ++ IN_foobar_012 all ::/0 ::/0 [goto] match-set ipsetv6 src ++ IN_foobar_02 all 1234:5678::1:0:0/96 ::/0 [goto] ++ IN_foobar_03 all 1234:5678::2:2:0/112 ::/0 [goto] ++ IN_foobar_04 all 1234:5678::2:0:0/96 ::/0 [goto] ++ IN_foobar_05 all 1234:5678::/80 ::/0 [goto] ++ IN_public all 1234:5678::20:20:20 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_foobar_010 all ::/0 ::/0 [goto] ++ IN_trusted all ::/0 ::/0 [goto] ++ IN_internal all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_foobar_00 all -- 0.0.0.0/0 10.1.1.1 [goto] ++ POST_foobar_01 all -- 0.0.0.0/0 10.1.1.0/24 [goto] ++ POST_foobar_010 all -- 0.0.0.0/0 10.10.10.10 [goto] ++ POST_foobar_011 all -- 0.0.0.0/0 0.0.0.0/0 [goto] match-set ipsetv4 dst ++ POST_foobar_02 all -- 0.0.0.0/0 10.1.0.0/16 [goto] ++ POST_foobar_03 all -- 0.0.0.0/0 10.2.2.0/24 [goto] ++ POST_foobar_04 all -- 0.0.0.0/0 10.2.0.0/16 [goto] ++ POST_foobar_05 all -- 0.0.0.0/0 10.0.0.0/8 [goto] ++ POST_public all -- 0.0.0.0/0 20.20.20.20 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_foobar_010 all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_internal all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_foobar_00 all ::/0 1234:5678::1:1:1 [goto] ++ POST_foobar_01 all ::/0 1234:5678::1:1:0/112 [goto] ++ POST_foobar_010 all ::/0 1234:5678::10:10:10 [goto] ++ POST_foobar_012 all ::/0 ::/0 [goto] match-set ipsetv6 dst ++ POST_foobar_02 all ::/0 1234:5678::1:0:0/96 [goto] ++ POST_foobar_03 all ::/0 1234:5678::2:2:0/112 [goto] ++ POST_foobar_04 all ::/0 1234:5678::2:0:0/96 [goto] ++ POST_foobar_05 all ::/0 1234:5678::/80 [goto] ++ POST_public all ::/0 1234:5678::20:20:20 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_foobar_010 all ::/0 ::/0 [goto] ++ POST_trusted all ::/0 ::/0 [goto] ++ POST_internal all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++]]) ++ ++FWD_END_TEST([-e '/WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now./d']) +-- +2.23.0 + diff --git a/SOURCES/0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch b/SOURCES/0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch new file mode 100644 index 0000000..28f6915 --- /dev/null +++ b/SOURCES/0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch @@ -0,0 +1,39 @@ +From 8b332eae015f215f9db3f2cd2961ebfcec9e2b1a Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 4 Feb 2020 13:12:31 -0500 +Subject: [PATCH 34/35] fix: firewall-offline-cmd: Don't print warning about + AllowZoneDrifting + +If we're called from firewall-offline-cmd, don't log the warning. It's +overly verbose to warn on every invocation. + +Fixes: afadd377b09d ("feat: AllowZoneDrifting config option") +(cherry picked from commit eefcb1a712ffca5e08dcefa6aa17c935c16b835f) +(cherry picked from commit b6d3bd4c4359523b483eb630f9265cc4cbe408f2) +--- + src/firewall/core/fw.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py +index 07bc9f375771..969052bd92bd 100644 +--- a/src/firewall/core/fw.py ++++ b/src/firewall/core/fw.py +@@ -331,10 +331,11 @@ class Firewall(object): + self._allow_zone_drifting = False + else: + self._allow_zone_drifting = True +- log.warning("AllowZoneDrifting is enabled. This is considered " +- "an insecure configuration option. It will be " +- "removed in a future release. Please consider " +- "disabling it now.") ++ if not self._offline: ++ log.warning("AllowZoneDrifting is enabled. This is considered " ++ "an insecure configuration option. It will be " ++ "removed in a future release. Please consider " ++ "disabling it now.") + log.debug1("AllowZoneDrifting is set to '%s'", + self._allow_zone_drifting) + +-- +2.23.0 + diff --git a/SOURCES/0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch b/SOURCES/0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..98ac334 --- /dev/null +++ b/SOURCES/0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch @@ -0,0 +1,138 @@ +From e9a5699dcb4e50dacbf1350b39a95dc9aef6cefa Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 4 Feb 2020 09:12:17 -0500 +Subject: [PATCH 35/35] RHEL only: default to AllowZoneDrifting=yes + +--- + config/firewalld.conf | 4 ++-- + doc/xml/firewalld.conf.xml | 2 +- + doc/xml/firewalld.dbus.xml | 2 +- + src/firewall/config/__init__.py.in | 2 +- + src/tests/dbus/firewalld.conf.at | 2 +- + src/tests/features/rfc3964_ipv4.at | 4 ++++ + src/tests/firewall-cmd.at | 4 ++++ + src/tests/functions.at | 1 + + src/tests/regression/rhbz1514043.at | 4 ++++ + 9 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/config/firewalld.conf b/config/firewalld.conf +index ebf8021226b7..6d0feb88f7c3 100644 +--- a/config/firewalld.conf ++++ b/config/firewalld.conf +@@ -81,5 +81,5 @@ RFC3964_IPv4=yes + # Note: If "yes" packets will only drift from source based zones to interface + # based zones (including the default zone). Packets never drift from interface + # based zones to other interfaces based zones (including the default zone). +-# Possible values; "yes", "no". Defaults to "no". +-AllowZoneDrifting=no ++# Possible values; "yes", "no". Defaults to "yes". ++AllowZoneDrifting=yes +diff --git a/doc/xml/firewalld.conf.xml b/doc/xml/firewalld.conf.xml +index 8108066e88bf..9574c567867f 100644 +--- a/doc/xml/firewalld.conf.xml ++++ b/doc/xml/firewalld.conf.xml +@@ -197,7 +197,7 @@ + to interface based zones (including the default zone). Packets + never drift from interface based zones to other interfaces + based zones (including the default zone). +- Valid values; "yes", "no". Defaults to "no". ++ Valid values; "yes", "no". Defaults to "yes". + + + +diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml +index f72bad526d65..408787594035 100644 +--- a/doc/xml/firewalld.dbus.xml ++++ b/doc/xml/firewalld.dbus.xml +@@ -2590,7 +2590,7 @@ + to interface based zones (including the default zone). Packets + never drift from interface based zones to other interfaces + based zones (including the default zone). +- Valid values; "yes", "no". Defaults to "no". ++ Valid values; "yes", "no". Defaults to "yes". + + + +diff --git a/src/firewall/config/__init__.py.in b/src/firewall/config/__init__.py.in +index c009d93e4164..fbef1828c8aa 100644 +--- a/src/firewall/config/__init__.py.in ++++ b/src/firewall/config/__init__.py.in +@@ -132,4 +132,4 @@ FALLBACK_AUTOMATIC_HELPERS = "system" + FALLBACK_FIREWALL_BACKEND = "nftables" + FALLBACK_FLUSH_ALL_ON_RELOAD = True + FALLBACK_RFC3964_IPV4 = True +-FALLBACK_ALLOW_ZONE_DRIFTING = False ++FALLBACK_ALLOW_ZONE_DRIFTING = True +diff --git a/src/tests/dbus/firewalld.conf.at b/src/tests/dbus/firewalld.conf.at +index 65ac702f4713..de3780e5b5e4 100644 +--- a/src/tests/dbus/firewalld.conf.at ++++ b/src/tests/dbus/firewalld.conf.at +@@ -3,7 +3,7 @@ AT_KEYWORDS(dbus) + + dnl Verify defaults over dbus. Should be inline with default firewalld.conf. + DBUS_GETALL([config], [config], 0, [dnl +-string "AllowZoneDrifting" : variant string "no" ++string "AllowZoneDrifting" : variant string "yes" + string "AutomaticHelpers" : variant string "system" + string "CleanupOnExit" : variant string "no" + string "DefaultZone" : variant string "public" +diff --git a/src/tests/features/rfc3964_ipv4.at b/src/tests/features/rfc3964_ipv4.at +index 54f5f756270b..15fef52612cc 100644 +--- a/src/tests/features/rfc3964_ipv4.at ++++ b/src/tests/features/rfc3964_ipv4.at +@@ -1,6 +1,10 @@ + FWD_START_TEST([RFC3964_IPv4]) + AT_KEYWORDS(rfc3964_ipv4) + ++dnl Expected test results assume this is set to "no" ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD ++ + AT_CHECK([sed -i 's/^LogDenied.*/LogDenied=all/' ./firewalld.conf]) + AT_CHECK([sed -i 's/^RFC3964_IPv4.*/RFC3964_IPv4=yes/' ./firewalld.conf]) + FWD_RELOAD +diff --git a/src/tests/firewall-cmd.at b/src/tests/firewall-cmd.at +index 53f2eb2c7c88..ad6ed9540c7f 100644 +--- a/src/tests/firewall-cmd.at ++++ b/src/tests/firewall-cmd.at +@@ -970,6 +970,10 @@ FWD_START_TEST([rich rules priority]) + + CHECK_LOG_AUDIT + ++ dnl Expected test results assume this is set to "no" ++ AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++ FWD_RELOAD ++ + dnl Verify generic layout of zone + NFT_LIST_RULES([inet], [filter_IN_public], 0, [dnl + table inet firewalld { +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 3771bb8bd5a7..ef7c696ddf73 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -149,6 +149,7 @@ m4_define([FWD_END_TEST], [ + IF_IPV6_SUPPORTED([], [ + sed -i "/WARNING: ip6tables not usable, disabling IPv6 firewall/d" ./firewalld.log + ]) ++ sed -i "/WARNING: AllowZoneDrifting is enabled./d" ./firewalld.log + if test x"$1" != x"ignore"; then + if test -n "$1"; then + sed -i $1 ./firewalld.log +diff --git a/src/tests/regression/rhbz1514043.at b/src/tests/regression/rhbz1514043.at +index 241cf547f7f3..8e4846a078b8 100644 +--- a/src/tests/regression/rhbz1514043.at ++++ b/src/tests/regression/rhbz1514043.at +@@ -1,6 +1,10 @@ + FWD_START_TEST([--set-log-denied does not zero config]) + AT_KEYWORDS(log_denied rhbz1514043) + ++dnl Expected test results assume this is set to "no" ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD ++ + FWD_CHECK([-q --set-log-denied=all]) + FWD_CHECK([-q --permanent --zone=public --add-service=samba]) + FWD_RELOAD +-- +2.23.0 + diff --git a/SOURCES/RHEL-only-0001-Add-cockpit-by-default-to-some-zones.patch b/SOURCES/RHEL-only-0001-Add-cockpit-by-default-to-some-zones.patch new file mode 100644 index 0000000..9995b07 --- /dev/null +++ b/SOURCES/RHEL-only-0001-Add-cockpit-by-default-to-some-zones.patch @@ -0,0 +1,242 @@ +From 0f28f2b7b8072bdc2e483d035230ddcb8b00a919 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 9 Jul 2018 11:29:33 -0400 +Subject: [PATCH] Add cockpit by default to some zones + +Fixes: #1581578 +--- + config/zones/home.xml | 1 + + config/zones/internal.xml | 1 + + config/zones/public.xml | 1 + + config/zones/work.xml | 1 + + src/tests/features/service_include.at | 2 +- + src/tests/firewall-cmd.at | 14 +++++++++++++- + src/tests/regression/gh366.at | 3 +++ + src/tests/regression/gh453.at | 2 ++ + src/tests/regression/rhbz1514043.at | 2 +- + 9 files changed, 24 insertions(+), 3 deletions(-) + +diff --git a/config/zones/home.xml b/config/zones/home.xml +index 42b29b2f2d50..8aa8afa0e8aa 100644 +--- a/config/zones/home.xml ++++ b/config/zones/home.xml +@@ -6,4 +6,5 @@ + + + ++ + +diff --git a/config/zones/internal.xml b/config/zones/internal.xml +index e646b48c94e8..40cb7e14424b 100644 +--- a/config/zones/internal.xml ++++ b/config/zones/internal.xml +@@ -6,4 +6,5 @@ + + + ++ + +diff --git a/config/zones/public.xml b/config/zones/public.xml +index 49795d8c9068..617e131a4895 100644 +--- a/config/zones/public.xml ++++ b/config/zones/public.xml +@@ -4,4 +4,5 @@ + For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted. + + ++ + +diff --git a/config/zones/work.xml b/config/zones/work.xml +index 6ea5550a40bd..9609ee6f65c2 100644 +--- a/config/zones/work.xml ++++ b/config/zones/work.xml +@@ -4,4 +4,5 @@ + For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted. + + ++ + +diff --git a/src/tests/features/service_include.at b/src/tests/features/service_include.at +index b3a50a84bd88..992c5ef0ba92 100644 +--- a/src/tests/features/service_include.at ++++ b/src/tests/features/service_include.at +@@ -90,7 +90,7 @@ FWD_CHECK([--zone=drop --list-services], 0, [dnl + + ]) + FWD_CHECK([--zone=public --list-services], 0, [dnl +-dhcpv6-client ssh ++cockpit dhcpv6-client ssh + ]) + FWD_CHECK([-q --permanent --service=my-service-with-include --remove-include=does-not-exist]) + FWD_RELOAD +diff --git a/src/tests/firewall-cmd.at b/src/tests/firewall-cmd.at +index efc8f9c50757..6444b4566af5 100644 +--- a/src/tests/firewall-cmd.at ++++ b/src/tests/firewall-cmd.at +@@ -1046,6 +1046,7 @@ FWD_START_TEST([rich rules priority]) + chain filter_IN_public_allow { + tcp dport 22 ct state new,untracked accept + ip6 daddr fe80::/64 udp dport 546 ct state new,untracked accept ++ tcp dport 9090 ct state new,untracked accept + tcp dport 1122 ct state new,untracked accept + tcp dport 3333 ct state new,untracked accept + tcp dport 4444 ct state new,untracked accept +@@ -1061,6 +1062,7 @@ FWD_START_TEST([rich rules priority]) + ]) + IPTABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED ++ ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1122 ctstate NEW,UNTRACKED + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3333 ctstate NEW,UNTRACKED + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:4444 ctstate NEW,UNTRACKED +@@ -1075,6 +1077,7 @@ FWD_START_TEST([rich rules priority]) + IP6TABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp ::/0 ::/0 tcp dpt:22 ctstate NEW,UNTRACKED + ACCEPT udp ::/0 fe80::/64 udp dpt:546 ctstate NEW,UNTRACKED ++ ACCEPT tcp ::/0 ::/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ACCEPT tcp ::/0 ::/0 tcp dpt:1122 ctstate NEW,UNTRACKED + ACCEPT tcp ::/0 ::/0 tcp dpt:3333 ctstate NEW,UNTRACKED + ACCEPT tcp ::/0 ::/0 tcp dpt:4444 ctstate NEW,UNTRACKED +@@ -1156,6 +1159,7 @@ FWD_START_TEST([rich rules priority]) + chain filter_IN_public_allow { + tcp dport 22 ct state new,untracked accept + ip6 daddr fe80::/64 udp dport 546 ct state new,untracked accept ++ tcp dport 9090 ct state new,untracked accept + } + } + ]) +@@ -1259,6 +1263,7 @@ FWD_START_TEST([rich rules priority]) + ]) + IPTABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED ++ ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ]) + IPTABLES_LIST_RULES([filter], [FWDI_public_pre], 0, [dnl + ]) +@@ -1293,6 +1298,7 @@ FWD_START_TEST([rich rules priority]) + IP6TABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp ::/0 ::/0 tcp dpt:22 ctstate NEW,UNTRACKED + ACCEPT udp ::/0 fe80::/64 udp dpt:546 ctstate NEW,UNTRACKED ++ ACCEPT tcp ::/0 ::/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ]) + IP6TABLES_LIST_RULES([filter], [FWDI_public_pre], 0, [dnl + ]) +@@ -1340,6 +1346,7 @@ FWD_START_TEST([rich rules priority]) + chain filter_IN_public_allow { + tcp dport 22 ct state new,untracked accept + ip6 daddr fe80::/64 udp dport 546 ct state new,untracked accept ++ tcp dport 9090 ct state new,untracked accept + icmp type echo-request accept + icmpv6 type echo-request accept + } +@@ -1380,6 +1387,7 @@ FWD_START_TEST([rich rules priority]) + ]) + IPTABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED ++ ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 8 + ]) + IPTABLES_LIST_RULES([filter], [FWDI_public_pre], 0, [dnl +@@ -1402,6 +1410,7 @@ FWD_START_TEST([rich rules priority]) + IP6TABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp ::/0 ::/0 tcp dpt:22 ctstate NEW,UNTRACKED + ACCEPT udp ::/0 fe80::/64 udp dpt:546 ctstate NEW,UNTRACKED ++ ACCEPT tcp ::/0 ::/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 128 + ]) + IP6TABLES_LIST_RULES([filter], [FWDI_public_pre], 0, [dnl +@@ -1458,6 +1467,7 @@ FWD_START_TEST([rich rules priority]) + chain filter_IN_public_allow { + tcp dport 22 ct state new,untracked accept + ip6 daddr fe80::/64 udp dport 546 ct state new,untracked accept ++ tcp dport 9090 ct state new,untracked accept + } + } + ]) +@@ -1495,6 +1505,7 @@ FWD_START_TEST([rich rules priority]) + ]) + IPTABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED ++ ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ]) + IPTABLES_LIST_RULES([filter], [IN_public_deny], 0, [dnl + ]) +@@ -1515,6 +1526,7 @@ FWD_START_TEST([rich rules priority]) + IP6TABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp ::/0 ::/0 tcp dpt:22 ctstate NEW,UNTRACKED + ACCEPT udp ::/0 fe80::/64 udp dpt:546 ctstate NEW,UNTRACKED ++ ACCEPT tcp ::/0 ::/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ]) + IP6TABLES_LIST_RULES([filter], [IN_public_deny], 0, [dnl + ]) +@@ -1540,7 +1552,7 @@ FWD_START_TEST([rich rules priority]) + icmp-block-inversion: no + interfaces: + sources: +- services: dhcpv6-client ssh ++ services: cockpit dhcpv6-client ssh + ports: + protocols: + masquerade: no +diff --git a/src/tests/regression/gh366.at b/src/tests/regression/gh366.at +index 1441a6be53bf..51ff504e6a9d 100644 +--- a/src/tests/regression/gh366.at ++++ b/src/tests/regression/gh366.at +@@ -7,6 +7,7 @@ table inet firewalld { + chain filter_IN_public_allow { + tcp dport 22 ct state new,untracked accept + ip6 daddr fe80::/64 udp dport 546 ct state new,untracked accept ++tcp dport 9090 ct state new,untracked accept + ip daddr 224.0.0.251 udp dport 5353 ct state new,untracked accept + ip6 daddr ff02::fb udp dport 5353 ct state new,untracked accept + } +@@ -14,11 +15,13 @@ ip6 daddr ff02::fb udp dport 5353 ct state new,untracked accept + ]) + IPTABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED ++ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ACCEPT udp -- 0.0.0.0/0 224.0.0.251 udp dpt:5353 ctstate NEW,UNTRACKED + ]) + IP6TABLES_LIST_RULES([filter], [IN_public_allow], 0, [dnl + ACCEPT tcp ::/0 ::/0 tcp dpt:22 ctstate NEW,UNTRACKED + ACCEPT udp ::/0 fe80::/64 udp dpt:546 ctstate NEW,UNTRACKED ++ACCEPT tcp ::/0 ::/0 tcp dpt:9090 ctstate NEW,UNTRACKED + ACCEPT udp ::/0 ff02::fb udp dpt:5353 ctstate NEW,UNTRACKED + ])]) + +diff --git a/src/tests/regression/gh453.at b/src/tests/regression/gh453.at +index f57a79dcf9a2..6d820fce840a 100644 +--- a/src/tests/regression/gh453.at ++++ b/src/tests/regression/gh453.at +@@ -18,6 +18,7 @@ NFT_LIST_RULES([inet], [filter_IN_public_allow], 0, [dnl + chain filter_IN_public_allow { + tcp dport 22 ct state new,untracked accept + ip6 daddr fe80::/64 udp dport 546 ct state new,untracked accept ++ tcp dport 9090 ct state new,untracked accept + tcp dport 21 ct helper set "helper-ftp-tcp" + tcp dport 21 ct state new,untracked accept + } +@@ -42,6 +43,7 @@ NFT_LIST_RULES([inet], [filter_IN_public_allow], 0, [dnl + chain filter_IN_public_allow { + tcp dport 22 ct state new,untracked accept + ip6 daddr fe80::/64 udp dport 546 ct state new,untracked accept ++ tcp dport 9090 ct state new,untracked accept + tcp dport 21 ct helper set "helper-ftp-tcp" + tcp dport 21 ct state new,untracked accept + tcp dport 5060 ct helper set "helper-sip-tcp" +diff --git a/src/tests/regression/rhbz1514043.at b/src/tests/regression/rhbz1514043.at +index deb93a5fac94..88ce4934e5ea 100644 +--- a/src/tests/regression/rhbz1514043.at ++++ b/src/tests/regression/rhbz1514043.at +@@ -5,7 +5,7 @@ FWD_CHECK([-q --set-log-denied=all]) + FWD_CHECK([-q --permanent --zone=public --add-service=samba]) + FWD_RELOAD + FWD_CHECK([--zone=public --list-all | TRIM | grep ^services], 0, [dnl +-services: dhcpv6-client samba ssh ++services: cockpit dhcpv6-client samba ssh + ]) + dnl check that log denied actually took effect + m4_if(iptables, FIREWALL_BACKEND, [ +-- +2.20.1 + diff --git a/SPECS/firewalld.spec b/SPECS/firewalld.spec new file mode 100644 index 0000000..dcba27d --- /dev/null +++ b/SPECS/firewalld.spec @@ -0,0 +1,1622 @@ +Summary: A firewall daemon with D-Bus interface providing a dynamic firewall +Name: firewalld +Version: 0.7.0 +Release: 5%{?dist}.1 +URL: http://www.firewalld.org +License: GPLv2+ +Source0: https://github.com/firewalld/firewalld/releases/download/v%{version}/firewalld-%{version}.tar.gz +Patch1: RHEL-only-0001-Add-cockpit-by-default-to-some-zones.patch +Patch2: 0001-fix-src-test-Makefile-use-wildcard-in-variable-expan.patch +Patch3: 0002-fix-CLI-show-service-includes-with-info-service.patch +Patch4: 0003-fix-tests-always-list-rules-using-macros.patch +Patch5: 0004-test-new-macro-PIPESTATUS0.patch +Patch6: 0005-test-use-PIPESTATUS0-in-LIST-macros.patch +Patch7: 0006-fix-test-features-rfc3964_ipv4-use-return-code-not-o.patch +Patch8: 0007-test-new-macro-CHECK_MODULE_PROTO_GRE.patch +Patch9: 0008-fix-test-regression-pr323-skip-if-GRE-module-doesn-t.patch +Patch10: 0009-test-service-coverage-for-import-from-file.patch +Patch11: 0010-fix-dbus-fix-service-API-break.patch +Patch12: 0011-fix-dbus-add-missing-APIs-for-service-includes.patch +Patch13: 0012-fix-tests-functions-use-gdbus-instead-of-dbus-send.patch +Patch14: 0013-test-functions-add-CHOMP-macro-for-shell-output.patch +Patch15: 0014-test-functions-add-macro-DBUS_INTROSPECT.patch +Patch16: 0015-test-dbus-service-API-coverage.patch +Patch17: 0016-fix-dbus-new-dict-based-APIs-for-services.patch +Patch18: 0017-test-dbus-coverage-for-new-service-APIs.patch +Patch19: 0018-fix-client-service-use-dict-based-dbus-APIs.patch +Patch20: 0019-fix-firewall-offline-cmd-service-use-dict-based-APIs.patch +Patch21: 0020-fix-direct-removeRules-was-mistakenly-removing-all-r.patch +Patch22: 0021-test-coverage-for-rhbz-1723610-and-gh-385.patch +Patch23: 0022-fix-tests-regression-rhbz1723610-make-output-reliabl.patch +Patch24: 0023-fix-tests-regression-rhbz1723610-avoid-calling-IPv6-.patch +Patch25: 0024-fix-guarantee-zone-source-dispatch-is-sorted-by-zone.patch +Patch26: 0025-test-verify-source-based-zone-dispatch-ordered-by-zo.patch +Patch27: 0026-fix-test-regression-rhbz1734765-guard-IPv6-usage.patch +Patch28: 0027-fix-nftables-fix-zone-dispatch-using-ipset-sources-i.patch +Patch29: 0028-test-regression-rhbz1734765-add-coverage-for-rhbz-17.patch +Patch30: 0030-feat-AllowZoneDrifting-config-option.patch +Patch31: 0031-feat-nftables-support-AllowZoneDrifting-yes.patch +Patch32: 0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch +Patch33: 0033-test-verify-AllowZoneDrifting-yes.patch +Patch34: 0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch +Patch35: 0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch + +BuildArch: noarch +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: desktop-file-utils +BuildRequires: gettext +BuildRequires: intltool +# glib2-devel is needed for gsettings.m4 +BuildRequires: glib2, glib2-devel +BuildRequires: systemd-units +BuildRequires: docbook-style-xsl +BuildRequires: libxslt +BuildRequires: iptables, ebtables, ipset +BuildRequires: python3-devel +BuildRequires: nftables >= 0.9.0-13 +Requires: iptables, ebtables, ipset +Requires: nftables >= 0.9.0-13 +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires: firewalld-filesystem = %{version}-%{release} +Requires: python3-firewall = %{version}-%{release} +Conflicts: selinux-policy < 3.14.1-28 +Conflicts: squid < 7:3.5.10-1 +Obsoletes: firewalld-selinux < 0.4.4.2-2 +# bz1581578 +Conflicts: cockpit-ws < 171-2 + +%description +firewalld is a firewall service daemon that provides a dynamic customizable +firewall with a D-Bus interface. + +%package -n python3-firewall +Summary: Python3 bindings for firewalld + +%{?python_provide:%python_provide python3-firewall} + +Obsoletes: python-firewall < 0.5.2-2 +Obsoletes: python2-firewall < 0.5.2-2 +Requires: python3-dbus +Requires: python3-slip-dbus +Requires: python3-decorator +Requires: python3-gobject-base + +%description -n python3-firewall +Python3 bindings for firewalld. + +%package -n firewalld-filesystem +Summary: Firewalld directory layout and rpm macros + +%description -n firewalld-filesystem +This package provides directories and rpm macros which +are required by other packages that add firewalld configuration files. + +%package -n firewall-applet +Summary: Firewall panel applet +Requires: %{name} = %{version}-%{release} +Requires: firewall-config = %{version}-%{release} +Requires: hicolor-icon-theme +Requires: python3-qt5-base +Requires: python3-gobject +Requires: libnotify +Requires: NetworkManager-libnm +Requires: dbus-x11 + +%description -n firewall-applet +The firewall panel applet provides a status information of firewalld and also +the firewall settings. + +%package -n firewall-config +Summary: Firewall configuration application +Requires: %{name} = %{version}-%{release} +Requires: hicolor-icon-theme +Requires: gtk3 +Requires: python3-gobject +Requires: NetworkManager-libnm +Requires: dbus-x11 + +%description -n firewall-config +The firewall configuration application provides an configuration interface for +firewalld. + +%prep +%autosetup -p1 +# must autogen since a patch above touched a Makefile.am +./autogen.sh + +%build +%configure --enable-sysconfig --enable-rpmmacros PYTHON="%{__python3} %{py3_shbang_opts}" +make %{?_smp_mflags} + +%install +make install DESTDIR=%{buildroot} +desktop-file-install --delete-original \ + --dir %{buildroot}%{_sysconfdir}/xdg/autostart \ + %{buildroot}%{_sysconfdir}/xdg/autostart/firewall-applet.desktop +desktop-file-install --delete-original \ + --dir %{buildroot}%{_datadir}/applications \ + %{buildroot}%{_datadir}/applications/firewall-config.desktop + +%find_lang %{name} --all-name + +%post +%systemd_post firewalld.service + +%preun +%systemd_preun firewalld.service + +%postun +%systemd_postun_with_restart firewalld.service + +%files -f %{name}.lang +%doc COPYING README +%{_sbindir}/firewalld +%{_bindir}/firewall-cmd +%{_bindir}/firewall-offline-cmd +%dir %{_datadir}/bash-completion/completions +%{_datadir}/bash-completion/completions/firewall-cmd +%dir %{_datadir}/zsh/site-functions +%{_datadir}/zsh/site-functions/_firewalld +%{_prefix}/lib/firewalld/icmptypes/*.xml +%{_prefix}/lib/firewalld/ipsets/README +%{_prefix}/lib/firewalld/services/*.xml +%{_prefix}/lib/firewalld/zones/*.xml +%{_prefix}/lib/firewalld/helpers/*.xml +%attr(0750,root,root) %dir %{_sysconfdir}/firewalld +%config(noreplace) %{_sysconfdir}/firewalld/firewalld.conf +%config(noreplace) %{_sysconfdir}/firewalld/lockdown-whitelist.xml +%attr(0750,root,root) %dir %{_sysconfdir}/firewalld/helpers +%attr(0750,root,root) %dir %{_sysconfdir}/firewalld/icmptypes +%attr(0750,root,root) %dir %{_sysconfdir}/firewalld/ipsets +%attr(0750,root,root) %dir %{_sysconfdir}/firewalld/services +%attr(0750,root,root) %dir %{_sysconfdir}/firewalld/zones +%defattr(0644,root,root) +%config(noreplace) %{_sysconfdir}/sysconfig/firewalld +%{_unitdir}/firewalld.service +%config(noreplace) %{_datadir}/dbus-1/system.d/FirewallD.conf +%{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.desktop.policy.choice +%{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.server.policy.choice +%{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.policy +%{_mandir}/man1/firewall*cmd*.1* +%{_mandir}/man1/firewalld*.1* +%{_mandir}/man5/firewall*.5* +%{_sysconfdir}/modprobe.d/firewalld-sysctls.conf + +%files -n python3-firewall +%attr(0755,root,root) %dir %{python3_sitelib}/firewall +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/__pycache__ +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/config +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/config/__pycache__ +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/core +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/core/__pycache__ +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/core/io +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/core/io/__pycache__ +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/server +%attr(0755,root,root) %dir %{python3_sitelib}/firewall/server/__pycache__ +%{python3_sitelib}/firewall/__pycache__/*.py* +%{python3_sitelib}/firewall/*.py* +%{python3_sitelib}/firewall/config/*.py* +%{python3_sitelib}/firewall/config/__pycache__/*.py* +%{python3_sitelib}/firewall/core/*.py* +%{python3_sitelib}/firewall/core/__pycache__/*.py* +%{python3_sitelib}/firewall/core/io/*.py* +%{python3_sitelib}/firewall/core/io/__pycache__/*.py* +%{python3_sitelib}/firewall/server/*.py* +%{python3_sitelib}/firewall/server/__pycache__/*.py* + +%files -n firewalld-filesystem +%dir %{_prefix}/lib/firewalld +%dir %{_prefix}/lib/firewalld/helpers +%dir %{_prefix}/lib/firewalld/icmptypes +%dir %{_prefix}/lib/firewalld/ipsets +%dir %{_prefix}/lib/firewalld/services +%dir %{_prefix}/lib/firewalld/zones +%{_rpmconfigdir}/macros.d/macros.firewalld + +%files -n firewall-applet +%attr(0755,root,root) %dir %{_sysconfdir}/firewall +%{_bindir}/firewall-applet +%defattr(0644,root,root) +%{_sysconfdir}/xdg/autostart/firewall-applet.desktop +%{_sysconfdir}/firewall/applet.conf +%{_datadir}/icons/hicolor/*/apps/firewall-applet*.* +%{_mandir}/man1/firewall-applet*.1* + +%files -n firewall-config +%{_bindir}/firewall-config +%defattr(0644,root,root) +%{_datadir}/firewalld/firewall-config.glade +%{_datadir}/firewalld/gtk3_chooserbutton.py* +%{_datadir}/firewalld/gtk3_niceexpander.py* +%{_datadir}/applications/firewall-config.desktop +%{_datadir}/metainfo/firewall-config.appdata.xml +%{_datadir}/icons/hicolor/*/apps/firewall-config*.* +%{_datadir}/glib-2.0/schemas/org.fedoraproject.FirewallConfig.gschema.xml +%{_mandir}/man1/firewall-config*.1* + +%changelog +* Wed Feb 05 2020 Eric Garver - 0.7.0-5.el8_1_0.1 +- restore zone drifting as a feature + +* Tue Aug 13 2019 Eric Garver - 0.7.0-5 +- bump nftables version requirements + +* Tue Aug 06 2019 Eric Garver - 0.7.0-4 +- backport patches to sort source-based zone dispatch by zone name + +* Tue Jul 23 2019 Eric Garver - 0.7.0-3 +- backport patch to show service includes in service output +- backport patches to fix dbus API break + +* Thu Jun 13 2019 Eric Garver - 0.7.0-2 +- package rebuild + +* Wed Jun 12 2019 Eric Garver - 0.7.0-1 +- rebase to v0.7.0 + +* Sun Jan 13 2019 Eric Garver - 0.6.3-7 +- backport additional patches for RFC3964_IPv4 filter feature + +* Tue Jan 08 2019 Eric Garver - 0.6.3-6 +- backport nftables support for wildcard interfaces +- backport RFC3964_IPv4 filter feature + +* Tue Dec 18 2018 Eric Garver - 0.6.3-5 +- backport fix for lost NM interfaces in default zone during reload + +* Thu Dec 13 2018 Eric Garver - 0.6.3-4 +- backport recent stable fixes +- backport fix for lost NM interfaces during reload +- backport rich rule priorities +- backport fix for set entries not applied +- update translations + +* Tue Oct 16 2018 Eric Garver - 0.6.3-3 +- backport FlushAllOnReload feature + +* Fri Oct 12 2018 Eric Garver - 0.6.3-2 +- use py3_shbang_opts for lockdown-whitelist +- fix cockpit patch causing test failure + +* Thu Oct 11 2018 Eric Garver - 0.6.3-1 +- rebase package to v0.6.3 +- use py3_shbang_opts for interpreter invocations + +* Mon Sep 10 2018 Eric Garver - 0.6.1-5 +- python3-firewalld can get by with python3-gobject-base +- firewall-config can get by with python3-qt5-base + +* Thu Aug 16 2018 Eric Garver - 0.6.1-4 +- backports for new failed state if startup fails +- backports to use explicit RETURN on user defined ebtables chains +- backports to fix nftables AUDIT log support + +* Tue Aug 14 2018 Eric Garver - 0.6.1-3 +- drop support for ebtables broute table + +* Fri Aug 10 2018 Eric Garver - 0.6.1-2 +- add more ports to high-availability service + +* Thu Aug 09 2018 Eric Garver - 0.6.1-1 +- rebase to v0.6.1 +- fix patch adding cockpit by default, fixes testsuite + +* Mon Jul 09 2018 Eric Garver - 0.6.0-2 +- Use correct conflicts version for cockpit-ws +- Enable cockpit by default in some zones + +* Fri Jul 06 2018 Eric Garver - 0.6.0-1 +- rebase to v0.6.0 + +* Tue May 01 2018 Eric Garver - 0.6.0-0.1.alpha1 +- rebase to v0.6.0-alpha + +* Wed Mar 21 2018 Eric Garver - 0.5.2-3 +- remove fedora-isms and clean up spec file + +* Wed Mar 21 2018 Eric Garver - 0.5.2-2 +- remove python2-firewall subpackage + +* Mon Mar 19 2018 Eric Garver - 0.5.2-1 +- rebase package to v0.5.2 + +* Fri Feb 09 2018 Igor Gnatenko - 0.5.1-2 +- Escape macros in %%changelog + +* Wed Feb 07 2018 Eric Garver - 0.5.1-1 +- rebase package to v0.5.1 + +* Wed Feb 07 2018 Fedora Release Engineering - 0.4.4.5-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Fri Jan 05 2018 Igor Gnatenko - 0.4.4.5-5 +- Remove obsolete scriptlets + +* Sun Dec 17 2017 Zbigniew Jędrzejewski-Szmek - 0.4.4.5-4 +- Python 2 binary package renamed to python2-firewall + See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3 + +* Mon Jul 31 2017 Thomas Woerner - 0.4.4.5-3 +- Fix spec file for next RHEL versions + +* Wed Jul 26 2017 Fedora Release Engineering - 0.4.4.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Jun 9 2017 Thomas Woerner - 0.4.4.5-1 +- Rebase to firewalld-0.4.4.5 + http://www.firewalld.org/2017/06/firewalld-0-4-4-5-release + - Fix build from spec + - Fix –remove-service-from-zone option (RHBZ#1438127) + - Support sctp and dccp in ports, source-ports, forward-ports, helpers and + rich rules (RHBZ#1429808) + - firewall-cmd: Fix –{set,get}-{short,description} for zone (RHBZ#1445238) + - firewall.core.ipXtables: Use new wait option for restore commands if + available + - New services for oVirt: + ctdb, ovirt-imageio, ovirt-storageconsole, ovirt-vmconsole and nrpe + - Rename extension for policy choices (server and desktop) to .policy.choice + (RHBZ#1449754) + - D-Bus interfaces: Fix GetAll for interfaces without properties + (RHBZ#1452017) + - Load NAT helpers with conntrack helpers (RHBZ#1452681) + - Translation updates +- Additional upstream patches: + - Rich-rule source validation (d69b7cb) + - IPv6 ICMP type only rich-rule fix (cf50bd0) + +* Mon Mar 27 2017 Thomas Woerner - 0.4.4.4-1 +- Rebase to firewalld-0.4.4.4 + http://www.firewalld.org/2017/03/firewalld-0-4-4-4-release +- Drop references to fedorahosted.org from spec file and Makefile.am, use + archive from github +- Fix inconsistent ordering of rules in INPUT_ZONE_SOURCE (issue#166) +- Fix ipset overloading from /etc/firewalld/ipsets +- Fix permanent rich rules using icmp-type elements (RHBZ#1434594) +- firewall-config: Deactivate edit, remove, .. buttons if there are no items +- Check if ICMP types are supported by kernel before trying to use them +- firewall-config: Show invalid ipset type in the ipset configuration dialog + in a special label + +* Tue Feb 21 2017 Thomas Woerner - 0.4.4.3-2 +- Fixed ipset overloading, dropped applied check in get_ipset (issue#206) + +* Fri Feb 10 2017 Thomas Woerner - 0.4.4.3-1 +- Rebase to firewalld-0.4.4.3 + http://www.firewalld.org/2017/02/firewalld-0-4-4-3-release +- Speed up of large file loading +- Support for more ipset types +- Speed up of adding or removing entries for ipsets from files +- Support icmp-type usage in rich rules +- Support for more icmp types +- Support for h323 conntrack helper +- New services +- Code cleanup and several other bug fixes +- Translation updates + +* Fri Feb 10 2017 Fedora Release Engineering - 0.4.4.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Tue Dec 13 2016 Stratakis Charalampos - 0.4.4.2-3 +- Rebuild for Python 3.6 + +* Mon Dec 5 2016 Thomas Woerner - 0.4.4.2-2 +- Dropping firewalld-selinux package again as the required fix made it into + selinux-policy packages for F-23+, updated selinux-policy version conflicts + +* Thu Dec 1 2016 Thomas Woerner - 0.4.4.2-1 +- New firewalld-selinux sub package delivering the SELinux policy module for + firewalld (RHBZ#1396765) (RHBZ#1394625) (RHBZ#1394578) (RHBZ#1394573) + (RHBZ#1394569) +- New firewalld release 0.4.4.2: + - firewalld.spec: Added helpers and ipsets paths to firewalld-filesystem + - firewall.core.fw_nm: create NMClient lazily + - Do not use hard-coded path for modinfo, use autofoo to detect it + - firewall.core.io.ifcfg: Dropped invalid option warning with bad format + string + - firewall.core.io.ifcfg: Properly handle quoted ifcfg values + - firewall.core.fw_zone: Do not reset ZONE with ifdown + - Updated translations from zanata + - firewall-config: Extra grid at bottom to visualize firewalld settings + +* Wed Nov 9 2016 Thomas Woerner - 0.4.4.1-1 +- firewall-config: Use proper source check in sourceDialog (fixes issue#162) +- firewallctl: New support for helpers +- Translation updates + +* Fri Oct 28 2016 Thomas Woerner - 0.4.4-1 +- Fix dist-check +- src/Makefile.am: Install new helper files +- config/Makefile.am: Install helpers +- Merged translations +- Updated translations from zanata +- firewalld.spec: Adapt requires for PyQt5 +- firewall-applet: Fix fromUTF8 for python2 PyQt5 usage +- firewall-applet: Use PyQt5 +- firewall-config: New nf_conntrack_select dialog, use nf_conntrack_helpers D-Bus property +- shell-completion/bash/firewall-cmd: Updates for helpers and also some fixes +- src/tests/firewall-[offline-]cmd_test.sh: New helper tests, adapted module tests for services +- doc/xml/seealso.xml: Add firewalld.helper(5) man page +- doc/xml/seealso.xml: Add firewalld.ipset(5) man page +- Fixed typo in firewalld.ipset(5) man page +- Updated firewalld.dbus(5) man page +- New firewalld.helper(5) man page +- doc/xml/firewall-offline-cmd.xml: Updated firewall-offline-cmd man page +- doc/xml/firewall-cmd.xml: Updated firewall-cmd man page +- firewall-offline-cmd: New support for helpers +- firewall-cmd: New support for helpers +- firewall.command: New check_helper_family, check_module and print_helper_info methods +- firewall.core.fw_test: Add helpers also to offline backend +- firewall.server.config: New AutomaticHelpers property (rw) +- firewall.server.config: Fix an dict size changed error for firewall.conf file changes +- firewall.server.config: Make LogDenied property readwrite to be consistent +- Some renames of nf_conntrack_helper* functions and structures, helpers is a dict +- firewall.core.fw: Properly check helper setting in set_automatic_helpers +- firewall.errors: Add missing BUILTIN_HELPER error code +- No extra interface for helpers needed in runtime, dropped DBUS_INTERFACE_HELPER +- firewall.server.firewalld: Drop unused queryHelper D-Bus method +- New helpers Q.931 and RAS from nf_conntrack_h323 +- firewall.core.io.helper: Allow dots in helper names, remove underscore +- firewall.core.io.firewalld_conf: Fixed typo in FALLBACK_AUTOMATIC_HELPERS +- firewall-[offline-]cmd: Use sys.excepthook to force exception_handler usage always +- firewall.core.fw_config: new_X methods should also check builtins +- firewall.client: Set helper family to "" if None +- firewall.client: Add missing module string to FirewallClientHelperSettings.settings +- config/firewalld.conf: Add possible values description for AutomaticHelpers +- helpers/amanda.xml: Fix typo in helper module +- firewall-config: Added support for helper module setting +- firewall.client: Added support for helper module setting +- firewall.server.config_helper: Added support for helper module setting +- firewall.core.io.service, firewall.server.config_service: Only replace underscore by dash if module start with nf_conntrack_ +- firewall.core.fw_zone: Use helper module instead of a generated name from helper name +- helpers: Added kernel module +- firewall.core.io.helper: Add module to helper +- firewall-cmd: Removed duplicate --get-ipset-types from help output +- firewall.core.fw_zone: Add zone bingings for PREROUTING in the raw table +- firewall.core.ipXtables: Add PREROUTING default rules for zones in raw table +- firewall-config: New support to handle helpers, new dialogs, new helper tab, .. +- config/org.fedoraproject.FirewallConfig.gschema.xml.in: New show-helpers setting +- firewall.client: New helper management for runtime and permanent configuration +- firewall.server.firewalld: New runtime helper management, new nf_conntrack_helper property +- firewall.server.config_service: Fix module name handling (no nf_conntrack_ prefix needed) +- firewall.server.config: New permanent D-Bus helper management +- New firewall.server.config_helper to provide the permanent D-Bus interface for helpers +- firewall.core.fw_zone: Use helpers fw.nf_conntrack_helper for services using helpers +- firewall.core.fw: New helper management, new _automatic_helpers and nf_conntrack_helper settings +- firewall.core.fw_config: Add support for permanent helper handling +- firewall.core.io.service: The module does not need to start with nf_conntrack_ anymore +- firewall.functions: New functions to get and set nf_conntrack_helper kernel setting +- firewall.core.io.firewalld_conf: New support for AutomaticHelpers setting +- firewall.config.dbus: New D-Bus definitions for helpers, new DBUS_INTERFACE_REVISION 12 +- New firewall.core.fw_helper providing FirewallHelper backend +- New firewall.core.helper with HELPER_MAXNAMELEN definition +- config/firewalld.conf: New AutomaticHelpers setting with description +- firewall.config.__init__.py.in: New helpers variables +- firewalld.spec: Add new helpers directory +- config/Makefile.am: Install new helpers +- New helper configuration files for amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp and tftp +- firewall.core.io.helper: New IO handler for netfilter helpers +- firewall.errors: New INVALID_HELPER error code +- firewall.core.io.ifcfg: Use .bak for save files +- firewall-config: Set internal log_denied setting after changing +- firewall.server.config: Copy props before removing items +- doc/xml/firewalld.ipset: Replaced icmptype name remains with ipset +- firewall.core.fw_zone: Fix LOG rule placement for LogDenied +- firewall.command: Use "source-ports" in print_zone_info +- firewall.core.logger: Use syslog.openlog() and syslog.closelog() +- firewall-[offline-]cmd man pages: Document --path-{zone,icmptype,ipset,service} +- firewall-cmd: Enable --path-{zone,icmptype,service} options again +- firewall.core.{ipXtables,ebtables}: Copy rule before extracting items in set_rules +- firewall.core.fw: Do not abort transaction on failed ipv6_rpfilter rules +- config/Makefile.am: Added cfengine, condor-collector and smtp-submission services +- Makefile.am: New dist-check used in the archive target +- src/Makefile.am: Reordered nobase_dist_python_DATA to be sorted +- config/Makefile.am: New CONFIG_FILES variable to contain the config files +- Merge pull request #150 from hspaans/master +- Merge pull request #146 from canvon/bugfix/spelling +- Merge pull request #145 from jcpunk/condor +- Command line tools man pages: New section about sequence options and exit codes +- Creating service file for SMTP-Submission. +- Creating service file for CFEngine. +- Fix typo in documentation: iptables mangle table +- Only use sort on lists of main items, but not for item properties +- firewall.core.io.io_object: import_config should not change ordering of lists +- firewall.core.fw_transaction: Load helper modules in FirewallZoneTransaction +- firewall.command: Fail with NOT_AUTHORIZED if authorization fails (RHBZ#1368549) +- firewall.command: Fix sequence exit code with at least one succeeded item +- Add condor collector service +- firewall-cmd: Fixed --{get,set}-{description,short} for permanent zones +- firewall.command: Do not use error code 254 for {ALREADY,NOT}_ENABLED sequences + +* Tue Aug 16 2016 Thomas Woerner - 0.4.3.3-1 +- Fix CVE-2016-5410: Firewall configuration can be modified by any logged in + user +- firewall/server/firewalld: Make getXSettings and getLogDenied CONFIG_INFO +- Update AppData configuration file. +- tests/firewalld_rich.py: Use new import structure and FirewallClient classes +- tests/firewalld_direct.py: Use new import structure +- tests: firewalld_direct: Fix assert to check for True instead of False +- tests: firewalld_config: Fix expected value when querying the zone target +- tests: firewalld_config: Use real nf_conntrack modules +- firewalld.spec: Added comment about make call for %%build +- firewall-config: Use also width_request and height_request with default size +- Updated firewall-config screenshot +- firewall-cmd: Fixed typo in help output (RHBZ#1367171) +- test-suite: Ignore stderr to get default zone also for missing firewalld.conf +- firewall.core.logger: Warnings should be printed to stderr per default +- firewall.core.fw_nm: Ignore NetworkManager if NM.Client connect fails +- firewall-cmd, firewallctl: Gracefully fail if SystemBus can not be aquired +- firewall.client: Generate new DBUS_ERROR if SystemBus can not be aquired +- test-suite: Do not fail on ALREADY_ENABLED --add-destination tests +- firewall.command: ALREADY_ENABLED, NOT_ENABLED, ZONE_ALREADY_SET are warnings +- doc/xml/firewalld.dbus.xml: Removed undefined reference +- doc/xml/transform-html.xsl.in: Fixed references in the document +- doc/xml/firewalld.{dbus,zone}.xml: Embed programlisting in para +- doc/xml/transform-html.xsl.in: Enhanced html formatting closer to the man page +- firewall: core: fw_nm: Instantiate the NM client only once +- firewall/core/io/*.py: Do not traceback on a general sax parsing issue +- firewall-offline-cmd: Fix --{add,remove}-entries-from-file +- firewall-cmd: Add missing action to fix --{add,remove}-entries-from-file +- firewall.core.prog: Do not output stderr, but return it in the error case +- firewall.core.io.ifcfg.py: Fix ifcfg file reader and writer (RHBZ#1362171) +- config/firewall.service.in: use KillMode=mixed +- config/firewalld.service.in: use network-pre.target +- firewall-config: Add missing gettext.textdomain call to fix translations +- Add UDP to transmission-client.xml service +- tests/firewall-[offline-]cmd_test.sh: Hide errors and warnings +- firewall.client: Fix ALREADY_ENABLED errors in icmptype destination calls +- firewall.client: Fix NOT_ENABLED errors in icmptype destination calls +- firewall.client: Use {ALREADY,NOT}_ENABLED errors in icmptype destination + calls +- firewall.command: Add the removed FirewallError handling to the action + (a17ce50) +- firewall.command: Do not use query methods for sequences and also single + options +- Add missing information about MAC and ipset sources to man pages and help + output +- firewalld.spec: Add BuildRequires for libxslt to enable rebuild of man pages +- firewall[-offline]-cmd, firewallctl, firewall.command: Use sys.{stdout,stderr} +- firewallctl: Fix traceback if not connected to firewalld +- firewall-config: Initialize value in on_richRuleDialogElementChooser_clicked +- firewall.command: Convert errors to string for Python3 +- firewall.command: Get proper firewall error code from D-BusExceptions +- firewall-cmd: Fixed traceback without args +- Add missing service files to Makefile.am +- shell-completion: Add shell completion support for + --{get,set}--{description,short} +- Updated RHEL-7 selinux-policy and squid conflict + +* Tue Jul 19 2016 Fedora Release Engineering - 0.4.3.2-2 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Mon Jul 4 2016 Thomas Woerner - 0.4.3.2-1 +- Fix regression with unavailable optional commands +- All missing backend messages should be warnings +- Individual calls for missing restore commands +- Only one authenticate call for add and remove options and also sequences +- New service RH-Satellite-6 +- Fixed selinux-policy conflict version for RHEL-7 + +* Wed Jun 29 2016 Thomas Woerner - 0.4.3.1-2 +- Fixed selinux-policy conflict version for Fedora 24 + +* Tue Jun 28 2016 Thomas Woerner - 0.4.3.1-1 +- New firewalld release 0.4.3.1 +- firewall.command: Fix python3 DBusException message not interable error +- src/Makefile.am: Fix path in firewall-[offline-]cmd_test.sh while installing +- firewallctl: Do not trace back on list command without further arguments +- firewallctl (man1): Added remaining sections zone, service, .. +- firewallctl: Added runtime-to-permanent, interface and source parser, + IndividualCalls setting +- firewall.server.config: Allow to set IndividualCalls property in config + interface +- Fix missing icmp rules for some zones +- runProg: Fix issue with running programs +- firewall-offline-cmd: Fix issues with missing system-config-firewall +- firewall.core.ipXtables: Split up source and dest addresses for transaction +- firewall.server.config: Log error in case of loading malformed files in + watcher +- Install and package the firewallctl man page +- New firewallctl utility (RHBZ#1147959) +- doc.xml.seealso: Show firewalld.dbus in See Also sections +- firewall.core.fw_config: Create backup on zone, service, ipset and icmptype + removal (RHBZ#1339251) +- {zone,service,ipset,icmptype}_writer: Do not fail on failed backup +- firewall-[offline-]cmd: Fix --new-X-from-file options for files in cwd +- firewall-cmd: Dropped duplicate setType call in --new-ipset +- radius service: Support also tcp ports (RBZ#1219717) +- xmlschemas: Support source-port, protocol, icmp-block-inversion and ipset + sources +- config.xmlschema.service.xsd: Fix service destination conflicts + (RHBZ#1296573) +- firewall-cmd, firewalld man: Information about new NetworkManager and ifcfg +- firewall.command: Only print summary and description in print_X_info with + verbose +- firewall.command: print_msg should be able to print empty lines +- firewall-config: No processing of runtime passthroughs signals in permanent +- Landspace.io fixes and pylint calm downs +- firewall.core.io.zone: Add zone_reader and zone_writer to __all__, pylint + fixes +- firewall-config: Fixed titles of command and context dialogs, also entry + lenths +- firewall-config: pylint calm downs +- firewall.core.fw_zone: Fix use of MAC source in rich rules without ipv limit +- firewall-config: Use self.active_zoens in conf_zone_added_cb +- firewall.command: New parse_port, extended parse methods with more checks +- firewall.command: Fixed parse_port to use the separator in the split call +- firewall.command: New [de]activate_exception_handler, raise error in parse_X +- services ha: Allow corosync-qnetd port +- firewall-applet: Support for kde5-nm-connection-editor +- tests/firewall-offline-cmd_test.sh: New tests for service and icmptype + modifications +- firewall-offline-cmd: Use FirewallCommand for simplification and sequence + options +- tests/firewall-cmd_test.sh: New tests for service and icmptype modifications +- firewall-cmd: Fixed set, remove and query destination options for services +- firewall.core.io.service: Source ports have not been checked in _check_config +- firewall.core.fw_zone: Method check_source_port is not used, removed +- firewall.core.base: Added default to ZONE_TARGETS +- firewall.client: Allow to remove ipv:address pair for service destinations +- tests/firewall-offline-cmd_test.sh: There is no timeout option in permanent +- firewall-cmd: Landscape.io fixes, pylint calm downs +- firewall-cmd: Use FirewallCommand for simplification and sequence options +- firewall.command: New FirewallCommand for command line client simplification +- New services: kshell, rsh, ganglia-master, ganglia-client +- firewalld: Cleanup of unused imports, do not translate some deamon messages +- firewalld: With fd close interation in runProg, it is not needed here anymore +- firewall.core.prog: Add fd close iteration to runProg +- firewall.core.fw_nm: Hide NM typelib import, new nm_get_dbus_interface + function +- firewalld.spec: Require NetworkManager-libnm instead of NetworkManager-glib +- firewall-config: New add/remove ipset entries from file, remove all entries +- firewall-applet: Fix tooltip after applet start with connection to firewalld +- firewall-config: Select new zone, service or icmptype if the view was empty +- firewalld.spec: Added build requires for iptables, ebtables and ipset +- Adding nf_conntrack_sip module to the service SIP +- firewall: core: fw_ifcfg: Quickly return if ifcfg directory does not exist +- Drop unneeded python shebangs +- Translation updates + +* Mon May 30 2016 Thomas Woerner - 0.4.2-1 +- New module to search for and change ifcfg files for interfaces not under + control of NM +- firewall_config: Enhanced messages in status bar +- firewall-config: New message window as overlay if not connected +- firewall-config: Fix sentivity of option, view menus and main paned if not + connected +- firewall-applet: Quit on SIGINT (Ctrl-C), reduced D-Bus calls, some cleanup +- firewall-[offline]cmd: Show target in zone information +- D-Bus: Completed masquerade methods in FirewallClientZoneSettings +- Fixed log-denied rules for icmp-blocks +- Keep sorting of interfaces, services, icmp-blocks and other settings in zones +- Fixed runtime-to-permanent not to save interfaces under control of NM +- New icmp-block-inversion flag in the zones +- ICMP type filtering in the zones +- New services: sip, sips, managesieve +- rich rules: Allow destination action (RHBZ#1163428) +- firewall-offline-cmd: New option -q/--quiet +- firewall-[offline-]cmd: New --add-[zone,service,ipset,icmptype]-from-file +- firewall-[offline-]cmd: Fix option for setting the destination address +- firewall-config: Fixed resizing behaviour +- New transaction model for speed ups in start, restart, stop and other actions +- firewall-cmd: New options --load{zone,service,ipset,icmptype}-defaults +- Fixed memory leak in dbus_introspection_add_properties +- Landscape.io fixes, pylint calm downs +- New D-Bus getXnames methods to speed up firewall-config and firewall-cmd +- ebtables-restore: No support for COMMIT command +- Source port support in services, zones and rich rules +- firewall-offline-cmd: Added --{add,remove}-entries-from-file for ipsets +- firewall-config: New active bindings side bar for simple binding changes +- Reworked NetworkManager module +- Proper default zone handling for NM connections +- Try to set zone binding with NM if interface is under control of NM +- Code cleanup and bug fixes +- Include test suite in the release and install in /usr/share/firewalld/tests +- New Travis-CI configuration file +- Fixed more broken frensh translations +- Translation updates + +* Mon May 9 2016 Thomas Woerner - 0.4.1.2-2 +- Fixed ebtables-restore does not support the COMMIT command issue + +* Wed Apr 20 2016 Thomas Woerner - 0.4.1.2-1 +- Fixed translations with python3 +- Fixed exception for failed NM import, new doc string +- Make ipsets visible per default in firewall-config +- Install new fw_nm module +- Do not fail if log file could not be opened +- Fixed broken fr translation + +* Tue Apr 19 2016 Thomas Woerner - 0.4.1-1 +- Enhancements of ipset handling + - No cleanup of ipsets using timeouts while reloading + - Only destroy conflicting ipsets + - Only use ipset types supported by the system + - Add and remove several ipset entries in one call using a file +- Reduce time frame where builtin chains are on policy DROP while reloading +- Include descriptions in --info-X calls +- Command line interface support to get and alter descriptions of zones, + services, ipsets and icmptypes with permanent option +- Properly watch changes in combined zones +- Fix logging in rich rule forward rules +- Transformed direct.passthrough errors into warnings +- Rework of import structures +- Reduced calls to get ids for port and protocol names (RHBZ#1305434) +- Build and installation fixes by Markos Chandras +- Provide D-Bus properties in introspection data +- Fix for flaws found by landscape.io +- Fix for repeated SUGHUP +- New NetworkManager module to get and set zones of connections, used in + firewall-applet and firewall-config +- configure: Autodetect backend tools ({ip,ip6,eb}tables{,-restore}, ipset) +- Code cleanups +- Bug fixes + +* Mon Feb 22 2016 Jiri Popelka - 0.4.0-4 +- Revert one commit to temporary work-around RHBZ#1309754 + +* Mon Feb 08 2016 Jiri Popelka - 0.4.0-3 +- Make sure tempdir is created even in offline mode. (RHBZ#1305175) + +* Wed Feb 03 2016 Fedora Release Engineering - 0.4.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Feb 1 2016 Thomas Woerner - 0.4.0-1 +- Version 0.4.0 + - Speed ups + - ipset support + - MAC address support + - Log of denied packets + - Mark action in rich rules + - Enhanced alteration of config files with command line tools + - Use of zone chains in direct interface + - firewall-applet enhancement + - New services: ceph-mon, ceph, docker-registry, imap, pop3, pulseaudio, + smtps, snmptrap, snmp, syslog-tls and syslog + - Several bug fixes + - Code optimizations + +* Tue Nov 10 2015 Fedora Release Engineering - 0.3.14.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Changes/python3.5 + +* Wed Jul 22 2015 Adam Williamson - 0.3.14.2-4 +- bump versions on old config package obsoletes (f21 is on 0.3.14 now) + +* Mon Jul 13 2015 Thomas Woerner - 0.3.14.2-3 +- Require python3-gobject-base for fedora >= 23 and rhel >= 8 (RHBZ#1242076) +- Fix rhel defines: No python3 for rhel-7 + +* Thu Jun 18 2015 Thomas Woerner - 0.3.14.2-2 +- Fixed 'pid_file' referenced before assignment (RHBZ#1233232) + +* Wed Jun 17 2015 Thomas Woerner - 0.3.14.2-1 +- reunification of the firewalld spec files for all Fedora releases +- fix dependencies for -applet and -config: use_python3 is the proper switch + not with_python3 (RHBZ#1232493) +- firewalld.spec: + - fixed requirements for -applet and -config +- man pages: + - adapted firewall-applet man page to new version +- firewall-applet: + - Only honour active connections for zone changes + - Change QSettings path and file names +- firewall-config: + - Only honour active connections for zone changes in the “Change Zones of Connections” menu +- Translations: + - updated translations + - marked translations for “Connections” for review + +* Wed Jun 17 2015 Fedora Release Engineering - 0.3.14.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Jun 16 2015 Stephen Gallagher 0.3.14.1-2 +- Fix issue with missing polkit policy when installing firewalld on + Cloud Edition. + +* Fri Jun 12 2015 Thomas Woerner - 0.3.14.1-1 +- firewall-applet + - do not use isSystemTrayAvailable check to fix KDE5 startup + - dropped gtk applet remain: org.fedoraproject.FirewallApplet.gschema.xml + +* Fri Jun 12 2015 Thomas Woerner - 0.3.14-1 +- renamed python2-firewall to python-firewall +- fixed requirements for GUI parts with Python3 +- dropped upstream merged python3 patch +- firewalld: + - print real zone names in error messages + - iptables 1.4.21 does not accept limits of 1/day, minimum is 2/day now + - rate limit fix for rich rules + - fix readdition of removed permanent direct settings + - adaption of the polkit domains to use PK_ACTION_DIRECT_INFO + - fixed two minor Python3 issues in firewall.core.io.direct + - fixed use of fallback configuration values + - fixed use without firewalld.conf + - firewalld main restructureization + - IPv6_rpfilter now also available as a property on D-Bus in the config interface + - fixed wait option use for ipXtables + - added --concurrent support for ebtables + - richLanguage: allow masquerading with destination + - richLanguage: limit masquerading forward rule to new connections + - ipXtables: No dns lookups in available_tables and _detect_wait_option + - full ebtables support: start, stop, reload, panic mode, direct chains and rules + - fix for reload with direct rules + - fix or flaws found by landscape.io + - pid file handling fixes in case of pid file removal + - fix for client issue in case of a dbus NoReply error +- configuration + - new services: dropbox-lansync, ptp + - new icmptypes: timestamp-request, timestamp-reply +- man pages: + - firewalld.zones(5): fixed typos + - firewalld.conf(5): Fixed wrong reference to firewalld.lockdown-whitelist page +- firewall-applet: + - new version using Qt4 fixing several issues with the Gtk version +- spec file: + - enabled Python3 support: new backends python-firewall and python3-firewall + - some cleanup +- git: + - migrated to github +- translations: + - migrated to zanata +- build environment: + - no need for autoconf-2.69, 2.68 is sufficient + +* Thu May 07 2015 Stephen Gallagher 0.3.13-7 +- Use VARIANT_ID instead of VARIANT for making decisions + +* Thu Apr 16 2015 Stephen Gallagher 0.3.13-6 +- Switch to using $VARIANT directly from /etc/os-release + +* Fri Mar 13 2015 Stephen Gallagher 0.3.13-5 +- Fix bugs with posttrans +- Remove nonexistent fedora-cloud.conf symlink + +* Fri Mar 13 2015 Stephen Gallagher 0.3.13-4 +- Remove per-edition config files +- Decide on default configuration based on /etc/os-release + +* Mon Feb 23 2015 Jiri Popelka - 0.3.13-3 +- use python3 bindings on fedora >=23 + +* Wed Jan 28 2015 Thomas Woerner - 0.3.13-2 +- enable python2 and python3 bindings for fedora >= 20 and rhel >= 7 +- use python3 bindings on fedora >= 22 and rhel >= 8 for firewalld, + firewall-config and firewall-applet + +* Thu Dec 04 2014 Jiri Popelka - 0.3.13-1 +- firewalld: + - ipXtables: use -w or -w2 if supported (RHBZ#1161745, RHBZ#1151067) + - DROP INVALID packets (RHBZ#1169837) + - don't use ipv6header for protocol matching. (RHBZ#1065565) + - removeAllPassthroughs(): remove passthroughs in reverse order (RHBZ#1167100) + - fix config.service.removeDestination() (RHBZ#1164584) +- firewall-config: + - portProtoDialog: other protocol excludes port number/range + - better fix for updating zoneStore also in update_active_zones() + - fix typo in menu +- configuration: + - new services: tinc, vdsm, mosh, iscsi-target, rsyncd + - ship and install XML Schema files. (#8) +- man pages: + - firewalld.dbus, firewalld.direct, firewalld, firewall-cmd +- spec file: + - filesystem subpackage + - make dirs&files in /usr/lib/ world-readable (RHBZ#915988) + +* Tue Oct 14 2014 Jiri Popelka - 0.3.12-1 +- firewalld: + - new runtimeToPermanent and tracked passsthrough support + - make permanent D-Bus interfaces more fine grained like the runtime versions (RHBZ#1127706) + - richLanguage: allow using destination with forward-port + - Rich_Rule.check(): action can't be used with icmp-block/forward-port/masquerade + - fixed Python specific D-Bus exception (RHBZ#1132441) +- firewall-cmd: + - new --runtime-to-permanent to create permanent from runtime configuration + - use new D-Bus methods for permanent changes + - show target REJECT instead of %%REJECT%% (RHBZ#1058794) + - --direct: make fail messages consistent (RHBZ#1141835) +- firewall-config: + - richRuleDialog - OK button tooltip indicates problem + - use new D-Bus methods for permanent changes + - show target REJECT instead of %%REJECT%% (RHBZ#1058794) + - update "Change Zones of Connections" menu on default zone change (RHBZ#11120212) + - fixed rename of zones, services and icmptypes to not create new entry (RBHZ#1131064) +- configuration: + - new service for Squid HTTP proxy server + - new service for Kerberos admin server + - new services for syslog and syslog-tls + - new services for SNMP and SNMP traps + - add Keywords to .desktop to improve software searchability +- docs: + - updated translations + - firewalld.richlanguage: improvements suggested by Rufe Glick + - firewalld.dbus: various improvements + - firewalld.zone: better description of Limit tag + - mention new homepage everywhere + +* Wed Aug 27 2014 Jiri Popelka - 0.3.11-3 +- Quiet systemctl if cups-browsed.service is not installed + +* Mon Aug 25 2014 Jiri Popelka - 0.3.11-2 +- add few Requires to spec (RHBZ#1133167) + +* Wed Aug 20 2014 Jiri Popelka - 0.3.11-1 +- firewalld: + - improve error messages + - check built-in chains in direct chain handling functions (RHBZ#1120619) + - dbus_to_python() check whether input is of expected type (RHBZ#1122018) + - handle negative timeout values (RHBZ#1124476) + - warn when Command/Uid/Use/Context already in lockdown whitelist (RHBZ#1126405) + - make --lockdown-{on,off} work again (RHBZ#1111573) +- firewall-cmd: + - --timeout now accepts time units (RHBZ#994044) +- firewall-config: + - show active (not default) zones in bold (RHBZ#993655) +- configuration: + - remove ipp-client service from all zones (RHBZ#1105639). + - fallbacks for missing values in firewalld.conf + - create missing dirs under /etc if needed + - add -Es to python command in lockdown-whitelist.xml (RHBZ#1099065) +- docs: + - 'direct' methods concern only chains/rules added via 'direct' (RHBZ#1120619) + - --remove-[interface/source] don't need a zone to be specified (RHBZ#1125851) + - various fixes in firewalld.zone(5), firewalld.dbus(5), firewalld.direct(5) +- others: + - rpm macros for easier packaging of e.g. services + +* Tue Jul 22 2014 Thomas Woerner - 0.3.10-5 +- Fixed wrong default zone names for server and workstation (RHBZ#1120296) + +* Tue Jul 8 2014 Thomas Woerner - 0.3.10-4 +- renamed fedora specific zones to FedoraServer and FedoraWorkstation for + zone name limitations (length and allowed chars) + +* Mon Jul 7 2014 Thomas Woerner - 0.3.10-3 +- New support for Fedora per-product configuration settings for Fedora.next + https://fedoraproject.org/wiki/Per-Product_Configuration_Packaging_Draft +- Added Fedora server zone (RHBZ#1110711) +- Added Fedora workstation zone(RHBZ#1113775) + +* Sat Jun 07 2014 Fedora Release Engineering - 0.3.10-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed May 28 2014 Jiri Popelka - 0.3.10-1 +- new services: freeipa-*, puppermaster, amanda-k5, synergy, + xmpp-*, tor, privoxy, sane +- do not use at_console in D-Bus policies (RHBZ#1094745) +- apply all rich rules for non-default targets +- AppData file (RHBZ#1094754) +- separate Polkit actions for desktop & server (RHBZ#1091068) +- sanitize missing ip6t_rpfilter (RHBZ#1074427) +- firewall/core/io/*: few improvements (RHBZ#1065738) +- no load failed error for absent direct.xml file +- new DBUS_INTERFACE.getZoneSettings to get all run-time zone settings +- fixed creation and deletion of zones, services and icmptypes over D-Bus signals +- FirewallClientZoneSettings: Set proper default target +- if Python2 then encode strings from sax parser (RHBZ#1059104, RHBZ#1058853) +- firewall-cmd: + - don't colour output of query commands (RHBZ#1097841) + - use "default" instead of {chain}_{zone} (RHBZ#1075675) + - New --get-target and --set-target + - Create and remove permanent zones, services and icmptypes +- firewall-config: + - Adding services and icmptypes resulted in duplicates in UI + - Use left button menu of -applet in Option menu +- firewall-offline-cmd: same functionality as 'firewall-cmd --permanent' +- firewall-applet: ZoneConnectionEditor was missing the Default Zone entry +- bash-completion: getting zones/services/icmps is different with/without --permanent +- firewalld.zone(5): removed superfluous slash (RHBZ#1091575) +- updated translations + +* Wed Feb 05 2014 Jiri Popelka - 0.3.9.3-1 +- Fixed persistent port forwarding (RHBZ#1056154) +- Stop default zone rules being applied to all zones (RHBZ#1057875) +- Enforce trust, block and drop zones in the filter table only (RHBZ#1055190) +- Allow RAs prior to applying IPv6_rpfilter (RHBZ#1058505) +- Fix writing of rule.audit in zone_writer() + +* Fri Jan 17 2014 Jiri Popelka - 0.3.9.2-1 +- fix regression introduced in 0.3.9 (RHBZ#1053932) + +* Thu Jan 16 2014 Jiri Popelka - 0.3.9.1-1 +- fix regressions introduced in 0.3.9 (RHBZ#1054068, RHBZ#1054120) + +* Mon Jan 13 2014 Jiri Popelka - 0.3.9-1 +- translation updates +- New IPv6_rpfilter setting to enable source address validation (RHBZ#847707) +- Do not mix original and customized zones in case of target changes, + apply only used zones +- firewall-cmd: fix --*_lockdown_whitelist_uid to work with uid 0 +- Don't show main window maximized. (RHBZ#1046811) +- Use rmmod instead of 'modprobe -r' (RHBZ#1031102) +- Deprecate 'enabled' attribute of 'masquerade' element +- firewall-config: new zone was added twice to the list +- firewalld.dbus(5) +- Enable python shebang fix again +- firewall/client: handle_exceptions: Use loop in decorator +- firewall-offline-cmd: Do not mask firewalld service with disabled option +- firewall-config: richRuleDialogActionRejectType Entry -> ComboBox +- Rich_Rule: fix parsing of reject element (RHBZ#1027373) +- Show combined zones in permanent configuration (RHBZ#1002016) +- firewall-cmd(1): document exit code 2 and colored output (RHBZ#1028507) +- firewall-config: fix RHBZ#1028853 + +* Tue Nov 05 2013 Jiri Popelka - 0.3.8-1 +- fix memory leaks +- New option --debug-gc +- Python3 compatibility +- Better non-ascii support +- several firewall-config & firewall-applet fixes +- New --remove-rules commands for firewall-cmd and removeRules methods for D-Bus +- Fixed FirewallDirect.get_rules to return proper list +- Fixed LastUpdatedOrderedDict.keys() +- Enable rich rule usage in trusted zone (RHBZ#994144) +- New error codes: INVALID_CONTEXT, INVALID_COMMAND, INVALID_USER and INVALID_UID + +* Thu Oct 17 2013 Jiri Popelka - 0.3.7-1 +- Don't fail on missing ip[6]tables/ebtables table. (RHBZ#967376) +- bash-completion: --permanent --direct options +- firewall/core/fw.py: fix checking for iptables & ip6tables (RHBZ#1017087) +- firewall-cmd: use client's exception_handler instead of catching exceptions ourselves +- FirewallClientZoneSettings: fix {add|remove|query}RichRule() +- Extend amanda-client service with 10080/tcp (RHBZ#1016867) +- Simplify Rich_Rule()_lexer() by using functions.splitArgs() +- Fix encoding problems in exception handling (RHBZ#1015941) + +* Fri Oct 04 2013 Jiri Popelka - 0.3.6.2-1 +- firewall-offline-cmd: --forward-port 'toaddr' is optional (RHBZ#1014958) +- firewall-cmd: fix variable name (RHBZ#1015011) + +* Thu Oct 03 2013 Jiri Popelka - 0.3.6.1-1 +- remove superfluous po files from archive + +* Wed Oct 02 2013 Jiri Popelka - 0.3.6-1 +- firewalld.richlanguage.xml: correct log levels (RHBZ#993740) +- firewall-config: Make sure that all zone settings are updated properly on firewalld restart +- Rich_Limit: Allow long representation for duration (RHBZ#994103 +- firewall-config: Show "Changes applied." after changes (RHBZ#993643) +- Use own connection dialog to change zones for NM connections +- Rename service cluster-suite to high-availability (RHBZ#885257) +- Permanent direct support for firewall-config and firewall-cmd +- Try to avoid file descriptor leaking (RHBZ#951900) +- New functions to split and join args properly (honoring quotes) +- firewall-cmd(1): 2 simple examples +- Better IPv6 NAT checking. +- Ship firewalld.direct(5). + +* Mon Sep 30 2013 Jiri Popelka - 0.3.5-1 +- Only use one PK action for configuration (RHBZ#994729) +- firewall-cmd: indicate non-zero exit code with red color +- rich-rule: enable to have log without prefix & log_level & limit +- log-level warn/err -> warning/error (RHBZ#1009436) +- Use policy DROP while reloading, do not reset policy in restart twice +- Add _direct chains to all table and chain combinations +- documentation improvements +- New firewalld.direct(5) man page docbook source +- tests/firewall-cmd_test.sh: make rich language tests work +- Rich_Rule._import_from_string(): improve error messages (RHBZ#994150) +- direct.passthrough wasn't always matching out_signature (RHBZ#967800) +- firewall-config: twist ICMP Type IP address family logic. +- firewall-config: port-forwarding/masquerading dialog (RHBZ#993658) +- firewall-offline-cmd: New --remove-service= option (BZ#969106) +- firewall-config: Options->Lockdown was not changing permanent. +- firewall-config: edit line on doubleclick (RHBZ#993572) +- firewall-config: System Default Zone -> Default Zone (RHBZ#993811) +- New direct D-Bus interface, persistent direct rule handling, enabled passthough +- src/firewall-cmd: Fixed help output to use more visual parameters +- src/firewall-cmd: New usage output, no redirection to man page anymore +- src/firewall/core/rich.py: Fixed forwad port destinations +- src/firewall-offline-cmd: Early enable/disable handling now with mask/unmask +- doc/xml/firewalld.zone.xml: Added more information about masquerade use +- Prefix to log message is optional (RHBZ#998079) +- firewall-cmd: fix --permanent --change-interface (RHBZ#997974) +- Sort zones/interfaces/service/icmptypes on output. +- wbem-https service (RHBZ#996668) +- applet&config: add support for KDE NetworkManager connection editor +- firewall/core/fw_config.py: New method update_lockdown_whitelist +- Added missing file watcher for lockdown whitelist in config D-Bus interface +- firewall/core/watcher: New add_watch_file for lockdown-whitelist and direct +- Make use of IPv6 NAT conditional, based on kernel number (RHBZ#967376) + +* Tue Jul 30 2013 Thomas Woerner 0.3.4-1 +- several rich rule check enhancements and fixes +- firewall-cmd: direct options - check ipv4|ipv6|eb (RHBZ#970505) +- firewall-cmd(1): improve description of direct options (RHBZ#970509) +- several firewall-applet enhancements and fixes +- New README +- several doc and man page fixes +- Service definitions for PCP daemons (RHBZ#972262) +- bash-completion: add lockdown and rich language options +- firewall-cmd: add --permanent --list-all[-zones] +- firewall-cmd: new -q/--quiet option +- firewall-cmd: warn when default zone not active (RHBZ#971843) +- firewall-cmd: check priority in --add-rule (RHBZ#914955) +- add dhcpv6 (for server) service (RHBZ#917866) +- firewall-cmd: add --permanent --get-zone-of-interface/source --change-interface/source +- firewall-cmd: print result (yes/no) of all --query-* commands +- move permanent-getZoneOf{Interface|Source} from firewall-cmd to server +- Check Interfaces/sources when updating permanent zone settings. +- FirewallDConfig: getZoneOfInterface/Source can actually return more zones +- Fixed toaddr check in forward port to only allow single address, no range +- firewall-cmd: various output improvements +- fw_zone: use check_single_address from firewall.functions +- getZoneOfInterface/Source does not need to throw exception +- firewall.functions: Use socket.inet_pton in checkIP, fixed checkIP*nMask +- firewall.core.io.service: Properly check port/proto and destination address +- Install applet desktop file into /etc/xdg/autostart +- Fixed option problem with rich rule destinations (RHBZ#979804) +- Better exception creation in dbus_handle_exceptions() decorator (RHBZ#979790) +- Updated firewall-offline-cmd +- Use priority in add, remove, query and list of direct rules (RHBZ#979509) +- New documentation (man pages are created from docbook sources) +- firewall/core/io/direct.py: use prirority for rule methods, new get_all_ methods +- direct: pass priority also to client.py and firewall-cmd +- applet: New blink and blink-count settings +- firewall.functions: New function ppid_of_pid +- applet: Check for gnome3 and fix it, use new settings, new size-changed cb +- firewall-offline-cmd: Fix use of systemctl in chroot +- firewall-config: use string.ascii_letters instead of string.letters +- dbus_to_python(): handle non-ascii chars in dbus.String. +- Modernize old syntax constructions. +- dict.keys() in Python 3 returns a "view" instead of list +- Use gettext.install() to install _() in builtins namespace. +- Allow non-ascii chars in 'short' and 'description' +- README: More information for "Working With The Source Repository" +- Build environment fixes +- firewalld.spec: Added missing checks for rhel > 6 for pygobject3-base +- firewall-applet: New setting show-inactive +- Don't stop on reload when lockdown already enabled (RHBZ#987403) +- firewall-cmd: --lockdown-on/off did not touch firewalld.conf +- FirewallApplet.gschema.xml: Dropped unused sender-info setting +- doc/firewall-applet.xml: Added information about gsettings +- several debug and log message fixes +- Add chain for sources so they can be checked before interfaces (RHBZ#903222) +- Add dhcp and proxy-dhcp services (RHBZ#986947) +- io/Zone(): don't error on deprecated family attr of source elem +- Limit length of zone file name (to 12 chars) due to Netfilter internals. +- It was not possible to overload a zone with defined source(s). +- DEFAULT_ZONE_TARGET: {chain}_ZONE_{zone} -> {chain}_{zone} +- New runtime getSettings for services and icmptypes, fixed policies callbacks +- functions: New functions checkUser, checkUid and checkCommand +- src/firewall/client: Fixed lockdown-whitelist-updated signal handling +- firewall-cmd(1): move firewalld.richlanguage(5) reference in --*-rich-rule +- Rich rule service: Only add modules for accept action +- firewall/core/rich: Several fixes and enhanced checks +- Fixed reload of direct rules +- firewall/client: New functions to set and get the exception handler +- firewall-config: New and enhanced UI to handle lockdown and rich rules +- zone's immutable attribute is redundant +- Do not allow to set settings in config for immutable zones. +- Ignore deprecated 'immutable' attribute in zone files. +- Eviscerate 'immutable' completely. +- FirewallDirect.query_rule(): fix it +- permanent direct: activate firewall.core.io.direct:Direct reader +- core/io/*: simplify getting of character data +- FirewallDirect.set_config(): allow reloading + +* Thu Jun 20 2013 Jiri Popelka +- Remove migrating to a systemd unit file from a SysV initscript +- Remove pointless "ExclusiveOS" tag + +* Fri Jun 7 2013 Thomas Woerner 0.3.3-2 +- Fixed rich rule check for use in D-Bus + +* Thu Jun 6 2013 Thomas Woerner 0.3.3-1 +- new service files +- relicensed logger.py under GPLv2+ +- firewall-config: sometimes we don't want to use client's exception handler +- When removing Service/IcmpType remove it from zones too (RHBZ#958401) +- firewall-config: work-around masquerade_check_cb() being called more times +- Zone(IO): add interfaces/sources to D-Bus signature +- Added missing UNKNOWN_SOURCE error code +- fw_zone.check_source: Raise INVALID_FAMILY if family is invalid +- New changeZoneOfInterface method, marked changeZone as deprecated +- Fixed firewall-cmd man page entry for --panic-on +- firewall-applet: Fixed possible problems of unescaped strings used for markup +- New support to bind zones to source addresses and ranges (D-BUS, cmd, applet +- Cleanup of unused variables in FirewallD.start +- New firewall/fw_types.py with LastUpdatedOrderedDict +- direct.chains, direct.rules: Using LastUpdatedOrderedDict +- Support splitted zone files +- New reader and writer for stored direct chains and rules +- LockdownWhitelist: fix write(), add get_commands/uids/users/contexts() +- fix service_writer() and icmptype_writer() to put newline at end of file +- firewall-cmd: fix --list-sources +- No need to specify whether source address family is IPv4 or IPv6 +- add getZoneOfSource() to D-Bus interface +- Add tests and bash-completion for the new "source" operations +- Convert all input args in D-Bus methods +- setDefaultZone() was calling accessCheck() *after* the action +- New uniqify() function to remove duplicates from list whilst preserving order +- Zone.combine() merge also services and ports +- config/applet: silence DBusException during start when FirewallD is not running (RHBZ#966518) +- firewall-applet: more fixes to make the address sources family agnostic +- Better defaults for lockdown white list +- Use auth_admin_keep for allow_any and allow_inactive also +- New D-Bus API for lockdown policies +- Use IPv4, IPv6 and BRIDGE for FirewallD properties +- Use rich rule action as audit type +- Prototype of string-only D-Bus interface for rich language +- Fixed wrongly merged source family check in firewall/core/io/zone.py +- handle_cmr: report errors, cleanup modules in error case only, mark handling +- Use audit type from rule action, fixed rule output +- Fixed lockdown whitelist D-Bus handling method names +- New rich rule handling in runtime D-Bus interface +- Added interface, source and rich rule handling (runtime and permanent) +- Fixed dbus_obj in FirewallClientConfigPolicies, added queryLockdown +- Write changes in setLockdownWhitelist +- Fixed typo in policies log message in method calls +- firewall-cmd: Added rich rule, lockdown and lockdown whitelist handling +- Don't check access in query/getLockdownWhitelist*() +- firewall-cmd: Also output masquerade flag in --list-all +- firewall-cmd: argparse is able to convert argument to desired type itself +- firewall-cmd_test.sh: tests for permanent interfaces/sources and lockdown whitelist +- Makefile.am: add missing files +- firewall-cmd_test.sh: tests for rich rules +- Added lockdown, source, interface and rich rule docs to firewall-cmd +- Do not masquerade lo if masquerade is enabled in the default zone (RHBZ#904098) +- Use in metavar for firewall-cmd parser + +* Fri May 10 2013 Jiri Popelka - 0.3.2-2 +- removed unintentional en_US.po from tarball + +* Tue Apr 30 2013 Jiri Popelka - 0.3.2-1 +- Fix signal handling for SIGTERM +- Additional service files (RHBZ#914859) +- Updated po files +- s/persistent/permanent/ (Trac Ticket #7) +- Better behaviour when running without valid DISPLAY (RHBZ#955414) +- client.handle_exceptions(): do not loop forever +- Set Zone.defaults in zone_reader (RHBZ#951747) +- client: do not pass the dbus exception name to handler +- IO_Object_XMLGenerator: make it work with Python 2.7.4 (RHBZ#951741) +- firewall-cmd: do not use deprecated BaseException.message +- client.py: fix handle_exceptions() (RHBZ#951314) +- firewall-config: check zone/service/icmptype name (RHBZ#947820) +- Allow 3121/tcp (pacemaker_remote) in cluster-suite service. (RHBZ#885257) +- firewall-applet: fix default zone hangling in 'shields-up' (RHBZ#947230) +- FirewallError.get_code(): check for unknown error + +* Wed Apr 17 2013 Jiri Popelka - 0.3.1-2 +- Make permanenent changes work with Python 2.7.4 (RHBZ#951741) + +* Thu Mar 28 2013 Thomas Woerner 0.3.1-1 +- Use explicit file lists for make dist +- New rich rule validation check code +- New global check_port and check_address functions +- Allow source white and black listing with the rich rule +- Fix error handling in case of unsupported family in rich rule +- Enable ip_forwarding in masquerade and forward-port +- New functions to read and write simple files using filename and content +- Add --enable-sysconfig to install Fedora-specific sysconfig config file. +- Add chains for security table (RHBZ#927015) +- firewalld.spec: no need to specify --with-systemd-unitdir +- firewalld.service: remove syslog.target and dbus.target +- firewalld.service: replace hard-coded paths +- Move bash-completion to new location. +- Revert "Added configure for new build env" +- Revert "Added Makefile.in files" +- Revert "Added po/Makefile.in.in" +- Revert "Added po/LINGUAS" +- Revert "Added aclocal.m4" +- Amend zone XML Schema + +* Wed Mar 20 2013 Thomas Woerner 0.3.0-1 +- Added rich language support +- Added lockdown feature +- Allow to bind interfaces and sources to zones permanently +- Enabled IPv6 NAT support + masquerading and port/packet forwarding for IPv6 only with rich language +- Handle polkit errors in client class and firewall-config +- Added priority description for --direct --add-rule in firewall-cmd man page +- Add XML Schemas for zones/services/icmptypes XMLs +- Don't keep file descriptors open when forking +- Introduce --nopid option for firewalld +- New FORWARD_IN_ZONES and FORWARD_OUT_ZONES chains (RHBZ#912782) +- Update cluster-suite service (RHBZ#885257) +- firewall-cmd: rename --enable/disable-panic to --panic-on/off (RHBZ#874912) +- Fix interaction problem of changed event of gtk combobox with polkit-kde + by processing all remaining events (RHBZ#915892) +- Stop default zone rules being applied to all zones (RHBZ#912782) +- Firewall.start(): don't call set_default_zone() +- Add wiki's URL to firewalld(1) and firewall-cmd(1) man pages +- firewalld-cmd: make --state verbose (RHBZ#886484) +- improve firewalld --help (RHBZ#910492) +- firewall-cmd: --add/remove-* can be used multiple times (RHBZ#879834) +- Continue loading zone in case of wrong service/port etc. (RHBZ#909466) +- Check also services and icmptypes in Zone() (RHBZ#909466) +- Increase the maximum length of the port forwarding fields from 5 to 11 in + firewall-config +- firewall-cmd: add usage to fail message +- firewall-cmd: redefine usage to point to man page +- firewall-cmd: fix visible problems with arg. parsing +- Use argparse module for parsing command line options and arguments +- firewall-cmd.1: better clarify where to find ACTIONs +- firewall-cmd Bash completion +- firewall-cmd.1: comment --zone= usage and move some options +- Use zone's target only in %%s_ZONES chains +- default zone in firewalld.conf was set to public with every restart (#902845) +- man page cleanup +- code cleanup + +* Thu Mar 07 2013 Jiri Popelka - 0.2.12-5 +- Another fix for RHBZ#912782 + +* Wed Feb 20 2013 Jiri Popelka - 0.2.12-4 +- Stop default zone rules being applied to all zones (RHBZ#912782) + +* Wed Feb 13 2013 Fedora Release Engineering - 0.2.12-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Jan 22 2013 Jiri Popelka - 0.2.12-2 +- Default zone in firewalld.conf was reseted with every restart (RHBZ#902845) +- Add icon cache related scriptlets for firewall-config (RHBZ#902680) +- Fix typo in firewall-config (RHBZ#895812) +- Fix few mistakes in firewall-cmd(1) man page + +* Mon Jan 14 2013 Thomas Woerner 0.2.12-1 +- firewall-cmd: use -V instead of -v for version info (RHBZ#886477) +- firewall-cmd: don't check reload()'s return value (RHBZ#886461) +- actually install firewalld.zones.5 +- firewall-config: treat exceptions when adding new zone/service/icmp + (RHBZ#886602) +- firewalld.spec: Fixed requirements of firewall-config to use gtk2 and + pygobject3 +- Fail gracefully when running in non X environment.(RHBZ#886551) +- offline-cmd: fail gracefully when no s-c-f config +- fix duplicated iptables rules (RHBZ#886515) +- detect errors and duplicates in config file (RHBZ#886581) +- firewall-config: don't make 'Edit Service' and 'Edit ICMP Type' insensitive +- firewalld.spec: fixed requirements, require pygobject3-base +- frewall-applet: Unused code cleanup +- firewall-applet: several usability fixes and enhancements + (RHBZ#886531) (RHBZ#886534) +- firewall/server/server.py: fixed KeyboardInterrupt message (RHBZ#886558) +- Moved fallback zone and minimal_mark to firewall.config.__init__ +- Do not raise ZONE_ALREADY_SET in change_zone if old zone is set again + (RHBZ#886432) +- Make default zone default for all unset connections/interfaces + (RHBZ#888288) (RHBZ#882736) +- firewall-config: Use Gtk.MessageType.WARNING for warning dialog +- firewall-config: Handle unknown services and icmptypes in persistent mode +- firewall-config: Do not load settings more than once +- firewall-config: UI cleanup and fixes (RHBZ#888242) +- firewall-cmd: created alias --change-zone for --change-interface +- firewall-cmd man page updates (RHBZ#806511) +- Merged branch 'build-cleanups' +- dropped call to autogen.sh in build stage, not needed anymore due to + 'build-cleanups' merge + +* Thu Dec 13 2012 Thomas Woerner 0.2.11-2 +- require pygobject3-base instead of pygobject3 (no cairo needed) (RHBZ#874378) +- fixed dependencies of firewall-config to use gtk3 with pygobject3-base and + not pygtk2 + +* Tue Dec 11 2012 Thomas Woerner 0.2.11-1 +- Fixed more _xmlplus (PyXML) incompatibilities to python xml +- Several man page updates +- Fixed error in addForwardPort, removeForwardPort and queryForwardPort +- firewall-cmd: use already existing queryForwardPort() +- Update firewall.cmd man page, use man page as firewall-cmd usage (rhbz#876394) +- firewall-config: Do not force to show labels in the main toolbar +- firewall-config: Dropped "Change default zone" from toolbar +- firewall-config: Added menu entry to change zones of connections +- firewall-applet: Zones can be changed now using nm-connection-editor + (rhbz#876661) +- translation updates: cs, hu, ja + +* Tue Nov 20 2012 Thomas Woerner 0.2.10-1 +- tests/firewalld_config.py: tests for config.service and config.icmptype +- FirewallClientConfigServiceSettings(): destinations are dict not list +- service/zone/icmptype: do not write deprecated name attribute +- New service ntp +- firewall-config: Fixed name of about dialog +- configure.in: Fixed getting of error codes +- Added coding to all pyhton files +- Fixed copyright years +- Beautified file headers +- Force use of pygobject3 in python-slip (RHBZ#874378) +- Log: firewall.server.config_icmptype, firewall.server.config_service and + firewall.server.config_zone: Prepend full path +- Allow ":" in interface names for interface aliases +- Add name argument to Updated and Renamed signal +- Disable IPv4, IPv6 and EB tables if missing - for IPv4/IPv6 only environments +- firewall-config.glade file cleanup +- firewall-config: loadDefaults() can throw exception +- Use toolbars for Add/Edit/Remove/LoadDefaults buttons for zones, services + and icmp types +- New vnc-server service, opens ports for displays :0 to :3 (RHBZ#877035) +- firewall-cmd: Fix typo in help output, allow default zone usage for + permanenent options +- Translation updates: cs, fr, ja, pt_BR and zh_CN + +* Wed Oct 17 2012 Thomas Woerner 0.2.9-1 +- firewall-config: some UI usability changes +- firewall-cmd: New option --list-all-zones, output of --list-all changed, + more option combination checks +- firewall-applet: Replaced NMClient by direct DBUS calls to fix python core + dumps in case of connection activates/deactivates +- Use fallback 'C' locale if current locale isn't supported (RHBZ#860278) +- Add interfaces to zones again after reload +- firewall-cmd: use FirewallClient().connected value +- firewall-cmd: --remove-interface was not working due to a typo +- Do not use restorecon for new and backup files +- Fixed use of properties REJECT and DROP +- firewalld_test.py: check interfaces after reload +- Translation updates +- Renamed firewall-convert-scfw-config to firewall-offline-cmd, used by + anaconda for firewall configuration (e.g. kickstart) +- Fix python shebang to use -Es at installation time for bin_SCRIPTS and + sbin_SCRIPTS and at all times in gtk3_chooserbutton.py +- tests/firewalld_config.py: update test_zones() test case +- Config interface: improve renaming of zones/services/icmp_types +- Move emiting of Added signals closer to source. +- FirewallClient(): config:ServiceAdded signal was wrongly mapped +- Add argument 'name' to Removed signal +- firewall-config: Add callbacks for config:[service|icmp]-[added|removed] +- firewall-config: catch INVALID_X error when removing zone/service/icmp_type +- firewall-config: remove unused code +- Revert "Neutralize _xmlplus instead of conforming it" +- firewall-applet: some UI usability changes +- firewall-cmd: ALREADY_ENABLED, NOT_ENABLED, ZONE_ALREADY_SET are warnings + +* Fri Sep 7 2012 Thomas Woerner 0.2.8-1 +- Do not apply old settings to zones after reload +- FirewallClient: Added callback structure for firewalld signals +- New firewall-config with full zone, service and icmptype support +- Added Shields Up/Down configuration dialog to firewall-applet +- Name attribute of main tag deprecated for zones, services and icmptypes, + will be ignored if present +- Fixed wrong references in firewalld man page +- Unregister DBus interfaces after sending out the Removed signal +- Use proper DBus signature in addIcmpType, addService and addZone +- New builtin property for config interfaces +- New test case for Config interface +- spec: use new systemd-rpm macros (rhbz#850110) +- More config file verifications +- Lots of smaller fixes and enhancements + +* Tue Aug 21 2012 Jiri Popelka 0.2.7-2 +- use new systemd-rpm macros (rhbz#850110) + +* Mon Aug 13 2012 Thomas Woerner 0.2.7-1 +- Update of firewall-config +- Some bug fixes + +* Tue Aug 7 2012 Thomas Woerner 0.2.6-1 +- New D-BUS interface for persistent configuration +- Aded support for persistent zone configuration in firewall-cmd +- New Shields Up feature in firewall-applet +- New requirements for python-decorator and pygobject3 +- New firewall-config sub-package +- New firewall-convert-scfw-config config script + +* Fri Apr 20 2012 Thomas Woerner 0.2.5-1 +- Fixed traceback in firewall-cmd for failed or canceled authorization, + return proper error codes, new error codes NOT_RUNNING and NOT_AUTHORIZED +- Enhanced firewalld service file (RHBZ#806868) and (RHBZ#811240) +- Fixed duplicates in zone after reload, enabled timed settings after reload +- Removed conntrack --ctstate INVALID check from default ruleset, because it + results in ICMP problems (RHBZ#806017). +- Update interfaces in default zone after reload (rhbz#804814) +- New man pages for firewalld(1), firewalld.conf(5), firewalld.icmptype(5), + firewalld.service(5) and firewalld.zone(5), updated firewall-cmd man page + (RHBZ#811257) +- Fixed firewall-cmd help output +- Fixed missing icon for firewall-applet (RHBZ#808759) +- Added root user check for firewalld (RHBZ#767654) +- Fixed requirements of firewall-applet sub package (RHBZ#808746) +- Update interfaces in default zone after changing of default zone (RHBZ#804814) +- Start firewalld before NetworkManager (RHBZ#811240) +- Add Type=dbus and BusName to service file (RHBZ#811240) + +* Fri Mar 16 2012 Thomas Woerner 0.2.4-1 +- fixed firewalld.conf save exception if no temporary file can be written to + /etc/firewalld/ + +* Thu Mar 15 2012 Thomas Woerner 0.2.3-1 +- firewall-cmd: several changes and fixes +- code cleanup +- fixed icmp protocol used for ipv6 (rhbz#801182) +- added and fixed some comments +- properly restore zone settings, timeout is always set, check for 0 +- some FirewallError exceptions were actually not raised +- do not REJECT in each zone +- removeInterface() don't require zone +- new tests in firewall-test script +- dbus_to_python() was ignoring certain values +- added functions for the direct interface: chains, rules, passthrough +- fixed inconsistent data after reload +- some fixes for the direct interface: priority positions are bound to ipv, + table and chain +- added support for direct interface in firewall-cmd: +- added isImmutable(zone) to zone D-Bus interface +- renamed policy file +- enhancements for error messages, enables output for direct.passthrough +- added allow_any to firewald policies, using at leas auth_admin for policies +- replaced ENABLE_FAILED, DISABLE_FAILED, ADD_FAILED and REMOVE_FAILED by + COMMAND_FAILED, resorted error codes +- new firewalld configuration setting CleanupOnExit +- enabled polkit again, found a fix for property problem with slip.dbus.service +- added dhcpv6-client to 'public' (the default) and to 'internal' zones. +- fixed missing settings form zone config files in + "firewall-cmd --list=all --zone=" call +- added list functions for services and icmptypes, added --list=services and + --list=icmptypes to firewall-cmd + +* Tue Mar 6 2012 Thomas Woerner 0.2.2-1 +- enabled dhcpv6-client service for zones home and work +- new dhcpv6-client service +- firewall-cmd: query mode returns reversed values +- new zone.changeZone(zone, interface) +- moved zones, services and icmptypes to /usr/lib/firewalld, can be overloaded + by files in /etc/firewalld (no overload of immutable zones block, drop, + trusted) +- reset MinimalMark in firewalld.cnf to default value +- fixed service destination (addresses not used) +- fix xmlplus to be compatible with the python xml sax parser and python 3 + by adding __contains__ to xml.sax.xmlreader.AttributesImpl +- use icon and glib related post, postun and posttrans scriptes for firewall +- firewall-cmd: fix typo in state +- firewall-cmd: fix usage() +- firewall-cmd: fix interface action description in usage() +- client.py: fix definition of queryInterface() +- client.py: fix typo in getInterfaces() +- firewalld.service: do not fork +- firewall-cmd: fix bug in --list=port and --port action help message +- firewall-cmd: fix bug in --list=service + +* Mon Mar 5 2012 Thomas Woerner +- moved zones, services and icmptypes to /usr/lib/firewalld, can be overloaded + by files in /etc/firewalld (no overload of immutable zones block, drop, + trusted) + +* Tue Feb 21 2012 Thomas Woerner 0.2.1-1 +- added missing firewall.dbus_utils + +* Tue Feb 7 2012 Thomas Woerner 0.2.0-2 +- added glib2-devel to build requires, needed for gsettings.m4 +- added --with-system-unitdir arg to fix installaiton of system file +- added glib-compile-schemas calls for postun and posttrans +- added EXTRA_DIST file lists + +* Mon Feb 6 2012 Thomas Woerner 0.2.0-1 +- version 0.2.0 with new FirewallD1 D-BUS interface +- supports zones with a default zone +- new direct interface as a replacement of the partial virt interface with + additional passthrough functionality +- dropped custom rules, use direct interface instead +- dropped trusted interface funcionality, use trusted zone instead +- using zone, service and icmptype configuration files +- not using any system-config-firewall parts anymore + +* Mon Feb 14 2011 Thomas Woerner 0.1.3-1 +- new version 0.1.3 +- restore all firewall features for reload: panic and virt rules and chains +- string fixes for firewall-cmd man page (by Jiri Popelka) +- fixed firewall-cmd port list (by Jiri Popelka) +- added firewall dbus client connect check to firewall-cmd (by Jiri Popelka) +- translation updates: de, es, gu, it, ja, kn, ml, nl, or, pa, pl, ru, ta, + uk, zh_CN + +* Mon Jan 3 2011 Thomas Woerner 0.1.2-1 +- fixed package according to package review (rhbz#665395): + - non executable scripts: dropped shebang + - using newer GPL license file + - made /etc/dbus-1/system.d/FirewallD.conf config(noreplace) + - added requires(post) and (pre) for chkconfig + +* Mon Jan 3 2011 Thomas Woerner 0.1.1-1 +- new version 0.1.1 +- fixed source path in POTFILES* +- added missing firewall_config.py.in +- added misssing space for spec_ver line +- using firewall_config.VARLOGFILE +- added date to logging output +- also log fatal and error logs to stderr and firewall_config.VARLOGFILE +- make log message for active_firewalld fatal + +* Mon Dec 20 2010 Thomas Woerner 0.1-1 +- initial package (proof of concept implementation)