Browse Source

firewalld package update

Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>
master
basebuilder_pel7ppc64bebuilder0 6 years ago
parent
commit
8af9539764
  1. 117
      SOURCES/0001-firewall.core.fw_nm-avoid-iterating-NM-devices-conne.patch
  2. 190
      SOURCES/0001-fw-if-startup-fails-on-reload-reapply-non-perm-confi.patch
  3. 26
      SOURCES/0001-ipset-check-type-when-parsing-ipset-definition.patch
  4. 28
      SOURCES/0001-tests-functions-check-state-after-a-reload.patch
  5. 132
      SOURCES/0002-firewall-core-io-functions-add-check_config.patch
  6. 352
      SOURCES/0002-firewall.core.fw_nm-identify-the-connections-by-uuid.patch
  7. 40
      SOURCES/0002-fw-If-direct-rules-fail-to-apply-add-a-Direct-label-.patch
  8. 45
      SOURCES/0002-fw-on-restart-set-policy-from-same-function.patch
  9. 68
      SOURCES/0003-firewall-offline-cmd-add-check-config-option.patch
  10. 37
      SOURCES/0003-firewall.core.fw_nm-ignore-generated-connections.patch
  11. 244
      SOURCES/0003-fw-if-failure-occurs-during-startup-set-state-to-FAI.patch
  12. 122
      SOURCES/0004-firewall-cmd-add-check-config-option.patch
  13. 416
      SOURCES/0005-tests-firewall-cmd-exercise-check-config.patch
  14. 46
      SOURCES/firewalld-0.4.4.3-exclude_firewallctl_rhbz#1374799.patch
  15. 449
      SOURCES/firewalld-0.4.4.3-qt4_applet.patch
  16. 1261
      SPECS/firewalld.spec

117
SOURCES/0001-firewall.core.fw_nm-avoid-iterating-NM-devices-conne.patch

@ -0,0 +1,117 @@
From 5f41f061390876f4c43c2306911d9b3482aed396 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 16 Jul 2018 17:42:34 +0200
Subject: [PATCH 1/3] firewall.core.fw_nm: avoid iterating NM devices,
connections

NetworkManager has an API to do the lookups.

(cherry picked from commit 65f92930a5d049404dac780c15eebe2d788e6285)
---
src/firewall/core/fw_nm.py | 70 ++++++++++++++++++----------------------------
1 file changed, 27 insertions(+), 43 deletions(-)

