Ejemplo n.º 1
0
 def queryOption(self, key, value, sender=None):
     key = dbus_to_python(key, str)
     value = dbus_to_python(value, str)
     log.debug1("config.ipset.%d.queryOption('%s', '%s')", self.id, key,
                value)
     settings = list(self.getSettings())
     return (key in settings[4] and settings[4][key] == value)
Ejemplo n.º 2
0
 def setIcmpBlockInversion(self, flag, sender=None):
     flag = dbus_to_python(flag, bool)
     log.debug1("%s.setIcmpBlockInversion('%s')", self._log_prefix, flag)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[15] = flag
     self.update(settings)
Ejemplo n.º 3
0
 def remove(self, sender=None):
     """remove icmptype
     """
     log.debug1("config.icmptype.%d.removeIcmpType()", self.id)
     self.parent.accessCheck(sender)
     self.config.remove_icmptype(self.obj)
     self.parent.removeIcmpType(self.obj)
Ejemplo n.º 4
0
    def Get(self, interface_name, property_name, sender=None):
        # get a property
        interface_name = dbus_to_python(interface_name)
        property_name = dbus_to_python(property_name)
        log.debug1("config.service.%d.Get('%s', '%s')", self.id,
                   interface_name, property_name)

        if interface_name != DBUS_INTERFACE_CONFIG_SERVICE:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.UnknownInterface: "
                "FirewallD does not implement %s" % interface_name)

        if property_name == "name":
            return self.obj.name
        elif property_name == "filename":
            return self.obj.filename
        elif property_name == "path":
            return self.obj.path
        elif property_name == "default":
            return self.obj.default
        elif property_name == "builtin":
            return self.config.is_builtin_service(self.obj)
        else:
            raise dbus.exceptions.DBusException(
                "org.freedesktop.DBus.Error.AccessDenied: "
                "Property '%s' isn't exported (or may not exist)" % \
                    property_name)
Ejemplo n.º 5
0
 def setShort(self, short, sender=None):
     short = dbus_to_python(short, str)
     log.debug1("%s.setShort('%s')", self._log_prefix, short)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[1] = short
     self.update(settings)
Ejemplo n.º 6
0
 def remove(self, sender=None):
     """remove helper
     """
     log.debug1("%s.removeHelper()", self._log_prefix)
     self.parent.accessCheck(sender)
     self.config.remove_helper(self.obj)
     self.parent.removeHelper(self.obj)
Ejemplo n.º 7
0
 def setVersion(self, version, sender=None):
     version = dbus_to_python(version, str)
     log.debug1("config.service.%d.setVersion('%s')", self.id, version)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[0] = version
     self.update(settings)
Ejemplo n.º 8
0
 def loadDefaults(self, sender=None):
     """load default settings for builtin zone
     """
     log.debug1("config.zone.%d.loadDefaults()", self.id)
     self.parent.accessCheck(sender)
     self.obj = self.config.load_zone_defaults(self.obj)
     self.Updated(self.obj.name)
Ejemplo n.º 9
0
 def update(self, settings, sender=None):
     # returns list ipv, table, list of chains
     log.debug1("config.direct.update()")
     settings = dbus_to_python(settings)
     self.config.get_direct().import_config(settings)
     self.config.get_direct().write()
     self.Updated()
