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