diff --git a/src/firewall/core/fw_nm.py b/src/firewall/core/fw_nm.py
index f75733fe65f6..76901cee2adf 100644
--- a/src/firewall/core/fw_nm.py
+++ b/src/firewall/core/fw_nm.py
@@ -73,22 +73,18 @@ def nm_get_zone_of_connection(connection):
"""
check_nm_imported()
- active_connections = nm_get_client().get_active_connections()
+ con = nm_get_client().get_connection_by_id(connection)
+ if con is None:
+ return False
- for active_con in active_connections:
- if active_con.get_id() == connection:
- con = active_con.get_connection()
- if con is None:
- continue
- setting_con = con.get_setting_connection()
- if setting_con is None:
- continue
- zone = setting_con.get_zone()
- if zone is None:
- zone = ""
- return zone
+ setting_con = con.get_setting_connection()
+ if setting_con is None:
+ return False
- return None
+ zone = setting_con.get_zone()
+ if zone is None:
+ zone = ""
+ return zone
def nm_set_zone_of_connection(zone, connection):
"""Set the zone for a connection
@@ -98,24 +94,18 @@ def nm_set_zone_of_connection(zone, connection):
"""
check_nm_imported()
- active_connections = nm_get_client().get_active_connections()
-
- for active_con in active_connections:
- con = active_con.get_connection()
- if con is None:
- continue
+ con = nm_get_client().get_connection_by_id(connection)
+ if con is None:
+ return False
- if active_con.get_id() == connection:
- setting_con = con.get_setting_connection()
- if setting_con is None:
- continue
- if zone == "":
- zone = None
- setting_con.set_property("zone", zone)
- con.commit_changes(True, None)
- return True
+ setting_con = con.get_setting_connection()
+ if setting_con is None:
+ return False
- return False
+ if zone == "":
+ zone = None
+ setting_con.set_property("zone", zone)
+ return con.commit_changes(True, None)
def nm_get_connections(connections, connections_uuid):
"""Get active connections from NM
@@ -150,21 +140,15 @@ def nm_get_connection_of_interface(interface):
"""
check_nm_imported()
- active_connections = nm_get_client().get_active_connections()
-
- for active_con in active_connections:
- # ignore vpn devices for now
- if active_con.get_vpn():
- continue
-
- devices = active_con.get_devices()
-
- for dev in devices:
- if dev.get_iface() == interface:
- return active_con.get_id()
+ device = nm_get_client().get_device_by_iface(interface)
+ if device is None:
+ return None
+ active_con = device.get_active_connection()
+ if active_con is None:
+ return None
- return None
+ return active_con.get_id()
def nm_get_bus_name():
if not _nm_imported:
--
2.16.3

190
SOURCES/0001-fw-if-startup-fails-on-reload-reapply-non-perm-confi.patch

@ -0,0 +1,190 @@
From 17470fa9deac4aa15ecf75b9c811c093bc44c019 Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Fri, 17 Aug 2018 12:26:53 -0400
Subject: [PATCH 1/2] fw: if startup fails on reload, reapply non-perm config
that survives reload

Even if startup fails we should still re-assign the non-permanent
interfaces to zones and non-permanent direct rules.

Fixes: rhbz 1498923
(cherry picked from commit 2796edc1691f52c3655991c0be814a617cb26910)
---
src/firewall/core/fw.py | 121 +++++++++++++++-------------
src/tests/regression/rhbz1498923.at | 17 ++++
2 files changed, 80 insertions(+), 58 deletions(-)

diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
index 5b706d6d3e80..9079f1bbc6a4 100644
--- a/src/firewall/core/fw.py
+++ b/src/firewall/core/fw.py
@@ -910,70 +910,75 @@ class Firewall(object):
def reload(self, stop=False):
_panic = self._panic
- try:
- # save zone interfaces
- _zone_interfaces = { }
- for zone in self.zone.get_zones():
- _zone_interfaces[zone] = self.zone.get_settings(zone)["interfaces"]
- # save direct config
- _direct_config = self.direct.get_runtime_config()
- _old_dz = self.get_default_zone()
-
- # stop
- self.cleanup()
+ # save zone interfaces
+ _zone_interfaces = { }
+ for zone in self.zone.get_zones():
+ _zone_interfaces[zone] = self.zone.get_settings(zone)["interfaces"]
+ # save direct config
+ _direct_config = self.direct.get_runtime_config()
+ _old_dz = self.get_default_zone()
+
+ # stop
+ self.cleanup()
- self.set_policy("DROP")
+ self.set_policy("DROP")
+ start_exception = None
+ try:
self._start(reload=True, complete_reload=stop)
-
- # handle interfaces in the default zone and move them to the new
- # default zone if it changed
- _new_dz = self.get_default_zone()
- if _new_dz != _old_dz:
- # if_new_dz has been introduced with the reload, we need to add it
- # https://github.com/firewalld/firewalld/issues/53
- if _new_dz not in _zone_interfaces:
- _zone_interfaces[_new_dz] = { }
- # default zone changed. Move interfaces from old default zone to
- # the new one.
- for iface, settings in list(_zone_interfaces[_old_dz].items()):
- if settings["__default__"]:
- # move only those that were added to default zone
- # (not those that were added to specific zone same as
- # default)
- _zone_interfaces[_new_dz][iface] = \
- _zone_interfaces[_old_dz][iface]
- del _zone_interfaces[_old_dz][iface]
-
- # add interfaces to zones again
- for zone in self.zone.get_zones():
- if zone in _zone_interfaces:
- self.zone.set_settings(zone, { "interfaces":
- _zone_interfaces[zone] })
- del _zone_interfaces[zone]
- else:
- log.info1("New zone '%s'.", zone)
- if len(_zone_interfaces) > 0:
- for zone in list(_zone_interfaces.keys()):
- log.info1("Lost zone '%s', zone interfaces dropped.", zone)
- del _zone_interfaces[zone]
- del _zone_interfaces
-
- # restore direct config
- self.direct.set_config(_direct_config)
-
- # enable panic mode again if it has been enabled before or set policy
- # to ACCEPT
- if _panic:
- self.enable_panic_mode()
+ except Exception as e:
+ # save the exception for later, but continue restoring interfaces,
+ # etc. We'll re-raise it at the end.
+ start_exception = e
+
+ # handle interfaces in the default zone and move them to the new
+ # default zone if it changed
+ _new_dz = self.get_default_zone()
+ if _new_dz != _old_dz:
+ # if_new_dz has been introduced with the reload, we need to add it
+ # https://github.com/firewalld/firewalld/issues/53
+ if _new_dz not in _zone_interfaces:
+ _zone_interfaces[_new_dz] = { }
+ # default zone changed. Move interfaces from old default zone to
+ # the new one.
+ for iface, settings in list(_zone_interfaces[_old_dz].items()):
+ if settings["__default__"]:
+ # move only those that were added to default zone
+ # (not those that were added to specific zone same as
+ # default)
+ _zone_interfaces[_new_dz][iface] = \
+ _zone_interfaces[_old_dz][iface]
+ del _zone_interfaces[_old_dz][iface]
+
+ # add interfaces to zones again
+ for zone in self.zone.get_zones():
+ if zone in _zone_interfaces:
+ self.zone.set_settings(zone, { "interfaces":
+ _zone_interfaces[zone] })
+ del _zone_interfaces[zone]
else:
- self.set_policy("ACCEPT")
+ log.info1("New zone '%s'.", zone)
+ if len(_zone_interfaces) > 0:
+ for zone in list(_zone_interfaces.keys()):
+ log.info1("Lost zone '%s', zone interfaces dropped.", zone)
+ del _zone_interfaces[zone]
+ del _zone_interfaces
+
+ # restore direct config
+ self.direct.set_config(_direct_config)
+
+ # enable panic mode again if it has been enabled before or set policy
+ # to ACCEPT
+ if _panic:
+ self.enable_panic_mode()
+ else:
+ self.set_policy("ACCEPT")
- self._state = "RUNNING"
- except Exception:
+ if start_exception:
self._state = "FAILED"
- self.set_policy("ACCEPT")
- raise
+ raise start_exception
+ else:
+ self._state = "RUNNING"
# STATE
diff --git a/src/tests/regression/rhbz1498923.at b/src/tests/regression/rhbz1498923.at
index bb0d841db2a7..9b68678180ef 100644
--- a/src/tests/regression/rhbz1498923.at
+++ b/src/tests/regression/rhbz1498923.at
@@ -1,11 +1,28 @@
FWD_START_TEST([invalid direct rule causes reload error])
FWD_CHECK([-q --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 8080 -j ACCEPT])
FWD_CHECK([-q --permanent --direct --add-rule ipv4 filter INPUT 1 --a-bogus-flag])
+
+dnl add some non-permanent things that should persist a reload
+FWD_CHECK([-q --zone=public --add-interface=foobar0])
+FWD_CHECK([-q --direct --direct --add-rule ipv4 filter FORWARD 0 -p tcp -j ACCEPT])
+
FWD_RELOAD(13, [ignore], [ignore], 251)
FWD_CHECK([--state], 251, [ignore], [failed
])
+dnl verify the non-permanent stuff we set above remained
+FWD_CHECK([--get-zone-of-interface=foobar0], 0, [dnl
+public
+])
+FWD_CHECK([-q --direct --direct --query-rule ipv4 filter FORWARD 0 -p tcp -j ACCEPT])
+
dnl now remove the bad rule and reload successfully
FWD_CHECK([-q --permanent --direct --remove-rule ipv4 filter INPUT 1 --a-bogus-flag])
FWD_RELOAD
+
+dnl verify the non-permanent stuff we set above remained
+FWD_CHECK([--get-zone-of-interface=foobar0], 0, [dnl
+public
+])
+FWD_CHECK([-q --direct --direct --query-rule ipv4 filter FORWARD 0 -p tcp -j ACCEPT])
FWD_END_TEST([-e '/.*a-bogus-flag.*/d'])
--
2.18.0

26
SOURCES/0001-ipset-check-type-when-parsing-ipset-definition.patch

@ -0,0 +1,26 @@
From 26e35f61bb856aa482f84f50521f924d4a6c12b1 Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Thu, 24 May 2018 16:30:13 -0400
Subject: [PATCH 1/5] ipset: check type when parsing ipset definition

(cherry picked from commit ebe0cb93c3f38a5d9af267407769eb187940c62f)
---
src/firewall/core/io/ipset.py | 2 ++
1 file changed, 2 insertions(+)

diff --git a/src/firewall/core/io/ipset.py b/src/firewall/core/io/ipset.py
index f291d15e0033..0670677b4206 100644
--- a/src/firewall/core/io/ipset.py
+++ b/src/firewall/core/io/ipset.py
@@ -320,6 +320,8 @@ class ipset_ContentHandler(IO_Object_ContentHandler):
self.item.parser_check_element_attrs(name, attrs)
if name == "ipset":
if "type" in attrs:
+ if attrs["type"] not in IPSET_TYPES:
+ raise FirewallError(errors.INVALID_TYPE, "%s" % attrs["type"])
self.item.type = attrs["type"]
if "version" in attrs:
self.item.version = attrs["version"]
--
2.16.3

28
SOURCES/0001-tests-functions-check-state-after-a-reload.patch

@ -0,0 +1,28 @@
From 83f7000d753f6e4c688ca91badc4d73bcf37929f Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Mon, 13 Aug 2018 14:39:25 -0400
Subject: [PATCH 1/4] tests/functions: check state after a reload

To make sure firewalld doesn't get stuck during a reload we should check
the state as well.

(cherry picked from commit 8b3591c3f238156911bb63dd5622168d21a9ae78)
---
src/tests/functions.at | 1 +
1 file changed, 1 insertion(+)

diff --git a/src/tests/functions.at b/src/tests/functions.at
index d9b1ce401bb0..02464f3c22df 100644
--- a/src/tests/functions.at
+++ b/src/tests/functions.at
@@ -55,6 +55,7 @@ m4_define([FWD_START_FIREWALLD], [
m4_define([FWD_RELOAD], [
FWD_CHECK([-q --reload], [$1], [$2], [$3])
+ FWD_CHECK([-q --state], [$4], [$5], [$6])
])
m4_define([FWD_RESTART], [
--
2.18.0

132
SOURCES/0002-firewall-core-io-functions-add-check_config.patch

@ -0,0 +1,132 @@
From 2342548148763cca0579da98ed0a682d22beb49d Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Fri, 1 Jun 2018 09:37:34 -0400
Subject: [PATCH 2/5] firewall/core/io/functions: add check_config()

This is a utility function to run checks on all the configuration files.

(cherry picked from commit 4164148b88f1882eabde4eeb4cc9a45506aff0fa)
---
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/firewall/core/io/functions.py | 84 +++++++++++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+)
create mode 100644 src/firewall/core/io/functions.py

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 12cdbf2c6929..2332f8acc4eb 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -70,6 +70,7 @@ src/firewall/core/prog.py
src/firewall/core/watcher.py
src/firewall/core/io/__init__.py
src/firewall/core/io/firewalld_conf.py
+src/firewall/core/io/functions.py
src/firewall/core/io/icmptype.py
src/firewall/core/io/io_object.py
src/firewall/core/io/service.py
diff --git a/src/Makefile.am b/src/Makefile.am
index b249c2e5fd46..b44ae0c1eca4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,6 +34,7 @@ nobase_dist_python_DATA = \
firewall/core/__init__.py \
firewall/core/io/direct.py \
firewall/core/io/firewalld_conf.py \
+ firewall/core/io/functions.py \
firewall/core/io/helper.py \
firewall/core/io/icmptype.py \
firewall/core/io/ifcfg.py \
diff --git a/src/firewall/core/io/functions.py b/src/firewall/core/io/functions.py
new file mode 100644
index 000000000000..7509a5390e12
--- /dev/null
+++ b/src/firewall/core/io/functions.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2018 Red Hat, Inc.
+#
+# Authors:
+# Eric Garver <egarver@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+
+from firewall import config
+from firewall.errors import FirewallError
+
+from firewall.core.io.zone import zone_reader
+from firewall.core.io.service import service_reader
+from firewall.core.io.ipset import ipset_reader
+from firewall.core.io.icmptype import icmptype_reader
+from firewall.core.io.helper import helper_reader
+from firewall.core.io.direct import Direct
+from firewall.core.io.lockdown_whitelist import LockdownWhitelist
+from firewall.core.io.firewalld_conf import firewalld_conf
+
+def check_config(fw=None):
+ readers = {
+ "ipset" : (ipset_reader, [config.FIREWALLD_IPSETS, config.ETC_FIREWALLD_IPSETS]),
+ "helper" : (helper_reader, [config.FIREWALLD_HELPERS, config.ETC_FIREWALLD_HELPERS]),
+ "icmptype" : (icmptype_reader, [config.FIREWALLD_ICMPTYPES, config.ETC_FIREWALLD_ICMPTYPES]),
+ "service" : (service_reader, [config.FIREWALLD_SERVICES, config.ETC_FIREWALLD_SERVICES]),
+ "zone" : (zone_reader, [config.FIREWALLD_ZONES, config.ETC_FIREWALLD_ZONES]),
+ }
+ for reader in readers.keys():
+ for dir in readers[reader][1]:
+ if not os.path.isdir(dir):
+ continue
+ for file in sorted(os.listdir(dir)):
+ if file.endswith(".xml"):
+ try:
+ obj = readers[reader][0](file, dir)
+ if fw and reader == "zone":
+ obj.fw_config = fw.config
+ obj.check_config(obj.export_config())
+ except FirewallError as error:
+ raise FirewallError(error.code, "'%s': %s" % (file, error.msg))
+ except Exception as msg:
+ raise Exception("'%s': %s" % (file, msg))
+ if os.path.isfile(config.FIREWALLD_DIRECT):
+ try:
+ obj = Direct(config.FIREWALLD_DIRECT)
+ obj.read()
+ obj.check_config(obj.export_config())
+ except FirewallError as error:
+ raise FirewallError(error.code, "'%s': %s" % (config.FIREWALLD_DIRECT, error.msg))
+ except Exception as msg:
+ raise Exception("'%s': %s" % (config.FIREWALLD_DIRECT, msg))
+ if os.path.isfile(config.LOCKDOWN_WHITELIST):
+ try:
+ obj = LockdownWhitelist(config.LOCKDOWN_WHITELIST)
+ obj.read()
+ obj.check_config(obj.export_config())
+ except FirewallError as error:
+ raise FirewallError(error.code, "'%s': %s" % (config.LOCKDOWN_WHITELIST, error.msg))
+ except Exception as msg:
+ raise Exception("'%s': %s" % (config.LOCKDOWN_WHITELIST, msg))
+ if os.path.isfile(config.FIREWALLD_CONF):
+ try:
+ obj = firewalld_conf(config.FIREWALLD_CONF)
+ obj.read()
+ except FirewallError as error:
+ raise FirewallError(error.code, "'%s': %s" % (config.FIREWALLD_CONF, error.msg))
+ except Exception as msg:
+ raise Exception("'%s': %s" % (config.FIREWALLD_CONF, msg))
--
2.16.3

352
SOURCES/0002-firewall.core.fw_nm-identify-the-connections-by-uuid.patch

@ -0,0 +1,352 @@
From 0ce07e30014a8ee6b2a8a4909c313f207d9c9b31 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 16 Jul 2018 17:43:04 +0200
Subject: [PATCH 2/3] firewall.core.fw_nm: identify the connections by uuid

...as opposed by id. Uuid is guarranteed to be uniquie, while the id is
provided merely for convenience without any guarrantees.

(cherry picked from commit 624039964bd16e5e0e8ffb73e708d3d0c40e89d3)
---
src/firewall-applet | 38 ++++++++++++++++++++------------------
src/firewall-config | 45 +++++++++++++++++++++++++--------------------
src/firewall/core/fw_nm.py | 16 ++++++++--------
3 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/src/firewall-applet b/src/firewall-applet
index 3dc149c32755..86aaccab9f88 100755
--- a/src/firewall-applet
+++ b/src/firewall-applet
@@ -155,11 +155,12 @@ class ZoneInterfaceEditor(QtGui.QDialog):
# ZoneConnectionEditor ########################################################
class ZoneConnectionEditor(ZoneInterfaceEditor):
- def __init__(self, fw, connection, zone):
+ def __init__(self, fw, connection, connection_name, zone):
self.fw = fw
self.connection = connection
+ self.connection_name = connection_name
self.zone = None
- self.title = _("Select zone for connection '%s'") % self.connection
+ self.title = _("Select zone for connection '%s'") % self.connection_name
QtGui.QDialog.__init__(self)
self.create_ui(zone)
@@ -168,12 +169,12 @@ class ZoneConnectionEditor(ZoneInterfaceEditor):
# apply changes
try:
nm_set_zone_of_connection(self.get_zone(), self.connection)
- except Exception as msg:
- text = _("Failed to set zone {zone} for connection {connection}")
+ except Exception:
+ text = _("Failed to set zone {zone} for connection {connection_name}")
QtGui.QMessageBox.warning(None, fromUTF8(escape(self.title)),
escape(text.format(
zone=self.get_zone(),
- connection=self.connection)))
+ connection_name=self.connection_name)))
self.hide()
# ZoneSourceEditor ############################################################
@@ -428,7 +429,7 @@ class TrayApplet(QtGui.QSystemTrayIcon):
self.active_zones = { }
self.connections = { }
- self.connections_uuid = { }
+ self.connections_name = { }
self.default_zone = None
self.zone_connection_editors = { }
self.zone_interface_editors = { }
@@ -666,30 +667,31 @@ class TrayApplet(QtGui.QSystemTrayIcon):
# NM controlled connections
for interface in self.connections:
connection = self.connections[interface]
- if connection not in self.connections_uuid:
- uuid = None
+ if connection not in self.connections_name:
+ connection_name = None
else:
- uuid = self.connections_uuid[connection]
+ connection_name = self.connections_name[connection]
zone = nm_get_zone_of_connection(connection)
- connections[connection] = [ zone, uuid ]
+ connections[connection] = [ zone, connection_name ]
binding = _("{entry} (Zone: {zone})")
# add NM controlled bindings
for connection in sorted(connections):
zone = connections[connection][0]
+ connection_name = connections[connection][1]
if zone == "":
_binding = _("{entry} (Default Zone: {default_zone})")
action = QtGui.QAction(
fromUTF8(escape(
_binding.format(default_zone=self.default_zone,
- entry=connection))), self)
+ entry=connection_name))), self)
else:
action = QtGui.QAction(
fromUTF8(escape(binding.format(zone=zone,
- entry=connection))), self)
+ entry=connection_name))), self)
action.triggered.connect(functools.partial(
- self.zone_connection_editor, connection, zone))
+ self.zone_connection_editor, connection, connection_name, zone))
self.left_menu.addAction(action)
# add interfaces entry
@@ -729,13 +731,13 @@ class TrayApplet(QtGui.QSystemTrayIcon):
editor.raise_()
editor.show()
- def zone_connection_editor(self, connection, zone):
+ def zone_connection_editor(self, connection, connection_name, zone):
if connection in self.zone_connection_editors:
self.zone_connection_editors[connection].set_zone(zone)
self.zone_connection_editors[connection].show()
return self.zone_connection_editors[connection].raise_()
- editor = ZoneConnectionEditor(self.fw, connection, zone)
+ editor = ZoneConnectionEditor(self.fw, connection, connection_name, zone)
self.zone_connection_editors[connection] = editor
editor.show()
editor.raise_()
@@ -755,15 +757,15 @@ class TrayApplet(QtGui.QSystemTrayIcon):
def nm_signal_receiver(self, *args, **kwargs):
self.connections.clear()
- self.connections_uuid.clear()
+ self.connections_name.clear()
# do not use NMClient could result in python core dump
if nm_is_imported():
text = _("Failed to get connections from NetworkManager")
try:
- nm_get_connections(self.connections, self.connections_uuid)
- except Exception as msg:
+ nm_get_connections(self.connections, self.connections_name)
+ except Exception:
self.notify(escape(text), urgency=Notify.Urgency.CRITICAL)
if text not in self.tooltip_messages:
self.tooltip_messages.append(text)
diff --git a/src/firewall-config b/src/firewall-config
index 02bffabf457c..223c0ff6d27d 100755
--- a/src/firewall-config
+++ b/src/firewall-config
@@ -1368,7 +1368,7 @@ class FirewallConfig(object):
# connect
self.connections = { }
- self.connections_uuid = { }
+ self.connections_name = { }
if nm_is_imported():
self.fw.bus.add_signal_receiver(
@@ -1428,11 +1428,11 @@ class FirewallConfig(object):
self.fw.changeZoneOfInterface(editor.get_zone(), interface)
del self.zone_interface_editors[interface]
- def change_zone_connection_editor(self, item, connection, zone):
+ def change_zone_connection_editor(self, item, connection, connection_name, zone):
if connection in self.zone_connection_editors:
return self.zone_connection_editors[connection].present()
- editor = ZoneConnectionEditor(self.fw, connection, zone)
+ editor = ZoneConnectionEditor(self.fw, connection, connection_name, zone)
editor.set_icon(self.icon)
editor.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
editor.set_transient_for(self.mainWindow)
@@ -1557,14 +1557,14 @@ class FirewallConfig(object):
self.update_active_zones()
self.connections.clear()
- self.connections_uuid.clear()
+ self.connections_name.clear()
# do not use NMClient could result in python core dump
if nm_is_imported():
try:
- nm_get_connections(self.connections, self.connections_uuid)
- except Exception as msg:
+ nm_get_connections(self.connections, self.connections_name)
+ except Exception:
text = _("Failed to get connections from NetworkManager")
self._warning(text)
@@ -1572,12 +1572,14 @@ class FirewallConfig(object):
while iter:
interface = self.interfaceStore.get_value(iter, 0)
if interface in self.connections:
- zone = nm_get_zone_of_connection(self.connections[interface])
+ connection = self.connections[interface]
+ connection_name = self.connections_name[connection]
+ zone = nm_get_zone_of_connection(connection)
if zone == "":
comment = self.default_zone_used_by_label % \
- self.connections[interface]
+ connection_name
else:
- comment = self.used_by_label % self.connections[interface]
+ comment = self.used_by_label % connection_name
self.interfaceStore.set_value(iter, 1, comment)
iter = self.interfaceStore.iter_next(iter)
self.change_interface_selection_cb(self.interfaceView.get_selection())
@@ -2427,37 +2429,38 @@ class FirewallConfig(object):
# add NM controlled entries
for connection in sorted(connections):
[ zone, _interfaces ] = connections[connection]
+ connection_name = self.connections_name[connection]
item = Gtk.MenuItem.new()
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
label = Gtk.Label()
if zone == "":
label.set_markup("%s (%s)\n<small>%s: %s</small>" % \
- (connection, ",".join(_interfaces),
+ (connection_name, ",".join(_interfaces),
escape(_("Default Zone")), self.default_zone))
else:
label.set_markup("%s (%s)\n<small>%s: %s</small>" % \
- (connection, ",".join(_interfaces),
+ (connection_name, ",".join(_interfaces),
escape(_("Zone")), zone))
label.set_alignment(0, 0.5)
label.set_padding(12, 0)
hbox.pack_start(label, True, True, 0)
item.add(hbox)
- item.connect("activate", self.change_zone_connection_editor, connection, zone)
+ item.connect("activate", self.change_zone_connection_editor, connection, connection_name, zone)
self.left_menu.append(item)
if zone == "":
self.bindingsStore.append(
self.connectionsIter,
[ "%s (%s)\n<small>%s</small>" % (
- connection, ",".join(_interfaces),
+ connection_name, ",".join(_interfaces),
_("Default Zone: %s") % self.default_zone),
connection, zone ])
else:
self.bindingsStore.append(
self.connectionsIter,
[ "%s (%s)\n<small>%s</small>" % (
- connection, ",".join(_interfaces),
+ connection_name, ",".join(_interfaces),
_("Zone: %s") % zone),
connection, zone ])
@@ -2683,7 +2686,7 @@ class FirewallConfig(object):
zone = self.bindingsStore.get_value(iter, 2)
if self.bindingsStore.get_value(parent_iter, 0) == _("Connections"):
- self.change_zone_connection_editor(None, item, zone)
+ self.change_zone_connection_editor(None, item, self.connections_name[item], zone)
elif self.bindingsStore.get_value(parent_iter, 0) == _("Interfaces"):
self.change_zone_interface_editor(None, item, zone)
elif self.bindingsStore.get_value(parent_iter, 0) == _("Sources"):
@@ -3894,9 +3897,10 @@ class FirewallConfig(object):
interface = self.interfaceStore.get_value(iter, 0)
if interface in self.connections:
connection = self.connections[interface]
+ connection_name = self.connections_name[connection]
if selected_zone == self.default_zone:
selected_zone = nm_get_zone_of_connection(connection)
- editor = ZoneConnectionEditor(self.fw, connection, selected_zone)
+ editor = ZoneConnectionEditor(self.fw, connection, connection_name, selected_zone)
editor.set_icon(self.icon)
editor.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
editor.set_transient_for(self.mainWindow)
@@ -3905,9 +3909,9 @@ class FirewallConfig(object):
result = editor.run()
except Exception:
text = _("Failed to set zone {zone} "
- "for connection {connection}")
+ "for connection {connection_name}")
self._warning(text.format(zone=editor.get_zone(),
- connection=editor.connection))
+ connection_name=editor.connection_name))
editor.hide()
else:
self.add_edit_interface(False)
@@ -8115,11 +8119,12 @@ class ZoneInterfaceEditor(Gtk.Dialog):
self.fw.changeZoneOfInterface(self.get_zone(), self.interface)
class ZoneConnectionEditor(ZoneInterfaceEditor):
- def __init__(self, fw, connection, zone):
+ def __init__(self, fw, connection, connection_name, zone):
self.fw = fw
self.connection = connection
+ self.connection_name = connection_name
self.zone = None
- self.title = _("Select zone for connection '%s'") % self.connection
+ self.title = _("Select zone for connection '%s'") % self.connection_name
Gtk.Dialog.__init__(self, self.title)
self.create_ui(zone)
diff --git a/src/firewall/core/fw_nm.py b/src/firewall/core/fw_nm.py
index 76901cee2adf..d21cc25feb8b 100644
--- a/src/firewall/core/fw_nm.py
+++ b/src/firewall/core/fw_nm.py
@@ -73,7 +73,7 @@ def nm_get_zone_of_connection(connection):
"""
check_nm_imported()
- con = nm_get_client().get_connection_by_id(connection)
+ con = nm_get_client().get_connection_by_uuid(connection)
if con is None:
return False
@@ -94,7 +94,7 @@ def nm_set_zone_of_connection(zone, connection):
"""
check_nm_imported()
- con = nm_get_client().get_connection_by_id(connection)
+ con = nm_get_client().get_connection_by_uuid(connection)
if con is None:
return False
@@ -107,14 +107,14 @@ def nm_set_zone_of_connection(zone, connection):
setting_con.set_property("zone", zone)
return con.commit_changes(True, None)
-def nm_get_connections(connections, connections_uuid):
+def nm_get_connections(connections, connections_name):
"""Get active connections from NM
@param connections return dict
- @param connections_uuid return dict
+ @param connections_name return dict
"""
connections.clear()
- connections_uuid.clear()
+ connections_name.clear()
check_nm_imported()
@@ -129,9 +129,9 @@ def nm_get_connections(connections, connections_uuid):
uuid = active_con.get_uuid()
devices = active_con.get_devices()
- connections_uuid[name] = uuid
+ connections_name[uuid] = name
for dev in devices:
- connections[dev.get_iface()] = name
+ connections[dev.get_iface()] = uuid
def nm_get_connection_of_interface(interface):
"""Get connection from NM that is using the interface
@@ -148,7 +148,7 @@ def nm_get_connection_of_interface(interface):
if active_con is None:
return None
- return active_con.get_id()
+ return active_con.get_uuid()
def nm_get_bus_name():
if not _nm_imported:
--
2.16.3