Ejemplo n.º 10
0
    def flush(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Flushing rule set")

        if self.ip4tables_enabled:
            try:
                self.ip4tables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush ipv4 firewall: %s" % e)
        if self.ip6tables_enabled:
            try:
                self.ip6tables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush ipv6 firewall: %s" % e)
        if self.ebtables_enabled:
            try:
                self.ebtables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush eb firewall: %s" % e)

        if use_transaction is None:
            transaction.execute(True)
Ejemplo n.º 11
0
 def queryEntry(self, entry, sender=None): # pylint: disable=W0613
     entry = dbus_to_python(entry, str)
     log.debug1("%s.queryEntry('%s')", self._log_prefix, entry)
     settings = list(self.getSettings())
     if "timeout" in settings[4] and settings[4]["timeout"] != "0":
         raise FirewallError(errors.IPSET_WITH_TIMEOUT)
     return entry in settings[5]
Ejemplo n.º 12
0
 def queryOption(self, key, value, sender=None): # pylint: disable=W0613
     key = dbus_to_python(key, str)
     value = dbus_to_python(value, str)
     log.debug1("%s.queryOption('%s', '%s')", self._log_prefix, key,
                value)
     settings = list(self.getSettings())
     return (key in settings[4] and settings[4][key] == value)
Ejemplo n.º 13
0
 def PropertiesChanged(self, interface_name, changed_properties,
                       invalidated_properties):
     interface_name = dbus_to_python(interface_name, str)
     changed_properties = dbus_to_python(changed_properties)
     invalidated_properties = dbus_to_python(invalidated_properties)
     log.debug1("%s.PropertiesChanged('%s', '%s', '%s')", self._log_prefix,
                interface_name, changed_properties, invalidated_properties)
Ejemplo n.º 14
0
 def remove(self, sender=None):
     """remove icmptype
     """
     log.debug1("%s.removeIcmpType()", self._log_prefix)
     self.parent.accessCheck(sender)
     self.config.remove_icmptype(self.obj)
     self.parent.removeIcmpType(self.obj)
Ejemplo n.º 15
0
 def loadDefaults(self, sender=None):
     """load default settings for builtin service
     """
     log.debug1("%s.loadDefaults()", self._log_prefix)
     self.parent.accessCheck(sender)
     self.obj = self.config.load_service_defaults(self.obj)
     self.Updated(self.obj.name)
Ejemplo n.º 16
0
 def remove(self, sender=None):
     """remove service
     """
     log.debug1("%s.removeService()", self._log_prefix)
     self.parent.accessCheck(sender)
     self.config.remove_service(self.obj)
     self.parent.removeService(self.obj)
Ejemplo n.º 17
0
 def setVersion(self, version, sender=None):
     version = dbus_to_python(version, str)
     log.debug1("%s.setVersion('%s')", self._log_prefix, version)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[0] = version
     self.update(settings)
Ejemplo n.º 18
0
 def remove(self, sender=None):
     """remove service
     """
     log.debug1("config.service.%d.removeService()", self.id)
     self.parent.accessCheck(sender)
     self.config.remove_service(self.obj)
     self.parent.removeService(self.obj)
Ejemplo n.º 19
0
 def remove(self, sender=None):
     """remove ipset
     """
     log.debug1("%s.remove()", self._log_prefix)
     self.parent.accessCheck(sender)
     self.config.remove_ipset(self.obj)
     self.parent.removeIPSet(self.obj)
Ejemplo n.º 20
0
 def queryPassthrough(self, ipv, args, sender=None):
     ipv = dbus_to_python(ipv)
     args = dbus_to_python(args)
     log.debug1("config.direct.queryPassthrough('%s', '%s')" % \
                (ipv, "','".join(args)))
     idx = (ipv, args)
     return idx in self.getSettings()[2]
Ejemplo n.º 21
0
 def setMasquerade(self, masquerade, sender=None):
     masquerade = dbus_to_python(masquerade, bool)
     log.debug1("%s.setMasquerade('%s')", self._log_prefix, masquerade)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[8] = masquerade
     self.update(settings)
Ejemplo n.º 22
0
    def set_policy(self, policy, which="used", use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Setting policy to '%s'", policy)

        if self.ip4tables_enabled:
            try:
                self.ip4tables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of ipv4 firewall: %s" % e)

        if self.ip6tables_enabled:
            try:
                self.ip6tables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of ipv6 firewall: %s" % e)
        if self.ebtables_enabled:
            try:
                self.ebtables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of eb firewall: %s" % e)

        if use_transaction is None:
            transaction.execute(True)
Ejemplo n.º 23
0
 def remove(self, sender=None):
     """remove ipset
     """
     log.debug1("config.ipset.%d.remove()", self.id)
     self.parent.accessCheck(sender)
     self.config.remove_ipset(self.obj)
     self.parent.removeIPSet(self.obj)
Ejemplo n.º 24
0
 def setShort(self, short, sender=None):
     short = dbus_to_python(short, str)
     log.debug1("config.service.%d.setShort('%s')", self.id, short)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[1] = short
     self.update(settings)
Ejemplo n.º 25
0
 def setTarget(self, target, sender=None):
     target = dbus_to_python(target, str)
     log.debug1("%s.setTarget('%s')", self._log_prefix, target)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[4] = target if target != "default" else DEFAULT_ZONE_TARGET
     self.update(settings)
Ejemplo n.º 26
0
 def remove(self, sender=None):
     """remove zone
     """
     log.debug1("config.zone.%d.removeZone()", self.id)
     self.parent.accessCheck(sender)
     self.config.remove_zone(self.obj)
     self.parent.removeZone(self.obj)
Ejemplo n.º 27
0
 def setDescription(self, description, sender=None):
     description = dbus_to_python(description, str)
     log.debug1("%s.setDescription('%s')", self._log_prefix, description)
     self.parent.accessCheck(sender)
     settings = list(self.getSettings())
     settings[2] = description
     self.update(settings)
Ejemplo n.º 28
0
    def supported_icmp_types(self):
        """Return ICMP types that are supported by the iptables/ip6tables command and kernel"""
        ret = [ ]
        output = ""
        try:
            output = self.__run(["-p",
                                 "icmp" if self.ipv == "ipv4" else "ipv6-icmp",
                                 "--help"])
        except ValueError as ex:
            if self.ipv == "ipv4":
                log.debug1("iptables error: %s" % ex)
            else:
                log.debug1("ip6tables error: %s" % ex)
        lines = output.splitlines()

        in_types = False
        for line in lines:
            #print(line)
            if in_types:
                line = line.strip().lower()
                splits = line.split()
                for split in splits:
                    if split.startswith("(") and split.endswith(")"):
                        x = split[1:-1]
                    else:
                        x = split
                    if x not in ret:
                        ret.append(x)
            if self.ipv == "ipv4" and line.startswith("Valid ICMP Types:") or \
               self.ipv == "ipv6" and line.startswith("Valid ICMPv6 Types:"):
                in_types = True
        return ret
Ejemplo n.º 29
0
def run_server(debug_gc=False):
    """ Main function for firewall server. Handles D-Bus and GLib mainloop.
    """
    service = None
    if debug_gc:
        from pprint import pformat
        import gc
        gc.enable()
        gc.set_debug(gc.DEBUG_LEAK)

        gc_timeout = 10
        def gc_collect():
            gc.collect()
            if len(gc.garbage) > 0:
                print("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
                      ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n")
                print("GARBAGE OBJECTS (%d):\n" % len(gc.garbage))
                for x in gc.garbage:
                    print(type(x),"\n  ",)
                    print(pformat(x))
                print("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
                      "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n")
            id = GLib.timeout_add_seconds(gc_timeout, gc_collect)

    try:
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        bus = dbus.SystemBus()
        name = dbus.service.BusName(config.dbus.DBUS_INTERFACE, bus=bus)
        service = FirewallD(name, config.dbus.DBUS_PATH)

        mainloop = GLib.MainLoop()
        slip.dbus.service.set_mainloop(mainloop)
        if debug_gc:
            id = GLib.timeout_add_seconds(gc_timeout, gc_collect)

        # use unix_signal_add if available, else unix_signal_add_full
        if hasattr(GLib, 'unix_signal_add'):
            unix_signal_add = GLib.unix_signal_add
        else:
            unix_signal_add = GLib.unix_signal_add_full

        unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGHUP,
                        sighup, service)
        unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGTERM,
                        sigterm, mainloop)

        mainloop.run()

    except KeyboardInterrupt as e:
        log.debug1("Stopping..")

    except SystemExit as e:
        log.error("Raising SystemExit in run_server")

    except Exception as e:
        log.error("Exception %s: %s", e.__class__.__name__, str(e))

    if service:
        service.stop()
Ejemplo n.º 30
0
 def queryDestination(self, family, address, sender=None): # pylint: disable=W0613
     family = dbus_to_python(family, str)
     address = dbus_to_python(address, str)
     log.debug1("%s.queryDestination('%s', '%s')", self._log_prefix,
                family, address)
     settings = self.getSettings()
     return (family in settings[5] and
             address == settings[5][family])
Ejemplo n.º 31
0
    def _start_check(self):
        try:
            self.ipset_backend.set_list()
        except ValueError:
            log.warning("ipset not usable, disabling ipset usage in firewall.")
            # ipset is not usable, no supported types
            self.ipset_enabled = False
            self.ipset_supported_types = []
        else:
            # ipset is usable, get all supported types
            self.ipset_supported_types = self.ipset_backend.set_supported_types(
            )

        self.ip4tables_backend.fill_exists()
        if not self.ip4tables_backend.restore_command_exists:
            if self.ip4tables_backend.command_exists:
                log.warning("iptables-restore is missing, using "
                            "individual calls for IPv4 firewall.")
            else:
                log.warning("iptables-restore and iptables are missing, "
                            "disabling IPv4 firewall.")
                self.ip4tables_enabled = False
        if self.nftables_enabled:
            self.ipv4_supported_icmp_types = self.nftables_backend.supported_icmp_types(
                "ipv4")
        else:
            if self.ip4tables_enabled:
                self.ipv4_supported_icmp_types = self.ip4tables_backend.supported_icmp_types(
                )
            else:
                self.ipv4_supported_icmp_types = []
        self.ip6tables_backend.fill_exists()
        if not self.ip6tables_backend.restore_command_exists:
            if self.ip6tables_backend.command_exists:
                log.warning("ip6tables-restore is missing, using "
                            "individual calls for IPv6 firewall.")
            else:
                log.warning("ip6tables-restore and ip6tables are missing, "
                            "disabling IPv6 firewall.")
                self.ip6tables_enabled = False
        if self.nftables_enabled:
            self.ipv6_supported_icmp_types = self.nftables_backend.supported_icmp_types(
                "ipv6")
        else:
            if self.ip6tables_enabled:
                self.ipv6_supported_icmp_types = self.ip6tables_backend.supported_icmp_types(
                )
            else:
                self.ipv6_supported_icmp_types = []
        self.ebtables_backend.fill_exists()
        if not self.ebtables_backend.restore_command_exists:
            if self.ebtables_backend.command_exists:
                log.warning("ebtables-restore is missing, using "
                            "individual calls for bridge firewall.")
            else:
                log.warning("ebtables-restore and ebtables are missing, "
                            "disabling bridge firewall.")
                self.ebtables_enabled = False

        if self.ebtables_enabled and not self._individual_calls and \
           not self.ebtables_backend.restore_noflush_option:
            log.debug1("ebtables-restore is not supporting the --noflush "
                       "option, will therefore not be used")
Ejemplo n.º 32
0
 def Updated(self, name):
     log.debug1("%s.Updated('%s')" % (self._log_prefix, name))
Ejemplo n.º 33
0
    def update_zone_from_path(self, name):
        filename = os.path.basename(name)
        path = os.path.dirname(name)

        if not os.path.exists(name):
            # removed file

            if path.startswith(config.ETC_FIREWALLD_ZONES):
                # removed custom zone
                for x in self._zones.keys():
                    obj = self._zones[x]
                    if obj.filename == filename:
                        del self._zones[x]
                        if obj.name in self._builtin_zones:
                            return ("update", self._builtin_zones[obj.name])
                        return ("remove", obj)
            else:
                # removed builtin zone
                for x in self._builtin_zones.keys():
                    obj = self._builtin_zones[x]
                    if obj.filename == filename:
                        del self._builtin_zones[x]
                        if obj.name not in self._zones:
                            # update dbus zone
                            return ("remove", obj)
                        else:
                            # builtin hidden, no update needed
                            return (None, None)

            # zone not known to firewalld, yet (timeout, ..)
            return (None, None)

        # new or updated file

        log.debug1("Loading zone file '%s'", name)
        try:
            obj = zone_reader(filename, path)
        except Exception as msg:
            log.error("Failed to load zone file '%s': %s", filename, msg)
            return (None, None)

        obj.fw_config = self

        if path.startswith(config.ETC_FIREWALLD_ZONES) and \
           len(path) > len(config.ETC_FIREWALLD_ZONES):
            # custom combined zone part
            obj.name = "%s/%s" % (os.path.basename(path),
                                  os.path.basename(filename)[0:-4])

        # new zone
        if obj.name not in self._builtin_zones and obj.name not in self._zones:
            self.add_zone(obj)
            return ("new", obj)

        # updated zone
        if path.startswith(config.ETC_FIREWALLD_ZONES):
            # custom zone update
            if obj.name in self._zones:
                obj.default = self._zones[obj.name].default
                self._zones[obj.name] = obj
            return ("update", obj)
        else:
            if obj.name in self._builtin_zones:
                # builtin zone update
                del self._builtin_zones[obj.name]
                self._builtin_zones[obj.name] = obj

                if obj.name not in self._zones:
                    # update dbus zone
                    return ("update", obj)
                else:
                    # builtin hidden, no update needed
                    return (None, None)

        # zone not known to firewalld, yet (timeout, ..)
        return (None, None)
Ejemplo n.º 34
0
 def queryProtocol(self, protocol, sender=None):  # pylint: disable=W0613
     protocol = dbus_to_python(protocol, str)
     log.debug1("%s.queryProtocol('%s')", self._log_prefix, protocol)
     return protocol in self.getSettings()[13]
Ejemplo n.º 35
0
 def getDescription(self, sender=None):  # pylint: disable=W0613
     log.debug1("%s.getDescription()", self._log_prefix)
     return self.getSettings()[2]
Ejemplo n.º 36
0
 def queryIcmpBlockInversion(self, sender=None):  # pylint: disable=W0613
     log.debug1("%s.queryIcmpBlockInversion()", self._log_prefix)
     return self.getSettings()[15]
Ejemplo n.º 37
0
 def getIcmpBlocks(self, sender=None):  # pylint: disable=W0613
     log.debug1("%s.getIcmpBlocks()", self._log_prefix)
     return self.getSettings()[7]
Ejemplo n.º 38
0
 def listServices(self, sender=None):
     """list services objects paths
     """
     log.debug1("config.listServices()")
     return self.services
Ejemplo n.º 39
0
 def IcmpTypeAdded(self, icmptype):
     log.debug1("config.IcmpTypeAdded('%s')" % (icmptype))
Ejemplo n.º 40
0
 def listZones(self, sender=None):
     """list zones objects paths
     """
     log.debug1("config.listZones()")
     return self.zones
Ejemplo n.º 41
0
 def ServiceAdded(self, service):
     log.debug1("config.ServiceAdded('%s')" % (service))
Ejemplo n.º 42
0
 def ZoneAdded(self, zone):
     log.debug1("config.ZoneAdded('%s')" % (zone))
Ejemplo n.º 43
0
    def _loader(self, path, reader_type, combine=False):
        # combine: several zone files are getting combined into one obj
        if not os.path.isdir(path):
            return

        if combine:
            if path.startswith(config.ETC_FIREWALLD) and reader_type == "zone":
                combined_zone = Zone()
                combined_zone.name = os.path.basename(path)
                combined_zone.check_name(combined_zone.name)
                combined_zone.path = path
                combined_zone.default = False
            else:
                combine = False

        for filename in sorted(os.listdir(path)):
            if not filename.endswith(".xml"):
                if path.startswith(config.ETC_FIREWALLD) and \
                        reader_type == "zone" and \
                        os.path.isdir("%s/%s" % (path, filename)):
                    self._loader("%s/%s" % (path, filename),
                                 reader_type,
                                 combine=True)
                continue

            name = "%s/%s" % (path, filename)
            log.debug1("Loading %s file '%s'", reader_type, name)
            try:
                if reader_type == "icmptype":
                    obj = icmptype_reader(filename, path)
                    if obj.name in self.icmptype.get_icmptypes():
                        orig_obj = self.icmptype.get_icmptype(obj.name)
                        log.debug1("  Overloads %s '%s' ('%s/%s')",
                                   reader_type, orig_obj.name, orig_obj.path,
                                   orig_obj.filename)
                        self.icmptype.remove_icmptype(orig_obj.name)
                    elif obj.path.startswith(config.ETC_FIREWALLD):
                        obj.default = True
                    try:
                        self.icmptype.add_icmptype(obj)
                    except FirewallError as error:
                        log.info1("%s: %s, ignoring for run-time." % \
                                    (obj.name, str(error)))
                    # add a deep copy to the configuration interface
                    self.config.add_icmptype(copy.deepcopy(obj))
                elif reader_type == "service":
                    obj = service_reader(filename, path)
                    if obj.name in self.service.get_services():
                        orig_obj = self.service.get_service(obj.name)
                        log.debug1("  Overloads %s '%s' ('%s/%s')",
                                   reader_type, orig_obj.name, orig_obj.path,
                                   orig_obj.filename)
                        self.service.remove_service(orig_obj.name)
                    elif obj.path.startswith(config.ETC_FIREWALLD):
                        obj.default = True
                    self.service.add_service(obj)
                    # add a deep copy to the configuration interface
                    self.config.add_service(copy.deepcopy(obj))
                elif reader_type == "zone":
                    obj = zone_reader(filename, path, no_check_name=combine)
                    if combine:
                        # Change name for permanent configuration
                        obj.name = "%s/%s" % (os.path.basename(path),
                                              os.path.basename(filename)[0:-4])
                        obj.check_name(obj.name)
                    # Copy object before combine
                    config_obj = copy.deepcopy(obj)
                    if obj.name in self.zone.get_zones():
                        orig_obj = self.zone.get_zone(obj.name)
                        self.zone.remove_zone(orig_obj.name)
                        if orig_obj.combined:
                            log.debug1("  Combining %s '%s' ('%s/%s')",
                                       reader_type, obj.name, path, filename)
                            obj.combine(orig_obj)
                        else:
                            log.debug1("  Overloads %s '%s' ('%s/%s')",
                                       reader_type, orig_obj.name,
                                       orig_obj.path, orig_obj.filename)
                    elif obj.path.startswith(config.ETC_FIREWALLD):
                        obj.default = True
                        config_obj.default = True
                    self.config.add_zone(config_obj)
                    if combine:
                        log.debug1("  Combining %s '%s' ('%s/%s')",
                                   reader_type, combined_zone.name, path,
                                   filename)
                        combined_zone.combine(obj)
                    else:
                        self.zone.add_zone(obj)
                elif reader_type == "ipset":
                    obj = ipset_reader(filename, path)
                    if obj.name in self.ipset.get_ipsets():
                        orig_obj = self.ipset.get_ipset(obj.name)
                        log.debug1("  Overloads %s '%s' ('%s/%s')",
                                   reader_type, orig_obj.name, orig_obj.path,
                                   orig_obj.filename)
                        self.ipset.remove_ipset(orig_obj.name)
                    elif obj.path.startswith(config.ETC_FIREWALLD):
                        obj.default = True
                    try:
                        self.ipset.add_ipset(obj)
                    except FirewallError as error:
                        log.warning("%s: %s, ignoring for run-time." % \
                                    (obj.name, str(error)))
                    # add a deep copy to the configuration interface
                    self.config.add_ipset(copy.deepcopy(obj))
                elif reader_type == "helper":
                    obj = helper_reader(filename, path)
                    if obj.name in self.helper.get_helpers():
                        orig_obj = self.helper.get_helper(obj.name)
                        log.debug1("  Overloads %s '%s' ('%s/%s')",
                                   reader_type, orig_obj.name, orig_obj.path,
                                   orig_obj.filename)
                        self.helper.remove_helper(orig_obj.name)
                    elif obj.path.startswith(config.ETC_FIREWALLD):
                        obj.default = True
                    self.helper.add_helper(obj)
                    # add a deep copy to the configuration interface
                    self.config.add_helper(copy.deepcopy(obj))
                elif reader_type == "policy":
                    obj = policy_reader(filename, path)
                    if obj.name in self.policy.get_policies():
                        orig_obj = self.policy.get_policy(obj.name)
                        log.debug1("  Overloads %s '%s' ('%s/%s')",
                                   reader_type, orig_obj.name, orig_obj.path,
                                   orig_obj.filename)
                        self.policy.remove_policy(orig_obj.name)
                    elif obj.path.startswith(config.ETC_FIREWALLD):
                        obj.default = True
                    self.policy.add_policy(obj)
                    # add a deep copy to the configuration interface
                    self.config.add_policy_object(copy.deepcopy(obj))
                else:
                    log.fatal("Unknown reader type %s", reader_type)
            except FirewallError as msg:
                log.error("Failed to load %s file '%s': %s", reader_type, name,
                          msg)
            except Exception:
                log.error("Failed to load %s file '%s':", reader_type, name)
                log.exception()

        if combine and combined_zone.combined:
            if combined_zone.name in self.zone.get_zones():
                orig_obj = self.zone.get_zone(combined_zone.name)
                log.debug1("  Overloading and deactivating %s '%s' ('%s/%s')",
                           reader_type, orig_obj.name, orig_obj.path,
                           orig_obj.filename)
                try:
                    self.zone.remove_zone(combined_zone.name)
                except Exception:
                    pass
                self.config.forget_zone(combined_zone.name)
            self.zone.add_zone(combined_zone)
Ejemplo n.º 44
0
    def _start(self, reload=False, complete_reload=False):
        # initialize firewall
        default_zone = config.FALLBACK_ZONE

        # load firewalld config
        log.debug1("Loading firewalld config file '%s'", config.FIREWALLD_CONF)
        try:
            self._firewalld_conf.read()
        except Exception as msg:
            log.warning(msg)
            log.warning("Using fallback firewalld configuration settings.")
        else:
            if self._firewalld_conf.get("DefaultZone"):
                default_zone = self._firewalld_conf.get("DefaultZone")

            if self._firewalld_conf.get("CleanupOnExit"):
                value = self._firewalld_conf.get("CleanupOnExit")
                if value is not None and value.lower() in ["no", "false"]:
                    self.cleanup_on_exit = False
                log.debug1("CleanupOnExit is set to '%s'",
                           self.cleanup_on_exit)

            if self._firewalld_conf.get("CleanupModulesOnExit"):
                value = self._firewalld_conf.get("CleanupModulesOnExit")
                if value is not None and value.lower() in ["yes", "true"]:
                    self.cleanup_modules_on_exit = True
                log.debug1("CleanupModulesOnExit is set to '%s'",
                           self.cleanup_modules_on_exit)

            if self._firewalld_conf.get("Lockdown"):
                value = self._firewalld_conf.get("Lockdown")
                if value is not None and value.lower() in ["yes", "true"]:
                    log.debug1("Lockdown is enabled")
                    try:
                        self.policies.enable_lockdown()
                    except FirewallError:
                        # already enabled, this is probably reload
                        pass

            if self._firewalld_conf.get("IPv6_rpfilter"):
                value = self._firewalld_conf.get("IPv6_rpfilter")
                if value is not None:
                    if value.lower() in ["no", "false"]:
                        self.ipv6_rpfilter_enabled = False
                    if value.lower() in ["yes", "true"]:
                        self.ipv6_rpfilter_enabled = True
            if self.ipv6_rpfilter_enabled:
                log.debug1("IPv6 rpfilter is enabled")
            else:
                log.debug1("IPV6 rpfilter is disabled")

            if self._firewalld_conf.get("IndividualCalls"):
                value = self._firewalld_conf.get("IndividualCalls")
                if value is not None and value.lower() in ["yes", "true"]:
                    log.debug1("IndividualCalls is enabled")
                    self._individual_calls = True

            if self._firewalld_conf.get("LogDenied"):
                value = self._firewalld_conf.get("LogDenied")
                if value is None or value.lower() == "no":
                    self._log_denied = "off"
                else:
                    self._log_denied = value.lower()
                    log.debug1("LogDenied is set to '%s'", self._log_denied)

            if self._firewalld_conf.get("FirewallBackend"):
                self._firewall_backend = self._firewalld_conf.get(
                    "FirewallBackend")
                log.debug1("FirewallBackend is set to '%s'",
                           self._firewall_backend)

            if self._firewalld_conf.get("FlushAllOnReload"):
                value = self._firewalld_conf.get("FlushAllOnReload")
                if value.lower() in ["no", "false"]:
                    self._flush_all_on_reload = False
                else:
                    self._flush_all_on_reload = True
                log.debug1("FlushAllOnReload is set to '%s'",
                           self._flush_all_on_reload)

            if self._firewalld_conf.get("RFC3964_IPv4"):
                value = self._firewalld_conf.get("RFC3964_IPv4")
                if value.lower() in ["no", "false"]:
                    self._rfc3964_ipv4 = False
                else:
                    self._rfc3964_ipv4 = True
                log.debug1("RFC3964_IPv4 is set to '%s'", self._rfc3964_ipv4)

            if self._firewalld_conf.get("AllowZoneDrifting"):
                value = self._firewalld_conf.get("AllowZoneDrifting")
                if value.lower() in ["no", "false"]:
                    self._allow_zone_drifting = False
                else:
                    self._allow_zone_drifting = True
                    if not self._offline:
                        log.warning(
                            "AllowZoneDrifting is enabled. This is considered "
                            "an insecure configuration option. It will be "
                            "removed in a future release. Please consider "
                            "disabling it now.")
                log.debug1("AllowZoneDrifting is set to '%s'",
                           self._allow_zone_drifting)

        self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf))

        self._select_firewall_backend(self._firewall_backend)

        if not self._offline:
            self._start_check()

        # load lockdown whitelist
        log.debug1("Loading lockdown whitelist")
        try:
            self.policies.lockdown_whitelist.read()
        except Exception as msg:
            if self.policies.query_lockdown():
                log.error("Failed to load lockdown whitelist '%s': %s",
                          self.policies.lockdown_whitelist.filename, msg)
            else:
                log.debug1("Failed to load lockdown whitelist '%s': %s",
                           self.policies.lockdown_whitelist.filename, msg)

        # copy policies to config interface
        self.config.set_policies(copy.deepcopy(self.policies))

        # load ipset files
        self._loader(config.FIREWALLD_IPSETS, "ipset")
        self._loader(config.ETC_FIREWALLD_IPSETS, "ipset")

        # load icmptype files
        self._loader(config.FIREWALLD_ICMPTYPES, "icmptype")
        self._loader(config.ETC_FIREWALLD_ICMPTYPES, "icmptype")

        if len(self.icmptype.get_icmptypes()) == 0:
            log.error("No icmptypes found.")

        # load helper files
        self._loader(config.FIREWALLD_HELPERS, "helper")
        self._loader(config.ETC_FIREWALLD_HELPERS, "helper")

        # load service files
        self._loader(config.FIREWALLD_SERVICES, "service")
        self._loader(config.ETC_FIREWALLD_SERVICES, "service")

        if len(self.service.get_services()) == 0:
            log.error("No services found.")

        # load zone files
        self._loader(config.FIREWALLD_ZONES, "zone")
        self._loader(config.ETC_FIREWALLD_ZONES, "zone")

        if len(self.zone.get_zones()) == 0:
            log.fatal("No zones found.")
            sys.exit(1)

        # load policy files
        self._loader(config.FIREWALLD_POLICIES, "policy")
        self._loader(config.ETC_FIREWALLD_POLICIES, "policy")

        # check minimum required zones
        error = False
        for z in ["block", "drop", "trusted"]:
            if z not in self.zone.get_zones():
                log.fatal("Zone '%s' is not available.", z)
                error = True
        if error:
            sys.exit(1)

        # check if default_zone is a valid zone
        if default_zone not in self.zone.get_zones():
            if "public" in self.zone.get_zones():
                zone = "public"
            elif "external" in self.zone.get_zones():
                zone = "external"
            else:
                zone = "block"  # block is a base zone, therefore it has to exist

            log.error("Default zone '%s' is not valid. Using '%s'.",
                      default_zone, zone)
            default_zone = zone
        else:
            log.debug1("Using default zone '%s'", default_zone)

        # load direct rules
        obj = Direct(config.FIREWALLD_DIRECT)
        if os.path.exists(config.FIREWALLD_DIRECT):
            log.debug1("Loading direct rules file '%s'" % \
                       config.FIREWALLD_DIRECT)
            try:
                obj.read()
            except Exception as msg:
                log.error("Failed to load direct rules file '%s': %s",
                          config.FIREWALLD_DIRECT, msg)
        self.direct.set_permanent_config(obj)
        self.config.set_direct(copy.deepcopy(obj))

        self._default_zone = self.check_zone(default_zone)

        if self._offline:
            return

        # check if needed tables are there
        self._check_tables()

        if log.getDebugLogLevel() > 0:
            # get time before flushing and applying
            tm1 = time.time()

        # Start transaction
        transaction = FirewallTransaction(self)

        # 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 flush.
        #
        # Future optimization for the ipset case in reload: The transaction
        # only needs to be split here if there are conflicting ipset types in
        # exsting ipsets and the configuration in firewalld.
        if (reload and complete_reload) or \
           (self.ipset_enabled and self.ipset.has_ipsets()):
            transaction.execute(True)
            transaction.clear()

        # complete reload: unload modules also
        if reload and complete_reload:
            log.debug1("Unloading firewall modules")
            self.modules_backend.unload_firewall_modules()

        self.apply_default_tables(use_transaction=transaction)
        transaction.execute(True)
        transaction.clear()

        # apply settings for loaded ipsets while reloading here
        if self.ipset_enabled and self.ipset.has_ipsets():
            log.debug1("Applying ipsets")
            self.ipset.apply_ipsets()

        # Start or continue with transaction

        # apply default rules
        log.debug1("Applying default rule set")
        self.apply_default_rules(use_transaction=transaction)

        # apply settings for loaded zones
        log.debug1("Applying used zones")
        self.zone.apply_zones(use_transaction=transaction)

        self.zone.change_default_zone(None,
                                      self._default_zone,
                                      use_transaction=transaction)

        # apply policies
        log.debug1("Applying used policies")
        self.policy.apply_policies(use_transaction=transaction)

        # Execute transaction
        transaction.execute(True)

        # Start new transaction for direct rules
        transaction.clear()

        # apply direct chains, rules and passthrough rules
        if self.direct.has_configuration():
            log.debug1("Applying direct chains rules and passthrough rules")
            self.direct.apply_direct(transaction)

            # 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

        if log.getDebugLogLevel() > 1:
            # get time after flushing and applying
            tm2 = time.time()
            log.debug2("Flushing and applying took %f seconds" % (tm2 - tm1))