40
SOURCES/0002-fw-If-direct-rules-fail-to-apply-add-a-Direct-label-.patch

@ -0,0 +1,40 @@
From efdecad74ac18d93b62a6f9ba3792904bb976b3b Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Fri, 17 Aug 2018 13:26:18 -0400
Subject: [PATCH 2/2] fw: If direct rules fail to apply add a "Direct" label to
error msg

Since they're free form it's easy to write a bad rule. This will at
least let user know where to look.

(cherry picked from commit db2d72e32579d14b5f03c6f06a9e6f38b00717cd)
---
src/firewall/core/fw.py | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
index 9079f1bbc6a4..21f5fc680c10 100644
--- a/src/firewall/core/fw.py
+++ b/src/firewall/core/fw.py
@@ -440,9 +440,15 @@ class Firewall(object):
log.debug1("Applying direct chains rules and passthrough rules")
self.direct.apply_direct(transaction)
- # Execute transaction
- transaction.execute(True)
- transaction.clear()
+ # since direct rules are easy to make syntax errors lets highlight
+ # the cause if the transaction fails.
+ try:
+ transaction.execute(True)
+ transaction.clear()
+ except FirewallError as e:
+ raise FirewallError(e.code, "Direct: %s" % (e.msg if e.msg else ""))
+ except Exception:
+ raise
del transaction
--
2.18.0

45
SOURCES/0002-fw-on-restart-set-policy-from-same-function.patch

@ -0,0 +1,45 @@
From aac434a339ec9d261bdba70eaf649bcd8820af51 Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Mon, 13 Aug 2018 16:02:11 -0400
Subject: [PATCH 2/4] fw: on restart set policy from same function

Toggle the DROP/ACCEPT policy from the same function. Doing it in
various areas is error prone.

(cherry picked from commit d3acaac62106b10945c7ac400140b5d0f2c4264d)
---
src/firewall/core/fw.py | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
index e99201d0363d..1ff36f18cd99 100644
--- a/src/firewall/core/fw.py
+++ b/src/firewall/core/fw.py
@@ -391,14 +391,11 @@ class Firewall(object):
# Start transaction
transaction = FirewallTransaction(self)
- if reload:
- self.set_policy("DROP", use_transaction=transaction)
-
# flush rules
self.flush(use_transaction=transaction)
# If modules need to be unloaded in complete reload or if there are
- # ipsets to get applied, limit the transaction to set_policy and flush.
+ # ipsets to get applied, limit the transaction to flush.
#
# Future optimization for the ipset case in reload: The transaction
# only needs to be split here if there are conflicting ipset types in
@@ -919,6 +916,8 @@ class Firewall(object):
# stop
self.cleanup()
+ self.set_policy("DROP")
+
# start
self._start(reload=True, complete_reload=stop)
--
2.18.0

68
SOURCES/0003-firewall-offline-cmd-add-check-config-option.patch

@ -0,0 +1,68 @@
From 9b8de9ce33e671a89ea8fd0b6e9c391c0b779726 Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Wed, 23 May 2018 14:35:10 -0400
Subject: [PATCH 3/5] firewall-offline-cmd: add --check-config option