Ejemplo n.º 45
0
 def getForwardPorts(self, sender=None):  # pylint: disable=W0613
     log.debug1("%s.getForwardPorts()", self._log_prefix)
     return self.getSettings()[9]
Ejemplo n.º 46
0
 def listIcmpTypes(self, sender=None):
     """list icmptypes objects paths
     """
     log.debug1("config.listIcmpTypes()")
     return self.icmptypes
Ejemplo n.º 47
0
 def queryMasquerade(self, sender=None):  # pylint: disable=W0613
     log.debug1("%s.queryMasquerade()", self._log_prefix)
     return self.getSettings()[8]
Ejemplo n.º 48
0
 def LockdownWhitelistUpdated(self):
     log.debug1("config.policies.LockdownWhitelistUpdated()")
Ejemplo n.º 49
0
 def queryIcmpBlock(self, icmptype, sender=None):  # pylint: disable=W0613
     icmptype = dbus_to_python(icmptype, str)
     log.debug1("%s.queryIcmpBlock('%s')", self._log_prefix, icmptype)
     return icmptype in self.getSettings()[7]
Ejemplo n.º 50
0
 def setLockdownWhitelist(self, settings, sender=None):
     log.debug1("config.policies.setLockdownWhitelistSettings(...)")
     settings = dbus_to_python(settings)
     self.config.get_policies().lockdown_whitelist.import_config(settings)
     self.config.get_policies().lockdown_whitelist.write()
     self.LockdownWhitelistUpdated()