(cherry picked from commit 749e64b74cff231585667417b37ff4f60af65dc0)
---
src/firewall-offline-cmd | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/firewall-offline-cmd b/src/firewall-offline-cmd
index 7f7c10739f77..13ecfadf4080 100755
--- a/src/firewall-offline-cmd
+++ b/src/firewall-offline-cmd
@@ -35,6 +35,7 @@ from firewall.errors import FirewallError
from firewall import config
from firewall.core.fw_test import Firewall_test
from firewall.functions import joinArgs, splitArgs
+from firewall.core.io.functions import check_config
from firewall.core.io.zone import zone_reader
from firewall.core.io.service import service_reader
from firewall.core.io.ipset import ipset_reader
@@ -62,6 +63,7 @@ General Options
-q, --quiet Do not print status messages
--system-config Path to firewalld system configuration
--default-config Path to firewalld default configuration
+ --check-config Check system and default configuration
Lokkit Compatibility Options
--migrate-system-config-firewall=<file>
@@ -532,6 +534,7 @@ parser_group_lokkit.add_argument("--block-icmp", metavar="<icmptype>", action='a
parser.add_argument("--system-config", metavar="path")
parser.add_argument("--default-config", metavar="path")
+parser.add_argument("--check-config", action="store_true")
parser_group_standalone = parser.add_mutually_exclusive_group()
parser_group_standalone.add_argument("-h", "--help",
@@ -970,7 +973,8 @@ cmd.set_verbose(a.verbose)
if not (options_standalone or options_ipset or \
options_lokkit or \
options_icmptype or options_service or options_helper or \
- options_permanent or options_direct or options_desc_xml_file):
+ options_permanent or options_direct or options_desc_xml_file or \
+ a.check_config):
cmd.fail(parser.format_usage() + "No option specified.")
if options_lokkit and (options_standalone or \
@@ -1035,6 +1039,16 @@ if a.system_config:
config.set_system_config_paths(a.system_config)
if a.default_config:
config.set_default_config_paths(a.default_config)
+if a.check_config:
+ try:
+ fw = Firewall_test()
+ fw.start()
+ check_config(fw)
+ except FirewallError as error:
+ cmd.print_and_exit("Configuration error: %s" % error, error.code)
+ except Exception as msg:
+ cmd.fail("Configuration error: %s" % msg)
+ sys.exit(0)
zone = a.zone
fw = Firewall_test()
--
2.16.3

37
SOURCES/0003-firewall.core.fw_nm-ignore-generated-connections.patch

@ -0,0 +1,37 @@
From a3e6d2c48a1535b56bc5f28094818f10f93bf352 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 16 Jul 2018 17:43:25 +0200
Subject: [PATCH 3/3] firewall.core.fw_nm: ignore generated connections

If a connection is generated by NetworkManager, changing it persists it and
makes the device managed by NetworkManager.

(cherry picked from commit a102dde5d9430d503767cbface3e3b610134bdb6)
---
src/firewall/core/fw_nm.py | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/src/firewall/core/fw_nm.py b/src/firewall/core/fw_nm.py
index d21cc25feb8b..0ed19248a79f 100644
--- a/src/firewall/core/fw_nm.py
+++ b/src/firewall/core/fw_nm.py
@@ -148,6 +148,16 @@ def nm_get_connection_of_interface(interface):
if active_con is None:
return None
+ try:
+ con = active_con.get_connection()
+ if con.get_flags() & NM.SettingsConnectionFlags.NM_GENERATED:
+ return None
+ except AttributeError:
+ # Prior to NetworkManager 1.12, we can only guess
+ # that a connection was generated.
+ if con.get_unsaved():
+ return None
+
return active_con.get_uuid()
def nm_get_bus_name():
--
2.16.3

244
SOURCES/0003-fw-if-failure-occurs-during-startup-set-state-to-FAI.patch

@ -0,0 +1,244 @@
From 9e4bf24e1e0a5d54398d2220f0a5217eff0704a7 Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Mon, 13 Aug 2018 16:53:46 -0400
Subject: [PATCH 3/4] fw: if failure occurs during startup set state to FAILED

Previously if a failure occurred at startup firewalld would get stuck in
INIT state and the policy would remain as "DROP". This commit changes
that behavior and introduces a new state "FAILED", which means a failure
occurred and we're running in a failed state. Policy is set to "ACCEPT"
so as to hopefully prevent locking out an admin.

(cherry picked from commit f475bd2293b7ba01ad4b56b68bef1b61d01526f0)
---
doc/xml/firewall-cmd.xml.in | 2 +-
doc/xml/firewalld.dbus.xml | 2 +-
src/firewall-cmd | 2 +
src/firewall/core/fw.py | 131 +++++++++++++++-------------
src/firewall/errors.py | 1 +
src/tests/regression/rhbz1498923.at | 8 +-
6 files changed, 83 insertions(+), 63 deletions(-)

diff --git a/doc/xml/firewall-cmd.xml.in b/doc/xml/firewall-cmd.xml.in
index 32c89591db86..c2606553e549 100644
--- a/doc/xml/firewall-cmd.xml.in
+++ b/doc/xml/firewall-cmd.xml.in
@@ -118,7 +118,7 @@
<term><option>--state</option></term>
<listitem>
<para>
- Check whether the firewalld daemon is active (i.e. running). Returns an exit code 0 if it is active, <replaceable>NOT_RUNNING</replaceable> otherwise (see <xref linkend="exit_codes"/>). This will also print the state to <replaceable>STDOUT</replaceable>.
+ Check whether the firewalld daemon is active (i.e. running). Returns an exit code 0 if it is active, <replaceable>RUNNING_BUT_FAILED</replaceable> if failure occurred on startup, <replaceable>NOT_RUNNING</replaceable> otherwise. See <xref linkend="exit_codes"/>. This will also print the state to <replaceable>STDOUT</replaceable>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml
index acdbb5fd6e00..ec82d4cad077 100644
--- a/doc/xml/firewalld.dbus.xml
+++ b/doc/xml/firewalld.dbus.xml
@@ -488,7 +488,7 @@
</varlistentry>
<varlistentry id="FirewallD1.Properties.state">
<term><parameter>state</parameter> - s - (ro)</term>
- <listitem><para>firewalld state. This can be either <literal>INIT</literal> or <literal>RUNNING</literal>. In <literal>INIT</literal> state, firewalld is starting up and initializing.</para></listitem>
+ <listitem><para>firewalld state. This can be either <literal>INIT</literal>, <literal>FAILED</literal>, or <literal>RUNNING</literal>. In <literal>INIT</literal> state, firewalld is starting up and initializing. In <literal>FAILED</literal> state, firewalld completely started but experienced a failure.</para></listitem>
</varlistentry>
<varlistentry id="FirewallD1.Properties.version">
<term><parameter>version</parameter> - s - (ro)</term>
diff --git a/src/firewall-cmd b/src/firewall-cmd
index b80115564e1b..12e18bb88a54 100755
--- a/src/firewall-cmd
+++ b/src/firewall-cmd
@@ -2022,6 +2022,8 @@ elif a.state:
state = fw.get_property("state")
if state == "RUNNING":
cmd.print_and_exit ("running")
+ elif state == "FAILED":
+ cmd.print_and_exit("failed", errors.RUNNING_BUT_FAILED)
else:
cmd.print_and_exit ("not running", errors.NOT_RUNNING)
elif a.get_log_denied:
diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
index 1ff36f18cd99..5b706d6d3e80 100644
--- a/src/firewall/core/fw.py
+++ b/src/firewall/core/fw.py
@@ -451,11 +451,16 @@ class Firewall(object):
tm2 = time.time()
log.debug2("Flushing and applying took %f seconds" % (tm2 - tm1))
- self._state = "RUNNING"
-
def start(self):
- self._start()
- self.set_policy("ACCEPT")
+ try:
+ self._start()
+ except Exception:
+ self._state = "FAILED"
+ self.set_policy("ACCEPT")
+ raise
+ else:
+ self._state = "RUNNING"
+ self.set_policy("ACCEPT")
def _loader(self, path, reader_type, combine=False):
# combine: several zone files are getting combined into one obj
@@ -905,64 +910,70 @@ class Firewall(object):
def reload(self, stop=False):
_panic = self._panic
- # save zone interfaces
- _zone_interfaces = { }
- for zone in self.zone.get_zones():
- _zone_interfaces[zone] = self.zone.get_settings(zone)["interfaces"]
- # save direct config
- _direct_config = self.direct.get_runtime_config()
- _old_dz = self.get_default_zone()
-
- # stop
- self.cleanup()
-
- self.set_policy("DROP")
-
- # start
- self._start(reload=True, complete_reload=stop)
-
- # handle interfaces in the default zone and move them to the new
- # default zone if it changed
- _new_dz = self.get_default_zone()
- if _new_dz != _old_dz:
- # if_new_dz has been introduced with the reload, we need to add it
- # https://github.com/firewalld/firewalld/issues/53
- if _new_dz not in _zone_interfaces:
- _zone_interfaces[_new_dz] = { }
- # default zone changed. Move interfaces from old default zone to
- # the new one.
- for iface, settings in list(_zone_interfaces[_old_dz].items()):
- if settings["__default__"]:
- # move only those that were added to default zone
- # (not those that were added to specific zone same as
- # default)
- _zone_interfaces[_new_dz][iface] = \
- _zone_interfaces[_old_dz][iface]
- del _zone_interfaces[_old_dz][iface]
-
- # add interfaces to zones again
- for zone in self.zone.get_zones():
- if zone in _zone_interfaces:
- self.zone.set_settings(zone, { "interfaces":
- _zone_interfaces[zone] })
- del _zone_interfaces[zone]
+ try:
+ # save zone interfaces
+ _zone_interfaces = { }
+ for zone in self.zone.get_zones():
+ _zone_interfaces[zone] = self.zone.get_settings(zone)["interfaces"]
+ # save direct config
+ _direct_config = self.direct.get_runtime_config()
+ _old_dz = self.get_default_zone()
+
+ # stop
+ self.cleanup()
+
+ self.set_policy("DROP")
+
+ self._start(reload=True, complete_reload=stop)
+
+ # handle interfaces in the default zone and move them to the new
+ # default zone if it changed
+ _new_dz = self.get_default_zone()
+ if _new_dz != _old_dz:
+ # if_new_dz has been introduced with the reload, we need to add it
+ # https://github.com/firewalld/firewalld/issues/53
+ if _new_dz not in _zone_interfaces:
+ _zone_interfaces[_new_dz] = { }
+ # default zone changed. Move interfaces from old default zone to
+ # the new one.
+ for iface, settings in list(_zone_interfaces[_old_dz].items()):
+ if settings["__default__"]:
+ # move only those that were added to default zone
+ # (not those that were added to specific zone same as
+ # default)
+ _zone_interfaces[_new_dz][iface] = \
+ _zone_interfaces[_old_dz][iface]
+ del _zone_interfaces[_old_dz][iface]
+
+ # add interfaces to zones again
+ for zone in self.zone.get_zones():
+ if zone in _zone_interfaces:
+ self.zone.set_settings(zone, { "interfaces":
+ _zone_interfaces[zone] })
+ del _zone_interfaces[zone]
+ else:
+ log.info1("New zone '%s'.", zone)
+ if len(_zone_interfaces) > 0:
+ for zone in list(_zone_interfaces.keys()):
+ log.info1("Lost zone '%s', zone interfaces dropped.", zone)
+ del _zone_interfaces[zone]
+ del _zone_interfaces
+
+ # restore direct config
+ self.direct.set_config(_direct_config)
+
+ # enable panic mode again if it has been enabled before or set policy
+ # to ACCEPT
+ if _panic:
+ self.enable_panic_mode()
else:
- log.info1("New zone '%s'.", zone)
- if len(_zone_interfaces) > 0:
- for zone in list(_zone_interfaces.keys()):
- log.info1("Lost zone '%s', zone interfaces dropped.", zone)
- del _zone_interfaces[zone]
- del _zone_interfaces
-
- # restore direct config
- self.direct.set_config(_direct_config)
-
- # enable panic mode again if it has been enabled before or set policy
- # to ACCEPT
- if _panic:
- self.enable_panic_mode()
- else:
+ self.set_policy("ACCEPT")
+
+ self._state = "RUNNING"
+ except Exception:
+ self._state = "FAILED"
self.set_policy("ACCEPT")
+ raise
# STATE
diff --git a/src/firewall/errors.py b/src/firewall/errors.py
index 1cd604884c99..63d007191ffa 100644
--- a/src/firewall/errors.py
+++ b/src/firewall/errors.py
@@ -97,6 +97,7 @@ MISSING_NAME = 205
MISSING_SETTING = 206
MISSING_FAMILY = 207
+RUNNING_BUT_FAILED = 251
NOT_RUNNING = 252
NOT_AUTHORIZED = 253
UNKNOWN_ERROR = 254
diff --git a/src/tests/regression/rhbz1498923.at b/src/tests/regression/rhbz1498923.at
index 505a523d5cc4..bb0d841db2a7 100644
--- a/src/tests/regression/rhbz1498923.at
+++ b/src/tests/regression/rhbz1498923.at
@@ -1,5 +1,11 @@
FWD_START_TEST([invalid direct rule causes reload error])
FWD_CHECK([-q --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 8080 -j ACCEPT])
FWD_CHECK([-q --permanent --direct --add-rule ipv4 filter INPUT 1 --a-bogus-flag])
-FWD_RELOAD(13, [ignore], [ignore])
+FWD_RELOAD(13, [ignore], [ignore], 251)
+FWD_CHECK([--state], 251, [ignore], [failed
+])
+
+dnl now remove the bad rule and reload successfully
+FWD_CHECK([-q --permanent --direct --remove-rule ipv4 filter INPUT 1 --a-bogus-flag])
+FWD_RELOAD
FWD_END_TEST([-e '/.*a-bogus-flag.*/d'])
--
2.18.0

122
SOURCES/0004-firewall-cmd-add-check-config-option.patch

@ -0,0 +1,122 @@
From c37c84f095d820cbd137a285e263075472934502 Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Thu, 31 May 2018 14:15:57 -0400
Subject: [PATCH 4/5] firewall-cmd: add --check-config option

Fixes: rhbz 1477771
(cherry picked from commit b071536beb7ef2c91adb79c7769a265fc74ab15f)
---
doc/xml/firewalld.dbus.xml | 11 +++++++++++
src/firewall-cmd | 6 +++++-
src/firewall/client.py | 5 +++++
src/firewall/server/firewalld.py | 11 +++++++++++
4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml
index f02edb173f6e..acdbb5fd6e00 100644
--- a/doc/xml/firewalld.dbus.xml
+++ b/doc/xml/firewalld.dbus.xml
@@ -347,6 +347,17 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry id="FirewallD1.Methods.checkPermanentConfig">
+ <term><methodname>checkPermanentConfig</methodname>() &rarr; Nothing</term>
+ <listitem>
+ <para>
+ Run checks on the permanent configuration. This is most useful if changes were made manually to configuration files.
+ </para>
+ <para>
+ Possible errors: any
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry id="FirewallD1.Methods.setDefaultZone">
<term><methodname>setDefaultZone</methodname>(s: <parameter>zone</parameter>) &rarr; Nothing</term>
<listitem>
diff --git a/src/firewall-cmd b/src/firewall-cmd
index 1a864b32e819..b80115564e1b 100755
--- a/src/firewall-cmd
+++ b/src/firewall-cmd
@@ -59,6 +59,7 @@ Status Options
--complete-reload Reload firewall and lose state information
--runtime-to-permanent
Create permanent from runtime configuration
+ --check-config Check permanent configuration for errors
Log Denied Options
--get-log-denied Print the log denied value
@@ -484,6 +485,7 @@ parser_group_standalone.add_argument("--reload", action="store_true")
parser_group_standalone.add_argument("--complete-reload", action="store_true")
parser_group_standalone.add_argument("--runtime-to-permanent",
action="store_true")
+parser_group_standalone.add_argument("--check-config", action="store_true")
parser_group_standalone.add_argument("--get-ipset-types", action="store_true")
parser_group_standalone.add_argument("--get-log-denied", action="store_true")
parser_group_standalone.add_argument("--set-log-denied", metavar="<value>")
@@ -750,7 +752,7 @@ options_standalone = a.help or a.version or \
a.get_default_zone or a.set_default_zone or \
a.get_active_zones or a.get_ipset_types or \
a.get_log_denied or a.set_log_denied or \
- a.get_automatic_helpers or a.set_automatic_helpers
+ a.get_automatic_helpers or a.set_automatic_helpers or a.check_config
options_desc_xml_file = a.set_description or a.get_description or \
a.set_short or a.get_short
@@ -2039,6 +2041,8 @@ elif a.complete_reload:
fw.complete_reload()
elif a.runtime_to_permanent:
fw.runtimeToPermanent()
+elif a.check_config:
+ fw.checkPermanentConfig()
elif a.direct:
if a.passthrough:
if len(a.passthrough) < 2:
diff --git a/src/firewall/client.py b/src/firewall/client.py
index f90bbd78eb73..da45ceb5b964 100644
--- a/src/firewall/client.py
+++ b/src/firewall/client.py
@@ -2760,6 +2760,11 @@ class FirewallClient(object):
def runtimeToPermanent(self):
self.fw.runtimeToPermanent()
+ @slip.dbus.polkit.enable_proxy
+ @handle_exceptions
+ def checkPermanentConfig(self):
+ self.fw.checkPermanentConfig()
+
@slip.dbus.polkit.enable_proxy
@handle_exceptions
def get_property(self, prop):
diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py
index fc7422f12261..2cecc4771cb0 100644
--- a/src/firewall/server/firewalld.py
+++ b/src/firewall/server/firewalld.py
@@ -42,6 +42,7 @@ from firewall.dbus_utils import dbus_to_python, \
command_of_sender, context_of_sender, uid_of_sender, user_of_uid, \
dbus_introspection_prepare_properties, \
dbus_introspection_add_properties
+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
@@ -336,6 +337,16 @@ class FirewallD(slip.dbus.service.Object):
def Reloaded(self):
log.debug1("Reloaded()")
+ @slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
+ @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='',
+ out_signature='')
+ @dbus_handle_exceptions
+ def checkPermanentConfig(self, sender=None): # pylint: disable=W0613
+ """Check permanent configuration
+ """
+ log.debug1("checkPermanentConfig()")
+ check_config(self.fw)
+
# runtime to permanent
@slip.dbus.polkit.require_auth(config.dbus.PK_ACTION_CONFIG)
--
2.16.3

416
SOURCES/0005-tests-firewall-cmd-exercise-check-config.patch

@ -0,0 +1,416 @@
From b388398d8c4b9859fba9b45371239bd2e5d6bfd4 Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Thu, 24 May 2018 16:30:41 -0400
Subject: [PATCH 5/5] tests/firewall-cmd: exercise --check-config

This exercises the --check-config option for both firewall-cmd and
firewall-offline-cmd.

We also remove the explicit check in config/Makefile as it's now part of
the normal testsuite.

(cherry picked from commit c2bd43e71018ca4e43141ca93fab352e344f4a30)
---
src/tests/firewall-cmd.at | 374 ++++++++++++++++++++++++++++++++++++++++++++++
src/tests/functions.at | 3 +
2 files changed, 377 insertions(+)

diff --git a/src/tests/firewall-cmd.at b/src/tests/firewall-cmd.at
index 7364e9770d27..92cade844b9e 100644
--- a/src/tests/firewall-cmd.at
+++ b/src/tests/firewall-cmd.at
@@ -840,3 +840,377 @@ FWD_END_TEST([-e '/ERROR: INVALID_RULE:/d' dnl
-e '/ERROR: INVALID_LOG_LEVEL: eror/d' dnl
-e '/ERROR: MISSING_FAMILY/d' dnl
-e '/ERROR: INVALID_LIMIT: 1\/2m/d'])
+
+FWD_START_TEST([config validation])
+ dnl default config
+ FWD_CHECK([--check-config], 0, ignore)
+
+ dnl The rest of these are negative test cases.
+
+ dnl firewalld.conf
+ AT_CHECK([cp ./firewalld.conf ./firewalld.conf.orig])
+ AT_CHECK([echo "SomeBogusField=yes" >> ./firewalld.conf])
+ FWD_CHECK([--check-config], 0, ignore, [dnl
+m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [dnl
+ERROR: Invalid option: 'SomeBogusField=yes'
+ERROR: Invalid option: 'SomeBogusField=yes'
+])])
+ AT_CHECK([cp ./firewalld.conf.orig ./firewalld.conf])
+
+ dnl direct
+ AT_DATA([./direct.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<direct>
+<chain table="filter" ipv="ipv7" chain="foobar"/>
+</direct>
+])
+ FWD_CHECK([--check-config], 111, ignore, ignore)
+
+ AT_DATA([./direct.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<direct>
+<rule />
+</direct>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+ AT_CHECK([rm ./direct.xml])
+
+ dnl lockdown-whitelist
+ AT_DATA([./lockdown-whitelist.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<whitelist>
+ <user uid="666"/>
+</whitelist>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./lockdown-whitelist.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<whitelist>
+ <uid id="666"/>
+</whitelist>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./lockdown-whitelist.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<whitelist>
+ <group name="foobar" />
+</whitelist>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+ AT_CHECK([rm ./lockdown-whitelist.xml])
+
+ dnl ipset
+ AT_CHECK([mkdir -p ./ipsets])
+ AT_DATA([./ipsets/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<ipset type="hash:mac">
+ <entry>12:34:56:78:90</entry>
+</ipset>
+])
+ FWD_CHECK([--check-config], 0, ignore, [dnl
+m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [dnl
+WARNING: INVALID_ENTRY: invalid mac address '12:34:56:78:90' in '12:34:56:78:90', ignoring.
+WARNING: INVALID_ENTRY: invalid mac address '12:34:56:78:90' in '12:34:56:78:90', ignoring.
+])])
+
+ AT_DATA([./ipsets/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<ipset type="hash:mac">
+ <entry bogus_attr="bogus">12:34:56:78:90:ab</entry>
+</ipset>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./ipsets/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<ipset type="hash:ip,bogus">
+</ipset>
+])
+ FWD_CHECK([--check-config], 119, ignore, ignore)
+ AT_CHECK([rm ./ipsets/foobar.xml])
+
+ dnl helpers
+ AT_CHECK([mkdir -p ./helpers])
+ AT_DATA([./helpers/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<helper>
+</helper>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./helpers/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<helper family="ipv7" module="nf_conntrack_ftp">
+</helper>
+])
+ FWD_CHECK([--check-config], 111, ignore, ignore)
+
+ AT_DATA([./helpers/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<helper family="ipv6" module="nf_conntrack_ftp">
+<port protocol="aoeui" port="666" />
+</helper>
+])
+ FWD_CHECK([--check-config], 103, ignore, ignore)
+ AT_CHECK([rm ./helpers/foobar.xml])
+
+ dnl icmptype
+ AT_CHECK([mkdir -p ./icmptypes])
+ AT_DATA([./icmptypes/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<bad_element />
+<icmptype>
+</icmptype>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./icmptypes/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<icmptype>
+<destination unexpected_attr="foobar" />
+</icmptype>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+ AT_CHECK([rm ./icmptypes/foobar.xml])
+
+ dnl services
+ AT_CHECK([mkdir -p ./services])
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<protocol value="aoeui" />
+</service>
+])
+ FWD_CHECK([--check-config], 103, ignore, ignore)
+
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<protocol bad_attr="foo" />
+</service>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<bad_element />
+</service>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<module module="bad_attr" />
+</service>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<port protocol="aoeu" port="666" />
+</service>
+])
+ FWD_CHECK([--check-config], 103, ignore, ignore)
+
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<port protocol="tcp" port="ssssssh" />
+</service>
+])
+ FWD_CHECK([--check-config], 102, ignore, ignore)
+
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<port protocol="tcp" port="22" />
+<source-port protocol="tcp" port="sssssh" />
+</service>
+])
+ FWD_CHECK([--check-config], 102, ignore, ignore)
+
+ AT_DATA([./services/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+<destination ipv4="224.0.0.1" ipv7="1234" />
+</service>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+ AT_CHECK([rm ./services/foobar.xml])
+
+ dnl zones
+ AT_CHECK([mkdir -p ./zones])
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+])
+ FWD_CHECK([--check-config], 112, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<service name="bogus_service_name" />
+</zone>
+])
+ FWD_CHECK([--check-config], 101, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<port protocol="ipv4" />
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<protocol value="thisdoesnotexist" />
+</zone>
+])
+ FWD_CHECK([--check-config], 103, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<icmp-block invalid_attr=""/>
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<icmp-type />
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<masquerade value="true" />
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<forward-port port="666" />
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<forward-port protocol="sctppp" />
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<source-port port="-1" />
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<interface />
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<source />
+</zone>
+])
+ FWD_CHECK([--check-config], 0, ignore, [dnl
+m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [dnl
+WARNING: Invalid source: No address no ipset.
+WARNING: Invalid source: No address no ipset.
+])])
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<rule>
+<source address="10.0.0.1/24" />
+<limit />
+</rule>
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<rule family="ipv4">
+<source address="10.0.0.1/24" />
+<accept>
+<limit value="none" />
+</accept>
+</rule>
+</zone>
+])
+ FWD_CHECK([--check-config], 0, ignore, [dnl
+m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [dnl
+WARNING: INVALID_LIMIT: none: rule family="ipv4" source address="10.0.0.1/24" accept limit value="none"
+WARNING: INVALID_LIMIT: none: rule family="ipv4" source address="10.0.0.1/24" accept limit value="none"
+])])
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<rule>
+<source address="10.0.0.1/24" />
+<log level="super_critical" />
+</rule>
+</zone>
+])
+ FWD_CHECK([--check-config], 0, ignore, [dnl
+m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [dnl
+WARNING: Invalid rule: Invalid log level
+WARNING: Invalid rule: Invalid log level
+])])
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<rule family="ipv4">
+<source address="10.0.0.1/24" />
+<audit prefix="foobar" />
+</rule>
+</zone>
+])
+ FWD_CHECK([--check-config], 28, ignore, ignore)
+
+ AT_DATA([./zones/foobar.xml], [dnl
+<?xml version="1.0" encoding="utf-8"?>
+<zone>
+<rule family="ipv6">
+<source address="10.0.0.1/24" />
+<accept />
+</rule>
+</zone>
+])
+ FWD_CHECK([--check-config], 0, ignore, [dnl
+m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [dnl
+WARNING: INVALID_ADDR: 10.0.0.1/24: rule family="ipv6" source address="10.0.0.1/24" accept
+WARNING: INVALID_ADDR: 10.0.0.1/24: rule family="ipv6" source address="10.0.0.1/24" accept
+])])
+ AT_CHECK([rm ./zones/foobar.xml])
+
+FWD_END_TEST([-e '/ERROR:/d'dnl
+ -e '/WARNING:/d'])
diff --git a/src/tests/functions.at b/src/tests/functions.at
index 7bd66d5c74fe..d9b1ce401bb0 100644
--- a/src/tests/functions.at
+++ b/src/tests/functions.at
@@ -122,6 +122,9 @@ m4_define([FWD_CHECK], [
m4_if(-1, m4_index([$1], [-default-zone]), [], [
m4_define([FWD_CHECK_RUN_FIREWALL_OFFLINE_CMD])
])
+ m4_if(-1, m4_index([$1], [--check-config]), [], [
+ m4_define([FWD_CHECK_RUN_FIREWALL_OFFLINE_CMD])
+ ])
], [
m4_if(-1, m4_index([$1], [--timeout]), [
m4_define([FWD_CHECK_RUN_FIREWALL_OFFLINE_CMD])
--
2.16.3

46
SOURCES/firewalld-0.4.4.3-exclude_firewallctl_rhbz#1374799.patch

@ -0,0 +1,46 @@
diff -up firewalld-0.4.4.3/doc/man/man1/Makefile.am.exclude_firewallctl_rhbz#1374799 firewalld-0.4.4.3/doc/man/man1/Makefile.am
--- firewalld-0.4.4.3/doc/man/man1/Makefile.am.exclude_firewallctl_rhbz#1374799 2016-12-16 13:35:59.000000000 +0100
+++ firewalld-0.4.4.3/doc/man/man1/Makefile.am 2017-02-08 19:20:18.109073530 +0100
@@ -1,3 +1,8 @@
EXTRA_DIST = $(man_MANS)
-man_MANS = firewall*.1
+man_MANS = \
+ firewall-applet.1 \
+ firewall-cmd.1 \
+ firewall-config.1 \
+ firewalld.1 \
+ firewall-offline-cmd.1
diff -up firewalld-0.4.4.3/doc/xml/Makefile.am.exclude_firewallctl_rhbz#1374799 firewalld-0.4.4.3/doc/xml/Makefile.am
--- firewalld-0.4.4.3/doc/xml/Makefile.am.exclude_firewallctl_rhbz#1374799 2016-10-31 10:19:14.000000000 +0100
+++ firewalld-0.4.4.3/doc/xml/Makefile.am 2017-02-08 19:16:45.904176658 +0100
@@ -11,7 +11,6 @@ man1_MANS = \
../man/man1/firewall-applet.1 \
../man/man1/firewall-cmd.1 \
../man/man1/firewall-config.1 \
- ../man/man1/firewallctl.1 \
../man/man1/firewalld.1 \
../man/man1/firewall-offline-cmd.1
diff -up firewalld-0.4.4.3/doc/xml/seealso.xml.exclude_firewallctl_rhbz#1374799 firewalld-0.4.4.3/doc/xml/seealso.xml
--- firewalld-0.4.4.3/doc/xml/seealso.xml.exclude_firewallctl_rhbz#1374799 2016-10-31 10:19:14.000000000 +0100
+++ firewalld-0.4.4.3/doc/xml/seealso.xml 2017-02-08 19:16:45.904176658 +0100
@@ -29,7 +29,6 @@
<member><citerefentry><refentrytitle>firewalld</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>firewall-cmd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>firewall-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
- <member><citerefentry><refentrytitle>firewallctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>firewalld.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>firewalld.direct</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>firewalld.dbus</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
diff -up firewalld-0.4.4.3/src/Makefile.am.exclude_firewallctl_rhbz#1374799 firewalld-0.4.4.3/src/Makefile.am
--- firewalld-0.4.4.3/src/Makefile.am.exclude_firewallctl_rhbz#1374799 2017-02-08 17:51:00.000000000 +0100
+++ firewalld-0.4.4.3/src/Makefile.am 2017-02-08 19:16:45.904176658 +0100
@@ -1,6 +1,6 @@
SUBDIRS = icons
-dist_bin_SCRIPTS = firewall-applet firewall-cmd firewall-offline-cmd firewall-config firewallctl
+dist_bin_SCRIPTS = firewall-applet firewall-cmd firewall-offline-cmd firewall-config
dist_sbin_SCRIPTS = firewalld
gladedir = $(pkgdatadir)

449
SOURCES/firewalld-0.4.4.3-qt4_applet.patch

@ -0,0 +1,449 @@
diff -up firewalld-0.4.4.3/src/firewall-applet.qt4_applet firewalld-0.4.4.3/src/firewall-applet
--- firewalld-0.4.4.3/src/firewall-applet.qt4_applet 2017-01-26 13:07:25.000000000 +0100
+++ firewalld-0.4.4.3/src/firewall-applet 2017-02-08 19:13:03.196185899 +0100
@@ -21,14 +21,14 @@
#
import sys
-from PyQt5 import QtGui, QtCore, QtWidgets
+from PyQt4 import QtGui, QtCore
import gi
gi.require_version('Notify', '0.7')
from gi.repository import Notify
import os
-from dbus.mainloop.pyqt5 import DBusQtMainLoop
+from dbus.mainloop.qt import DBusQtMainLoop
import functools
from firewall.config import *
@@ -74,20 +74,21 @@ def escape(text):
return text
def fromUTF8(text):
- if PY2 and QtCore.QT_VERSION < 0x050000:
+ if PY2:
return QtCore.QString.fromUtf8(text)
- return text
+ else:
+ return text
# ZoneInterfaceEditor #########################################################
-class ZoneInterfaceEditor(QtWidgets.QDialog):
+class ZoneInterfaceEditor(QtGui.QDialog):
def __init__(self, fw, interface, zone):
self.fw = fw
self.interface = interface
self.zone = None
self.title = _("Select zone for interface '%s'") % self.interface
- QtWidgets.QDialog.__init__(self)
+ QtGui.QDialog.__init__(self)
self.create_ui(zone)
def create_ui(self, zone):
@@ -96,19 +97,19 @@ class ZoneInterfaceEditor(QtWidgets.QDia
self.resize(100, 50)
- vbox = QtWidgets.QVBoxLayout()
+ vbox = QtGui.QVBoxLayout()
vbox.setSpacing(6)
- label = QtWidgets.QLabel(fromUTF8(escape(self.title)))
+ label = QtGui.QLabel(fromUTF8(escape(self.title)))
vbox.addWidget(label)
- self.combo = QtWidgets.QComboBox()
+ self.combo = QtGui.QComboBox()
self.fill_zone_combo()
vbox.addWidget(self.combo)
- buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok
- | QtWidgets.QDialogButtonBox.Cancel)
- self.ok_button = buttonBox.button(QtWidgets.QDialogButtonBox.Ok)
+ buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok
+ | QtGui.QDialogButtonBox.Cancel)
+ self.ok_button = buttonBox.button(QtGui.QDialogButtonBox.Ok)
buttonBox.accepted.connect(self.ok)
buttonBox.rejected.connect(self.hide)
vbox.addWidget(buttonBox)
@@ -160,7 +161,7 @@ class ZoneConnectionEditor(ZoneInterface
self.zone = None
self.title = _("Select zone for connection '%s'") % self.connection
- QtWidgets.QDialog.__init__(self)
+ QtGui.QDialog.__init__(self)
self.create_ui(zone)
def ok(self):
@@ -169,7 +170,7 @@ class ZoneConnectionEditor(ZoneInterface
nm_set_zone_of_connection(self.get_zone(), self.connection)
except Exception as msg:
text = _("Failed to set zone {zone} for connection {connection}")
- QtWidgets.QMessageBox.warning(None, fromUTF8(escape(self.title)),
+ QtGui.QMessageBox.warning(None, fromUTF8(escape(self.title)),
escape(text.format(
zone=self.get_zone(),
connection=self.connection)))
@@ -184,7 +185,7 @@ class ZoneSourceEditor(ZoneInterfaceEdit
self.zone = None
self.title = _("Select zone for source '%s'") % self.source
- QtWidgets.QDialog.__init__(self)
+ QtGui.QDialog.__init__(self)
self.create_ui(zone)
def ok(self):
@@ -193,7 +194,7 @@ class ZoneSourceEditor(ZoneInterfaceEdit
# ShieldsEditor #########################################################
-class ShieldsEditor(QtWidgets.QDialog):
+class ShieldsEditor(QtGui.QDialog):
def __init__(self, fw, settings, shields_up, shields_down):
self.fw = fw
self.settings = settings
@@ -201,63 +202,63 @@ class ShieldsEditor(QtWidgets.QDialog):
self.shields_down = shields_down
self.title = _("Configure Shields Up/Down Zones")
- QtWidgets.QDialog.__init__(self)
+ QtGui.QDialog.__init__(self)
self.create_ui()
def create_ui(self):
self.setWindowTitle(fromUTF8(escape(self.title)))
self.rejected.connect(self.hide)
- vbox = QtWidgets.QVBoxLayout()
+ vbox = QtGui.QVBoxLayout()
vbox.setSpacing(6)
- label = QtWidgets.QLabel(fromUTF8(escape(
+ label = QtGui.QLabel(fromUTF8(escape(
_("Here you can select the zones used for Shields Up and "
"Shields Down."))))
label.setWordWrap(True)
vbox.addWidget(label)
- label = QtWidgets.QLabel(fromUTF8(escape(
+ label = QtGui.QLabel(fromUTF8(escape(
_("This feature is useful for people using the default zones "
"mostly. For users, that are changing zones of connections, it "
"might be of limited use."))))
label.setWordWrap(True)
vbox.addWidget(label)
- grid = QtWidgets.QGridLayout()
+ grid = QtGui.QGridLayout()
grid.setSpacing(6)
- label = QtWidgets.QLabel(fromUTF8(escape(_("Shields Up Zone:"))))
+ label = QtGui.QLabel(fromUTF8(escape(_("Shields Up Zone:"))))
label.setWordWrap(True)
grid.addWidget(label, 0, 0, 1, 1)
- self.shields_up_combo = QtWidgets.QComboBox()
+ self.shields_up_combo = QtGui.QComboBox()
#self.fill_combo(self.shields_up_combo)
#self.set_shields_up(self.shields_up)
grid.addWidget(self.shields_up_combo, 0, 1, 1, 1)
- button = QtWidgets.QPushButton(_("Reset To Default"))
+ button = QtGui.QPushButton(_("Reset To Default"))
button.clicked.connect(self.reset_shields_up)
grid.addWidget(button, 0, 2, 1, 1)
- label = QtWidgets.QLabel(fromUTF8(escape(_("Shields Down Zone:"))))
+ label = QtGui.QLabel(fromUTF8(escape(_("Shields Down Zone:"))))
label.setWordWrap(True)
grid.addWidget(label, 1, 0, 1, 1)
- self.shields_down_combo = QtWidgets.QComboBox()
+ self.shields_down_combo = QtGui.QComboBox()
#self.fill_combo(self.shields_down_combo)
#self.set_shields_down(self.shields_down)
grid.addWidget(self.shields_down_combo, 1, 1, 1, 1)
- button = QtWidgets.QPushButton(_("Reset To Default"))
+ button = QtGui.QPushButton(_("Reset To Default"))
button.clicked.connect(self.reset_shields_down)
grid.addWidget(button, 1, 2, 1, 1)
vbox.addLayout(grid)
- buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok
- | QtWidgets.QDialogButtonBox.Cancel)
- self.ok_button = buttonBox.button(QtWidgets.QDialogButtonBox.Ok)
+ buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok
+ | QtGui.QDialogButtonBox.Cancel)
+ self.ok_button = buttonBox.button(QtGui.QDialogButtonBox.Ok)
buttonBox.accepted.connect(self.ok)
buttonBox.rejected.connect(self.hide)
vbox.addWidget(buttonBox)
@@ -328,56 +329,56 @@ class ShieldsEditor(QtWidgets.QDialog):
# AboutDialog #################################################################
-class AboutDialog(QtWidgets.QDialog):
+class AboutDialog(QtGui.QDialog):
def __init__(self, name, icon, version, url, copyright, authors, license):
- QtWidgets.QDialog.__init__(self)
+ QtGui.QDialog.__init__(self)
self.setWindowIcon(icon)
self.setWindowTitle(fromUTF8(escape(_("About %s" % name))))
self.resize(500, 250)
- vbox = QtWidgets.QVBoxLayout()
+ vbox = QtGui.QVBoxLayout()
vbox.setSpacing(6)
- hbox = QtWidgets.QHBoxLayout()
+ hbox = QtGui.QHBoxLayout()
hbox.setSpacing(24)
- label = QtWidgets.QLabel()
+ label = QtGui.QLabel()
label.setPixmap(icon.pixmap(96))
label.setMinimumSize(96, 96)
label.setMaximumSize(96, 96)
hbox.addWidget(label)
- vbox2 = QtWidgets.QVBoxLayout()
+ vbox2 = QtGui.QVBoxLayout()
vbox2.setSpacing(3)
- label = QtWidgets.QLabel(name)
+ label = QtGui.QLabel(name)
font = label.font()
font.setPointSize(font.pointSize()*2)
font.setBold(True)
label.setFont(font)
vbox2.addWidget(label)
- vbox2.addWidget(QtWidgets.QLabel(version))
+ vbox2.addWidget(QtGui.QLabel(version))
- label = QtWidgets.QLabel("<a href=\"%s\">%s</a>" % (url, url))
+ label = QtGui.QLabel("<a href=\"%s\">%s</a>" % (url, url))
label.setTextFormat(QtCore.Qt.RichText)
label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction)
label.setOpenExternalLinks(True)
vbox2.addWidget(label)
- vbox2.addWidget(QtWidgets.QLabel(copyright))
+ vbox2.addWidget(QtGui.QLabel(copyright))
hbox.addLayout(vbox2)
vbox.addLayout(hbox)
- tabs = QtWidgets.QTabWidget()
+ tabs = QtGui.QTabWidget()
tabs.setStyleSheet("QTabWidget::tab { padding: 1px 1px 1px 1px; }")
- tab = QtWidgets.QWidget()
- vbox3 = QtWidgets.QVBoxLayout()
- textedit = QtWidgets.QPlainTextEdit()
+ tab = QtGui.QWidget()
+ vbox3 = QtGui.QVBoxLayout()
+ textedit = QtGui.QPlainTextEdit()
#textedit.setStyleSheet("QPlainTextEdit { border: 0; padding: 0; }")
textedit.setReadOnly(True)
textedit.setPlainText(fromUTF8("\n".join(authors)))
@@ -385,9 +386,9 @@ class AboutDialog(QtWidgets.QDialog):
tab.setLayout(vbox3)
tabs.addTab(tab, fromUTF8(escape(_("Authors"))))
- tab = QtWidgets.QWidget()
- vbox3 = QtWidgets.QVBoxLayout()
- textedit = QtWidgets.QPlainTextEdit()
+ tab = QtGui.QWidget()
+ vbox3 = QtGui.QVBoxLayout()
+ textedit = QtGui.QPlainTextEdit()
#textedit.setStyleSheet("QPlainTextEdit { border: 0; padding: 0; }")
textedit.setReadOnly(True)
textedit.setPlainText(license)
@@ -397,7 +398,7 @@ class AboutDialog(QtWidgets.QDialog):
vbox.addWidget(tabs)
- buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Close)
+ buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Close)
buttonBox.rejected.connect(self.hide)
vbox.addWidget(buttonBox)
@@ -405,7 +406,7 @@ class AboutDialog(QtWidgets.QDialog):
# TrayApplet ##################################################################
-class TrayApplet(QtWidgets.QSystemTrayIcon):
+class TrayApplet(QtGui.QSystemTrayIcon):
def __init__(self):
super(TrayApplet, self).__init__()
self.name = _("Firewall Applet")
@@ -452,67 +453,67 @@ class TrayApplet(QtWidgets.QSystemTrayIc
# urgencies
- self.urgencies = { "noicon": QtWidgets.QSystemTrayIcon.NoIcon,
- "information": QtWidgets.QSystemTrayIcon.Information,
- "warning": QtWidgets.QSystemTrayIcon.Warning,
- "critical": QtWidgets.QSystemTrayIcon.Critical }
+ self.urgencies = { "noicon": QtGui.QSystemTrayIcon.NoIcon,
+ "information": QtGui.QSystemTrayIcon.Information,
+ "warning": QtGui.QSystemTrayIcon.Warning,
+ "critical": QtGui.QSystemTrayIcon.Critical }
# actions
- self.shieldsupAction = QtWidgets.QAction(fromUTF8(escape(_("Shields Up"))),
+ self.shieldsupAction = QtGui.QAction(fromUTF8(escape(_("Shields Up"))),
self)
self.shieldsupAction.setCheckable(True)
self.shieldsupAction.setChecked(False)
self.shieldsupAction.triggered.connect(self.shieldsup_changed_cb)
- self.notificationsAction = QtWidgets.QAction(
+ self.notificationsAction = QtGui.QAction(
fromUTF8(escape(_("Enable Notifications"))), self)
self.notificationsAction.setCheckable(True)
self.notificationsAction.setChecked(False)
self.notificationsAction.triggered.connect(self.notification_changed_cb)
- self.settingsAction = QtWidgets.QAction(
+ self.settingsAction = QtGui.QAction(
fromUTF8(escape(_("Edit Firewall Settings..."))), self)
self.settingsAction.triggered.connect(self.configure_cb)
- self.changeZonesAction = QtWidgets.QAction(
+ self.changeZonesAction = QtGui.QAction(
fromUTF8(escape(_("Change Zones of Connections..."))), self)
self.changeZonesAction.triggered.connect(self.nm_connection_editor)
- self.shieldsAction = QtWidgets.QAction(
+ self.shieldsAction = QtGui.QAction(
fromUTF8(escape(_("Configure Shields UP/Down Zones..."))), self)
self.shieldsAction.triggered.connect(self.configure_shields)
- self.panicAction = QtWidgets.QAction(
+ self.panicAction = QtGui.QAction(
fromUTF8(escape(_("Block all network traffic"))), self)
self.panicAction.setCheckable(True)
self.panicAction.setChecked(False)
self.panicAction.triggered.connect(self.panic_mode_cb)
- self.aboutAction = QtWidgets.QAction(fromUTF8(escape(_("About"))), self)
+ self.aboutAction = QtGui.QAction(fromUTF8(escape(_("About"))), self)
self.aboutAction.triggered.connect(self.about_dialog.exec_)
- #self.quitAction = QtWidgets.QAction(fromUTF8(escape(_("Quit"))), self,
+ #self.quitAction = QtGui.QAction(fromUTF8(escape(_("Quit"))), self,
# triggered=self.quit)
- self.connectionsAction = QtWidgets.QWidgetAction(self)
- self.connectionsAction.setDefaultWidget(QtWidgets.QLabel(
+ self.connectionsAction = QtGui.QWidgetAction(self)
+ self.connectionsAction.setDefaultWidget(QtGui.QLabel(
fromUTF8("<b>"+escape(_("Connections"))+"</b> ")))
- self.interfacesAction = QtWidgets.QWidgetAction(self)
- self.interfacesAction.setDefaultWidget(QtWidgets.QLabel(
+ self.interfacesAction = QtGui.QWidgetAction(self)
+ self.interfacesAction.setDefaultWidget(QtGui.QLabel(
fromUTF8("<b>"+escape(_("Interfaces"))+"</b> ")))
- self.sourcesAction = QtWidgets.QWidgetAction(self)
- self.sourcesAction.setDefaultWidget(QtWidgets.QLabel(
+ self.sourcesAction = QtGui.QWidgetAction(self)
+ self.sourcesAction.setDefaultWidget(QtGui.QLabel(
fromUTF8("<b>"+escape(_("Sources"))+"</b> ")))
# init
- self.left_menu = QtWidgets.QMenu()
+ self.left_menu = QtGui.QMenu()
self.left_menu.setStyleSheet('QMenu { margin: 5px; }')
- self.right_menu = QtWidgets.QMenu()
+ self.right_menu = QtGui.QMenu()
self.right_menu.addAction(self.shieldsupAction)
self.right_menu.addAction(self.notificationsAction)
self.right_menu.addSeparator()
@@ -631,7 +632,7 @@ class TrayApplet(QtWidgets.QSystemTrayIc
self.setVisible(True)
def activated_cb(self, reason):
- if reason == QtWidgets.QSystemTrayIcon.Trigger:
+ if reason == QtGui.QSystemTrayIcon.Trigger:
self.left_menu.popup(QtGui.QCursor.pos())
def update_active_zones(self):
@@ -679,12 +680,12 @@ class TrayApplet(QtWidgets.QSystemTrayIc
zone = connections[connection][0]
if zone == "":
_binding = _("{entry} (Default Zone: {default_zone})")
- action = QtWidgets.QAction(
+ action = QtGui.QAction(
fromUTF8(escape(
_binding.format(default_zone=self.default_zone,
entry=connection))), self)
else:
- action = QtWidgets.QAction(
+ action = QtGui.QAction(
fromUTF8(escape(binding.format(zone=zone,
entry=connection))), self)
action.triggered.connect(functools.partial(
@@ -697,7 +698,7 @@ class TrayApplet(QtWidgets.QSystemTrayIc
# add other interfaces
for interface in sorted(interfaces):
zone = interfaces[interface]
- action = QtWidgets.QAction(
+ action = QtGui.QAction(
fromUTF8(escape(binding.format(zone=zone, entry=interface))),
self)
action.triggered.connect(functools.partial(
@@ -709,7 +710,7 @@ class TrayApplet(QtWidgets.QSystemTrayIc
for source in sorted(sources):
zone = sources[source]
- action = QtWidgets.QAction(
+ action = QtGui.QAction(
fromUTF8(escape(binding.format(zone=zone, entry=source))),
self)
action.triggered.connect(functools.partial(
@@ -931,10 +932,10 @@ class TrayApplet(QtWidgets.QSystemTrayIc
os.system("%s &" % NM_CONNECTION_EDITOR)
def warning(self, text):
- QtWidgets.QMessageBox.warning(None, fromUTF8(escape(self.name)), text)
+ QtGui.QMessageBox.warning(None, fromUTF8(escape(self.name)), text)
def error(self, text):
- QtWidgets.QMessageBox.critical(None, fromUTF8(escape(self.name)), text)
+ QtGui.QMessageBox.critical(None, fromUTF8(escape(self.name)), text)
def configure_cb(self, widget):
os.system("firewall-config &")
@@ -970,8 +971,6 @@ class TrayApplet(QtWidgets.QSystemTrayIc
def reloaded(self):
if self.notificationsAction.isChecked():
self.notify(escape(_("FirewallD has been reloaded.")))
- self.update_active_zones()
- self.update_tooltip()
def default_zone_changed(self, zone):
self.default_zone = zone
@@ -1118,7 +1117,7 @@ Options:
# reset SIGINT signal to default
signal.signal(signal.SIGINT, signal.SIG_DFL)
-app = QtWidgets.QApplication(sys.argv)
+app = QtGui.QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
applet = TrayApplet()

1261
SPECS/firewalld.spec

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save