Ejemplo n.º 51
0
 def querySourcePort(self, port, protocol, sender=None):  # pylint: disable=W0613
     port = dbus_to_python(port, str)
     protocol = dbus_to_python(protocol, str)
     log.debug1("%s.querySourcePort('%s', '%s')", self._log_prefix, port,
                protocol)
     return (port, protocol) in self.getSettings()[14]
Ejemplo n.º 52
0
 def getLockdownWhitelist(self, sender=None):
     log.debug1("config.policies.getLockdownWhitelist()")
     return self.config.get_policies().lockdown_whitelist.export_config()
Ejemplo n.º 53
0
 def getTarget(self, sender=None):  # pylint: disable=W0613
     log.debug1("%s.getTarget()", self._log_prefix)
     settings = self.getSettings()
     return settings[4] if settings[4] != DEFAULT_ZONE_TARGET else "default"
Ejemplo n.º 54
0
 def getRichRules(self, sender=None):  # pylint: disable=W0613
     log.debug1("%s.getRichRules()", self._log_prefix)
     return self.getSettings()[12]
Ejemplo n.º 55
0
 def Renamed(self, name):
     log.debug1("%s.Renamed('%s')" % (self._log_prefix, name))
Ejemplo n.º 56
0
 def querySource(self, source, sender=None):  # pylint: disable=W0613
     source = dbus_to_python(source, str)
     log.debug1("%s.querySource('%s')", self._log_prefix, source)
     return source in self.getSettings()[11]
Ejemplo n.º 57
0
 def queryRichRule(self, rule, sender=None):  # pylint: disable=W0613
     rule = dbus_to_python(rule, str)
     log.debug1("%s.queryRichRule('%s')", self._log_prefix, rule)
     rule_str = str(Rich_Rule(rule_str=rule))
     return rule_str in self.getSettings()[12]
Ejemplo n.º 58
0
 def queryInterface(self, interface, sender=None):  # pylint: disable=W0613
     interface = dbus_to_python(interface, str)
     log.debug1("%s.queryInterface('%s')", self._log_prefix, interface)
     return interface in self.getSettings()[10]
Ejemplo n.º 59
0
 def Updated(self):
     log.debug1("config.direct.Updated()")
Ejemplo n.º 60
0
 def getSettings(self, sender=None):
     # returns list ipv, table, list of chains
     log.debug1("config.direct.getSettings()")
     return self.config.get_direct().export_config()